目标:實作子彈向目标發射
子彈的發射是為了射中目标,傻乎乎的直上直下,還以為是在滾鍵盤呢。
向目标發射,實作的原理很簡單,得到敵機的坐标pos1,得到子彈的坐标pos2,讓pos2朝着po1飛行。
坐标可以直接讀取 目标的rect.x rect.y來計算擷取。飛行的方向,稍微複雜一點,用到高中的一些知識,已知兩個坐标的坐标點,求他們的角度。有了角度,設定速度和起始點,就能朝着目标發射了。
假如 pos1 = (pos1_x, pos1_y) ,pos2 = (pos2_x,pox2_y),子彈pos1朝着 pos2的方向的角度,計算公式如下:
atan((pos2_y - pos1_y) / (pos2_x-pos1)) 得到兩者的斜率,用atan得到角度,這個角度的機關是弧度。
測試代碼如下:
import math
pos1_x ,pos1_y = 1, 1
pos2_x, pos2_y = 2, 2
angle = math.atan((pos2_y - pos1_y) / (pos2_x - pos1_x))
print(angle)
輸出的結果是0.785398163397448 。他們的角度是45度,孤弧度是pi/4=0.785398163397448。沒錯了。
但是當兩個坐标點的X坐标可能相等,這樣無法用在分母上。做個判斷在計算??
pos1_x ,pos1_y = 1, 11
pos2_x, pos2_y = 1, 2
if pos2_x == pos1_x:
if pos1_y <= pos2_y:
angle = math.pi / 2
else:
angle = - math.pi / 2
else:
angle = math.atan((pos2_y - pos1_y) / (pos2_x - pos1_x))
print(angle)
能得到結果了,符合要求。
算法沒問題了,回到遊戲裡來測試。因為目前沒有飛機在螢幕,就測試下飛到螢幕正中下方把。為了測試簡單,直接定義為點(240,860),由于數學的直角坐标系和遊戲的坐标系,Y方向是反的,可以換算。這裡直接用了fabs函數,未考慮轉換。
#子彈3,随機水準線出來,夕陽方向(240,680)
bullet3 = Bullet()
pos1_x ,pos1_y = random.randint(0,400), 200
bullet3.set_pos(pos1_x,pos1_y)
pos2_x, pos2_y = 240, 680
if pos2_x == pos1_x:
if pos1_y <= pos2_y:
bullet3_angle = math.pi / 2
else:
bullet3_angle = -math.pi / 2
else:
bullet3_angle = math.atan(fabs((pos2_y - pos1_y) / (pos2_x - pos1_x)))
print(bullet3_angle)
#傳回的是弧度,要進行角度轉換
bullet3_angle = bullet3_angle *180 / math.pi
bullet3.set_speed(20,bullet3_angle)
# print(angle)
self.bullet_sprite.add(bullet3)
奇怪的現象發生了,大部分子彈能朝着目标發射(請忽略子彈的圖像大小引起的偏差),小部分亂飛了。
要對 方向的象限做判斷:angle為弧度
第一象限: angle = angle
第二象限:angle = pi - angle
第三象限:angle = pi + angle
第四象限: angle = 2*pi - angle
測試了一下,子彈朝着夕陽奔跑了。
裡面還是存在錯誤,圖像的每次運動方向上的距離是個int ,計算出來的是float,取整數後有偏差。