Pygame子弹从A点到B点的运动

时间:2017-05-13 09:22:03

标签: python python-2.7 pygame equations

我正在尝试使用名为&{39; python' Pygame的{​​{1}}库制作游戏。 (v1.9.2)我为这名球员制作了一个角色。这个角色应该"拍摄" "子弹"或者"法术"到mouse_pos点,我需要帮助的是" bullet"具有分配给1 self.speed = 1的恒定速度,如果我试图提高速度,当子弹到达mouse_pos时它将导致闪烁效果,因为self.pos将高于或低于mouse_pos。

如何让这个子弹快速进入&像子弹一样平滑,仍然可以到达设置mouse_pos的确切位置?

self.speed = 1 的示例
https://media.giphy.com/media/AAifrctxHHQbe/giphy.gif

self.speed = 2 的示例
http://4.1m.yt/d_TmNNq.gif

相关代码在update()函数内 Sprites.py(Spell / Bullet class)

class Spell(pygame.sprite.Sprite):
    def __init__(self,game,x,y,spelltype,mouse_pos):
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.width = TILESIZE
        self.height = TILESIZE
        self.type = spelltype
        self.effects = [
                'effect_'+self.type+'_00',
                'effect_'+self.type+'_01',
                'effect_'+self.type+'_02'
        ]
        self.image = pygame.image.load(path.join(IMG_DIR,"attack/attack_"+self.type+".png")).convert_alpha()
        self.image = pygame.transform.scale(self.image,(self.width,self.height))
        self.rect = self.image.get_rect()
        self.rect.x = x+self.width
        self.rect.y = y+self.height
        self.speed = 1
        self.mouse_pos = mouse_pos
        self.idx = 0

    def update(self):
        if not self.rect.collidepoint(self.mouse_pos):
            if self.mouse_pos[0] < self.rect.x:
                self.rect.x -= self.speed
            elif self.mouse_pos[0] > self.rect.x:
                self.rect.x += self.speed

            if self.mouse_pos[1] < self.rect.y:
                self.rect.y -= self.speed
            elif self.mouse_pos[1] > self.rect.y:
                self.rect.y += self.speed
        else:
            self.image = pygame.image.load(path.join(IMG_DIR,"effects/"+self.effects[self.idx]+".png"))
            self.idx += 1
            if self.idx >= len(self.effects):
                self.kill()

2 个答案:

答案 0 :(得分:2)

如果你的子弹太快以至于它穿过了目标,你可能想要测试子弹之间的线是否指向它的最后一个点与你的目标相交。

此处提供了更多详细信息:https://gamedev.stackexchange.com/questions/18604/how-do-i-handle-collision-detection-so-fast-objects-are-not-allowed-to-pass-thro

答案 1 :(得分:2)

毕达哥拉斯定理描述了n维空间中点之间的距离。对于你的情况

distance = math.sqrt(sum[ (self.mouse_pos[0] - self.rect.x) ** 2 
                        , (self.mouse_pos[1] - self.rect.y) ** 2
                        ]))
if distance < self.speed: 
    #remove the bullet from the scene

这不是一个很好的解决方案,因为子弹会不切实际地移动,  不同角度的不同速度。实际上它将以45(及)速度在45&#39;角度和速度为1,在90&#39;。

但是,我认为你不想进行三角学讲座。

编辑:这是三角学讲座。 你的程序将实际移动子弹,因为它在x和y方向上以全速移动它。你需要做的是让速度在两个方向都慢,这样x速度和y速度(矢量)形成的三角形的斜边等于1.由于速度总是1,这个三角形,恰好是单位圈。

       m
       |\
       | \
sin(A) |  \ This speed is 1
       |   \
       |   A\
       ------p
        cos(A)

如果你的角色位于p,并且鼠标位于m,那么你会发现它们之间的角度标记为A.然后x速度将是A的余弦,y速度将是正弦值。甲

你如何找到角度?你使用arctangent ... 实际上,这里是要使用的代码。

import math
if not self.rect.collidepoint(self.mouse_pos):
        angle = math.atan2( (self.mouse_pos[1] - self.rect.y)
                          , (self.mouse_pos[0] - self.rect.x)
        self.rect.x += self.speed * math.cos(angle)
        self.rect.y += self.speed * math.sin(angle)

或类似的东西。我的符号可能会混淆。