在pygame中向鼠标方向射击子弹

我只是想不通为什么我的子弹不起作用。我做了一个子弹课,这里是:


class Bullet:

    def __init__(self):

        self.x = player.x

        self.y = player.y

        self.height = 7

        self.width = 2

        self.bullet = pygame.Surface((self.width, self.height))

        self.bullet.fill((255, 255, 255))

现在我在我的游戏类中添加了几个函数,这是新代码:


class Game:

    def __init__(self):

        self.bullets = []

    

    def shoot_bullet(self):

         if self.bullets:

            for bullet in self.bullets:

                rise = mouse.y - player.y

                run = mouse.x - player.x

                angle = math.atan2(rise, run)


                bullet.x += math.cos(angle)

                bullet.y += math.sin(angle)


                pygame.transform.rotate(bullet.bullet, -math.degrees(angle))

                D.blit(bullet.bullet, (bullet.x, bullet.y))



    def generate_bullet(self):

        if  mouse.is_pressed():

            self.bullets.append(Bullet())

我期望代码做的是每次按下鼠标按钮时Bullet()都会添加一个,然后计算玩家和鼠标之间的角度并相应地朝鼠标的方向射击子弹。然而,结果是一团糟,子弹实际上不旋转也不移动。它们被生成并奇怪地移动到屏幕的左侧。我不确定我是否搞砸了,或者我使用的方法完全错误。game.bulletsgame.shoot_bullet


大话西游666
浏览 254回答 1
1回答

弑天下

首先pygame.transform.rotate不变换对象本身,而是创建一个新的旋转表面并将其返回。如果你想向某个方向发射子弹,方向是在子弹发射的那一刻定义的,但它不会连续改变。当子弹发射时,设置子弹的起始位置并计算到鼠标位置的方向向量:self.pos = (x, y)mx, my = pygame.mouse.get_pos()self.dir = (mx - x, my - y)方向向量不应该取决于到鼠标的距离,但它必须是单位向量。通过除以欧几里得距离来归一化向量length = math.hypot(*self.dir)if length == 0.0:    self.dir = (0, -1)else:    self.dir = (self.dir[0]/length, self.dir[1]/length)计算向量的角度并旋转子弹。一般来说,向量的角度可以通过 计算atan2(y, x)。atan2(-y, x)y轴需要反转(angle = math.degrees(math.atan2(-self.dir[1], self.dir[0]))self.bullet = pygame.Surface((7, 2)).convert_alpha()self.bullet.fill((255, 255, 255))self.bullet = pygame.transform.rotate(self.bullet, angle)要更新子弹的位置,只需缩放方向(按速度)并将其添加到子弹的位置:self.pos = (self.pos[0]+self.dir[0]*self.speed,             self.pos[1]+self.dir[1]*self.speed)要将旋转的子弹绘制在正确的位置,请选取旋转子弹的边界矩形并设置中心点self.pos(请参阅如何使用 PyGame 围绕其中心旋转图像?):bullet_rect = self.bullet.get_rect(center = self.pos)surf.blit(self.bullet, bullet_rect)  另请参阅向目标或鼠标射击子弹最小的例子: repl.it/@Rabbid76/PyGame-FireBulletInDirectionOfMousehttps://i.stack.imgur.com/oyzor.gif import pygameimport mathpygame.init()window = pygame.display.set_mode((500, 500))clock = pygame.time.Clock()class Bullet:    def __init__(self, x, y):        self.pos = (x, y)        mx, my = pygame.mouse.get_pos()        self.dir = (mx - x, my - y)        length = math.hypot(*self.dir)        if length == 0.0:            self.dir = (0, -1)        else:            self.dir = (self.dir[0]/length, self.dir[1]/length)        angle = math.degrees(math.atan2(-self.dir[1], self.dir[0]))        self.bullet = pygame.Surface((7, 2)).convert_alpha()        self.bullet.fill((255, 255, 255))        self.bullet = pygame.transform.rotate(self.bullet, angle)        self.speed = 2    def update(self):          self.pos = (self.pos[0]+self.dir[0]*self.speed,                     self.pos[1]+self.dir[1]*self.speed)    def draw(self, surf):        bullet_rect = self.bullet.get_rect(center = self.pos)        surf.blit(self.bullet, bullet_rect)  bullets = []pos = (250, 250)run = Truewhile run:    clock.tick(60)    for event in pygame.event.get():        if event.type == pygame.QUIT:            run = False        if event.type == pygame.MOUSEBUTTONDOWN:            bullets.append(Bullet(*pos))    for bullet in bullets[:]:        bullet.update()        if not window.get_rect().collidepoint(bullet.pos):            bullets.remove(bullet)    window.fill(0)    pygame.draw.circle(window, (0, 255, 0), pos, 10)    for bullet in bullets:        bullet.draw(window)    pygame.display.flip()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python