pygame游戏编程心得(一)——转向行为(目标追踪)

  最近自学python语言的过程中接触到了Pygame,这也是我第一次接触到游戏引擎。作为一个男生对游戏有天然的兴趣,所以当看到pygame时自己做个小游戏的想法便油然而生,在这个过程中遇到了很多问题。基于学习和讨论的基于学习和讨论的目的写了这个文章。


 遇到的问题:怎么实现敌方精灵的自动追踪?

 在查阅了相关资料后有了解决办法—— 转向力 = 所需速度 - 当前速度

pygame游戏编程心得(一)——转向行为(目标追踪)_第1张图片

在上述公式中,我们已知精灵的当前速度和目标位置只需要计算施加的速度即可,我们可以这样设计敌人精灵,

(假设我们的目标位置是鼠标位置)

class Mob(pg.sprite.Sprite):
 def __init__(self):
     self.groups = all_sprites
     pg.sprite.Sprite.__init__(self, self.groups)
     self.image = pg.Surface((MOB_SIZE, MOB_SIZE))
     self.image.fill(YELLOW)
     self.rect = self.image.get_rect()
     self.pos = vec(randint(0, WIDTH), randint(0, HEIGHT))#当前位置
     self.vel = vec(MAX_SPEED, 0).rotate(uniform(0, 360))#当前速度
     self.acc = vec(0, 0)#施加速度
     self.rect.center = self.pos



按照上述公式我们不难得出如下方法,

def follow_mouse(self):
 mpos = pg.mouse.get_pos()#鼠标位置
 self.acc = (mpos - self.pos)


 但这样并不能得到理想的效果,因为如果鼠标位置距离精灵当前位置很大,所求得的施加速度self.acc可能

非常大, “瞬间”就会将敌人精灵拉到目标位置,或者 运动轨迹比较生硬。

pygame游戏编程心得(一)——转向行为(目标追踪)_第2张图片
我们可以控制转向力的大小来解决这个问题,在精灵类之外添加如下常量,

MAX_SPEED = 5    #最大速度
MAX_FORCE = 0.1  #最大力量
改进函数 def follow_mouse(self),对施加速度进行限制。

def seek(self, target):
        self.desired = (target - self.pos).normalize() * MAX_SPEED
        steer = (self.desired - self.vel)
        if steer.length() > MAX_FORCE:
            steer.scale_to_length(MAX_FORCE)
        return steer
 如此运动轨迹已经变得“优美”起来了,但还有一个BUG,当敌人精灵到达目标地点后, 无法停止运动

出现持续 “抖动”现象。查看我们的代码就会发现,施加给敌人精灵的速度一直存在,并没有在到达目标地点

后消失。为解决抖动现象,我们可以设定一个常量表示到目标位置的临界距离,大于这个距离时,敌人精灵

“全速”接近目标位置,小于这个距离时慢慢减小施加的速度。

APPROACH_RADIUS = 120 #表示距离的常量
继续改进def seek(self, target)函数,

    def seek_with_approach(self, target):
        self.desired = (target - self.pos)#需要目标向量
        dist = self.desired.length()#目标向量大小
        self.desired.normalize_ip()
        if dist < APPROACH_RADIUS:
            self.desired *= dist / APPROACH_RADIUS * MAX_SPEED
        else:
            self.desired *= MAX_SPEED
        steer = (self.desired - self.vel)
        if steer.length() > MAX_FORCE:
            steer.scale_to_length(MAX_FORCE)
        return steer
这样便可实现相对完美的目标追踪运动了。
最后完整的测试代码,点击打开链接




你可能感兴趣的:(pygame游戏编程心得(一)——转向行为(目标追踪))