为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

大话西游666 2022-07-12 15:29:08
我只是想不通为什么我的子弹不起作用。我做了一个子弹课,这里是: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
查看完整描述

1 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

首先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-FireBulletInDirectionOfMouse

https://i.stack.imgur.com/oyzor.gif

import pygame

import math


pygame.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 = True

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


查看完整回答
反对 回复 2022-07-12
  • 1 回答
  • 0 关注
  • 191 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信