pygame-使子弹朝光标方向射击

时间:2019-07-31 05:18:52

标签: python math pygame

我正在尝试使游戏中的项目符号朝着光标的方向射击,直到它碰到窗口边界为止。我的子弹当前朝着光标移动,但是一旦到达光标所在的位置就停止。

我注意到,如果我的光标不在屏幕上,则子弹可能会到达边界,因此我尝试通过乘法和加法将用于计算子弹移动的光标位置始终更改为不在窗口之外,但我无法完全按照我想要的方式工作。

win = pygame.display.set_mode((1000, 800))
pos = pygame.mouse.get_pos()
keys = pygame.key.get_pressed()

def shoot(bullets):
    for bullet in bullets:
        if bullet.x > 0 and bullet.x <1000 and bullet.y > 0 and bullet.y < 800:
            pygame.draw.circle(win, (255, 255, 255), (round(bullet.x) ,round(bullet.y)),5)
            diffX = bullet.targetX - bullet.x
            diffY = bullet.targetY - bullet.y
            ang = math.atan2(diffY,diffX)
            bullet.x += math.cos(ang)*bullet.vel
            bullet.y += math.sin(ang)*bullet.vel

if keys[pygame.K_SPACE] and RegBullet.canShoot:
        RegBullet.canShoot = False
        regBullets.append(RegBullet(win,x=p1.getX(),y=p1.getY(),targetX=pos[0],targetY=pos[1]))
        pause = threading.Thread(target=cool_down,args=(1,))
        pause.start()

1 个答案:

答案 0 :(得分:4)

问题是您需要通过矢量计算从子弹当前位置到目标点(bullet.targetXbullet.targetY)的子弹方向。
一旦子弹到达目标,那么这个方向就是(0,0)并且子弹不再移动。
不要将目标位置存储在bullet中。而是存储初始方向向量。例如:

bullet.diffX = targetX - bullet.x
bullet.diffY = targetY - bullet.y
ang = math.atan2(bullet.diffY, bullet.diffX)
bullet.x += math.cos(ang)*bullet.vel
bullet.y += math.sin(ang)*bullet.vel

使用pygame.Rect.collidepoint()来验证项目符号是否在窗口内:

for bullet in bullets:
   if pygame.Rect(0, 0, 1000, 800).collidepoint(bullet.x, bullet.y):
       # [...]

甚至.colliderect

for bullet in bullets:
   radius = 5
   bullet_rect = pygame.Rect(-radius, -radius, radius, radius);
   bullet_rect.center = (bullet.x, bullet.y)
   if pygame.Rect(0, 0, 1000, 800).colliderect(bullet_rect):
       # [...]

我建议使用pygame.math.Vector2来计算子弹的运动,例如:

bullet.pos = pg.math.Vector2(bullet.x, bullet.y)
bullet.dir = pg.math.Vector2(targetX, targetY) - bullet.pos
bullet.dir = bullet.dir.normalize()
for bullet in bullets:

    if #[...]

        bullet.pos += bullet.dir * bullet.vel
        bullet.x, bullet.y = (round(bullet.pos.x), round(bullet.pos.y))