Pygame 子弹从A点运动到B点
Pygame bullet motion from point A to point B
我正在尝试使用名为“Pygame
”(v1.9.2) 的 python
库制作游戏,并且我已经为玩家制作了一个角色。这个角色应该 "shoot" "bullets" 或 "spells" 到 mouse_pos
的点,我需要帮助的是 "bullet" 有一个恒定的速度分配给1 self.speed = 1
,如果我尝试提高速度,当子弹到达 mouse_pos 时会导致闪烁效果,因为 self.pos 将高于或低于 mouse_pos。
我怎样才能让这颗子弹像子弹一样快速、平稳地移动,并且仍然到达设置 mouse_pos 的确切位置?
示例 self.speed = 1
示例 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()
如果你的子弹跑得太快以至于它穿过了目标,你可能想测试子弹当前点和它的最后一点之间的线是否与你的目标相交。
勾股定理讲述了 n 维空间中点与点之间的距离 space。针对您的情况
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
这不是一个很好的解决方案,因为子弹会不切实际地移动,
以不同的速度在不同的角度。事实上,它将以 sqrt(2) 的速度以 45' 角移动,并以 1 的速度在 90' 角移动。
但是,我假设你不想听三角学讲座。
编辑:这是三角学讲座。
您的程序将逼真地移动子弹,因为它在 x 和 y 方向上都以全速移动。您需要做的是让两个方向的速度都变慢,这样 x 速度和 y 速度(向量)形成的三角形的斜边等于 1。由于速度始终为 1,因此这个三角形, 恰好是单位圆
m
|\
| \
sin(A) | \ This speed is 1
| \
| A\
------p
cos(A)
如果你的角色在p,鼠标在m,那么你找到它们之间的角度在这里标记为A。那么x-speed就是A的余弦,y-speed就是A 的正弦
你是怎么找到角度的?你用反正切...
事实上,这是要使用的代码。
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)
或类似的东西。我可能混淆了我的符号。
我正在尝试使用名为“Pygame
”(v1.9.2) 的 python
库制作游戏,并且我已经为玩家制作了一个角色。这个角色应该 "shoot" "bullets" 或 "spells" 到 mouse_pos
的点,我需要帮助的是 "bullet" 有一个恒定的速度分配给1 self.speed = 1
,如果我尝试提高速度,当子弹到达 mouse_pos 时会导致闪烁效果,因为 self.pos 将高于或低于 mouse_pos。
我怎样才能让这颗子弹像子弹一样快速、平稳地移动,并且仍然到达设置 mouse_pos 的确切位置?
示例 self.speed = 1
示例 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()
如果你的子弹跑得太快以至于它穿过了目标,你可能想测试子弹当前点和它的最后一点之间的线是否与你的目标相交。
勾股定理讲述了 n 维空间中点与点之间的距离 space。针对您的情况
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
这不是一个很好的解决方案,因为子弹会不切实际地移动, 以不同的速度在不同的角度。事实上,它将以 sqrt(2) 的速度以 45' 角移动,并以 1 的速度在 90' 角移动。
但是,我假设你不想听三角学讲座。
编辑:这是三角学讲座。 您的程序将逼真地移动子弹,因为它在 x 和 y 方向上都以全速移动。您需要做的是让两个方向的速度都变慢,这样 x 速度和 y 速度(向量)形成的三角形的斜边等于 1。由于速度始终为 1,因此这个三角形, 恰好是单位圆
m
|\
| \
sin(A) | \ This speed is 1
| \
| A\
------p
cos(A)
如果你的角色在p,鼠标在m,那么你找到它们之间的角度在这里标记为A。那么x-speed就是A的余弦,y-speed就是A 的正弦
你是怎么找到角度的?你用反正切... 事实上,这是要使用的代码。
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)
或类似的东西。我可能混淆了我的符号。