【问题标题】:calculating direction of the player to shoot pygame计算玩家射击的方向pygame
【发布时间】:2020-02-29 11:51:28
【问题描述】:

这是我的播放器类

class Player:
    def  __init__(self, image):
        self.rotation_angle = 0

    def rotate(self, keys, left, right):
        if keys[right]:
            self.rotation_angle -= 0.5
        if keys[left]:
            self.rotation_angle += 0.5
        self.rotated_player = pygame.transform.rotate(self.player, (self.rotation_angle))

现在基于self.rotation_angle,我需要射击子弹。所以我做了以下事情。

class Bullet:
    def __init__(self):
        self.pos = [player1.pos[0], player1.pos[1]]
        self.direction = math.radians(player1.rotation_angle)
        self.bullet = pygame.Surface((5, 20))
        self.rotated_bullet = pygame.transform.rotate(self.bullet, (self.direction))
        self.bullet.fill((100, 200, 120))
        self.time = 0

    def shoot(self):
        self.pos[0] += math.cos(self.direction) * self.time
        self.pos[1] += math.sin(self.direction) * self.time
        self.time += 0.5

但是这种方法起作用了,产生的子弹只是朝某个随机方向移动。我尝试不将角度转换为弧度并将 y 轴的 self.direction 值更改为负值,但它不起作用。我将如何准确计算子弹的方向?感谢您的帮助。

【问题讨论】:

    标签: python math pygame


    【解决方案1】:

    数学运算math.sinmath.cos 的角度单位是弧度,但pygame.transform.rotate() 的角度单位是度。此外,您必须创建一个带有 SRCALPHA 标志的 pygame.Surface,并在旋转之前用子弹颜色填充表面:

    class Bullet:
        def __init__(self):
            self.pos = [player1.pos[0], player1.pos[1]]
            self.direction = math.radians(player1.rotation_angle)
            self.bullet = pygame.Surface((10, 5), pygame.SRCALPHA)
            self.bullet.fill((100, 200, 120))
            self.rotated_bullet = pygame.transform.rotate(self.bullet, player1.rotation_angle)
            self.time = 0
    

    在 pygame 中,y 轴点从上到下。这与通常的Cartesian coordinate system 的方向相反。因此,必须反转方向的 y 坐标:

    class Bullet:
        # [...]
    
        def shoot(self):
            self.pos[0] += math.cos(self.direction) * self.time
            self.pos[1] -= math.sin(self.direction) * self.time
            self.time += 0.5
    

    看例子:

    import pygame
    import math
    
    pygame.init()
    WIDTH, HEIGHT = 500, 500
    window = pygame.display.set_mode((500, 500))
    clock = pygame.time.Clock()
    
    class Player():
        def  __init__(self):
            self.rotation_angle = 0
            self.player = pygame.Surface((20, 20), pygame.SRCALPHA)
            self.player.fill((0, 255, 0))
            self.rotated_player = self.player
            self.pos = (WIDTH//2, HEIGHT//2)
            
        def rotate(self, keys, left, right):
            if keys[right]:
                self.rotation_angle -= 0.5
            if keys[left]:
                self.rotation_angle += 0.5
            self.rotated_player = pygame.transform.rotate(self.player, (self.rotation_angle))
    
    class Bullet:
        def __init__(self):
            self.pos = [player1.pos[0], player1.pos[1]]
            self.direction = math.radians(player1.rotation_angle)
            self.bullet = pygame.Surface((10, 5), pygame.SRCALPHA)
            self.bullet.fill((100, 200, 120))
            self.rotated_bullet = pygame.transform.rotate(self.bullet, player1.rotation_angle)
            self.time = 0
    
        def shoot(self):
            self.pos[0] += math.cos(self.direction) * self.time
            self.pos[1] -= math.sin(self.direction) * self.time
            self.time += 0.5
    
    player1 = Player()
    
    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.KEYDOWN and event.key == pygame.K_SPACE:
                bullets.append(Bullet())
    
        keys = pygame.key.get_pressed()
        player1.rotate(keys, pygame.K_LEFT, pygame.K_RIGHT)       
    
        for bullet in bullets[:]:
            bullet.shoot()
            if not window.get_rect().collidepoint(bullet.pos):
                bullets.remove(bullet)
    
        window.fill(0)
        window.blit(player1.rotated_player, player1.rotated_player.get_rect(center=player1.pos))
        for bullet in bullets:
            window.blit(bullet.rotated_bullet, bullet.rotated_bullet.get_rect(center=bullet.pos))
        pygame.display.flip()
    

    也可以看看

    Why aren't any bullets appearing on screen? - pygame
    Shooting a bullet in pygame in the direction of mouse

    【讨论】:

    • 您好,感谢您的回答。只是一个简单的问题,“pygame.SCRALPHA”和“convert_alpha”一样吗?
    • @hippozhipos 也有同样的效果。如果您使用pygame.SCRALPHA,则会生成一个具有每像素 alpha 的表面。如果您使用convert_alpha,则生成的表面没有alpha,然后进行转换。
    猜你喜欢
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    相关资源
    最近更新 更多