Pygame- 让子弹向光标方向射击

3

我试图使游戏中的子弹向光标方向射击,直到撞到窗口边缘。目前我的子弹会朝向光标飞行,但一旦到达光标位置就会停止。

我发现如果我的光标在屏幕外面,子弹可以飞到边缘,所以我尝试修改用来计算子弹移动的光标位置,使其始终处于窗口外部,通过乘法和加法实现,但我无法完全满足我的要求。

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()

只提供与该项目相关的代码。如果您需要查看更多代码,请告诉我。 - X and Y
1个回答

4
请参考Shooting a bullet in pygame in the direction of mousecalculating direction of the player to shoot pygame
问题在于您计算子弹方向时使用了从当前位置到目标点(bullet.targetX, bullet.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))

谢谢您指出这一点。我将diffX和diffY移动到我的子弹类中,并从那里调用它们,而不是不断刷新它们。 - X and Y

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接