首先这里要说明一下的是在pygame里,坐标系实际上是普通二位坐标系的第四象限,而且y轴乘以-1.如图所示。图中绿色区域就是pygame的画面坐标系。
接下来我们分析一下,怎么计算导弹追踪的轨迹。
先看下图
上图中,我们可以看到,当A在x轴向右移动|AR|长的距离以及在y轴向上移动 |BR| 长的距离后 A就和B重合了,也就是完成了我们所谓的追踪,那么我们只要求出了AR、BR就能够实现我们想要的功能。
由于A和B的位置已知,所以:
AR = Bx-Ax ;
BR = (By-Ay)* -1 = Ay - By 这里乘以-1是因为在上面说过,pygame里的坐标系是平面坐标系第四象限y轴*-1
好了,基本上到这里,就完成了。。。。
道理其实就是这么简单。当然,如果只移动一次就完成了追踪,在我们看来这个过程是瞬间的,无法被体现出来。所以在游戏中我们只要让这个过程放慢,变为肉眼可见即可。
这里我们把AB 切为很多段,这样A就是一步一步的接近B的,这样我们就能够控制A移动到B的速度了。好了,有了思路 具体操作如下
如上图所示,AR上的每一步都在X轴上与AR平行,所以以该点为顶点的角都和角BAR相等,所以,我们只要利用三角函数就能求出每一次运动时该点坐标的变化。
sina = BR / AB
cosa = AR / AB
假设我们想要用7步来完成追踪,每一步分别为A1,A2,A3.... 他们之间的距离应为AB/7(这里平均分配了,其实也可以指定不同的步长,但我实在想不明白这么做的理由。)因为AB已知,所以AB/7 也已知
A1的横坐标为Ax + (cos * AB/7)
A1的纵坐标为 Ay + (sina * AB/7)
以此类推,就可以得到A1到A6的所有坐标了。
完整代码如下:
import pygame,sys,math
pygame.init()
screen = pygame.display.set_mode((600,800))
pygame.display.set_caption("test")
clock = pygame.time.Clock()
target = pygame.Rect(200,200,10,10)
tracer = pygame.Rect(0,0,10,10)
speed = 3
def trace(target,tracer):
x1, y1 = tracer.x, tracer.y # 应为pygame的rect函数只接受int类型数,所以为了不影响计算精度,我们先暂时定义两个数用于计算,最后将这连个数传入rect即可
x2, y2 = target.x, target.y # 同上
dx = x2 - x1
dy = y1 - y2
r = math.sqrt(math.pow(dx,2) + math.pow(dy,2))
sin = dy / r
cos = dx / r
x1 += cos * speed
y1 -= sin * speed
tracer.x,tracer.y = x1,y1
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
clock.tick(30)
screen.fill((255,255,255))
#************填写内容*********************
mouse_pos = pygame.mouse.get_pos()
target.x,target.y = (mouse_pos)
pygame.draw.rect(screen,(255,0,0),target)
pygame.draw.rect(screen,(0,255,0),tracer)
trace(target,tracer)
#***************************************
pygame.display.update()
效果如下图:
以上我们就完成一次轨迹追踪的算法,但在这个算法里,导弹是以匀速向目标移动的,显然这不够细节,所以,以后我会讨论一下,如何在运动过程中加入初速度这个变量,使得不同的初速度获得不同的运动轨迹,以及在运动的过程中如何调整角度,以使追踪物的头部始终朝向被追踪目标。