为“太空入侵者”制造子弹

2024-09-28 16:19:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在我的《太空入侵者》中为我的飞船制造炮弹。我认为现在唯一不起作用的是显示所有的投射物,因为我不知道怎么做,这就是为什么我尝试使用blit而没有起作用。我也想延迟每发子弹之间的时间,但我不知道如何做到这一点。 到目前为止,这是我做过的最先进的屏幕相关程序。你知道吗

import pygame
pygame.init()

class Player():
    def __init__(self):
        self.originalImage = pygame.image.load("ship.png")
        self.image = self.originalImage
        self.xposition = 480
        self.yposition = 450
        self.speed = 1

class Projectile():
    def __init__(self):
        self.originalImage = pygame.image.load("shot.png")
        self.image = self.originalImage
        self.xposition = player.xposition
        self.yposition = player.yposition
        self.speed = 1


size = width, height = 960, 540
screen = pygame.display.set_mode(size)
background = 0, 0, 0
player = Player()
projectile = Projectile()
projectiles = []
keys = pygame.key.get_pressed()

while True:
    screen.fill(background)

    for projectile in projectiles:
        if projectile.yposition < height:
            projectile.yposition -= projectile.speed
        else:
            projectiles.pop(projectiles.index(projectile))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) == True:
        player.xposition += player.speed
    if (keys[pygame.K_LEFT] or keys[pygame.K_a]) == True:
        player.xposition -= player.speed
    if (keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]) == True:
        projectiles.append(projectile)

    for projectile in projectiles:
        screen.blit(projectile.image, (projectile.xposition, projectile.yposition))

    screen.blit(player.image, ((player.xposition, player.yposition)))
    pygame.display.flip()

我编辑了评论后的代码,但仍然没有移动。。。你知道吗


Tags: orimageselftrueifkeysscreenpygame
2条回答

问题出在哪里:

  • 没有任何东西在移动,因为pygame.key.get_pressed()在游戏循环之外,即只在启动时检查键的状态。

  • 每次拍摄时必须创建一个新的Projectile实例,否则只能拍摄一次。

  • 要使投射物正确地出现,你必须先闪动玩家精灵,然后闪动投射物,否则玩家精灵会覆盖它们。

  • 若要在两次射击之间编写延迟代码,请将射击冷却时间存储在变量中(最好是player属性),您可以在每次射击时将其设置为某个正值,并在每个回合中递减。

  • 您使用sys.exit(),但尚未导入sys,这会使您的游戏在退出时崩溃。或者,您可以raise SystemExit,这与系统出口(),不需要任何导入。

下面是更正的代码:

import pygame
pygame.init()

class Player():
    def __init__(self):
        self.originalImage = pygame.image.load("ship.png")
        self.image = self.originalImage
        self.xposition = 480
        self.yposition = 450
        self.speed = 1
        self.attack_cooldown = 0   # variable to store shooting cooldown

class Projectile():
    def __init__(self):
        self.originalImage = pygame.image.load("shot.png")
        self.image = self.originalImage
        self.xposition = player.xposition
        self.yposition = player.yposition
        self.speed = 1


size = width, height = 960, 540
screen = pygame.display.set_mode(size)
background = 0, 0, 0
player = Player()
projectiles = []

while True:
    screen.fill(background)

    # decrement the current shooting cooldown
    if player.attack_cooldown > 0:
        player.attack_cooldown -= 1

    for projectile in projectiles:
        if projectile.yposition < height:
            projectile.yposition -= projectile.speed
        else:
            projectiles.pop(projectiles.index(projectile))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            raise SystemExit   # does the same thing as sys.exit() but you don't need to import sys

    keys = pygame.key.get_pressed()   # put this in the game loop

    if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
        player.xposition += player.speed
    if keys[pygame.K_LEFT] or keys[pygame.K_a]:
        player.xposition -= player.speed
    if keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]:
        if player.attack_cooldown == 0:   # shoot only when not on cooldown
            projectiles.append(Projectile())   # shoot a new projectile instead of the one you already shot
            player.attack_cooldown = 100   # add shooting cooldown, the number can be any positive integer you want

    # blit the player first
    screen.blit(player.image, ((player.xposition, player.yposition)))
    for projectile in projectiles:
        screen.blit(projectile.image, (projectile.xposition, projectile.yposition))

    pygame.display.flip()

我建议使用^{}。从Sprite导出Projectile。一个Sprite应该具有.image.rect属性。添加一个方法,该方法移动Projectile并且^{}在它超出边界时将其移动。e、 克:

class Projectile(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__() 
        self.originalImage = pygame.image.load("shot.png")
        self.image = self.originalImage
        self.rect = self.image.get_rect(center = (player.xposition, player.yposition))
        self.speed = 1

    def move(self):
        self.rect.y -= self.speed
        if self.rect.y < 0:
            self.kill()

创建^{}以包含投射物:

projectiles = pygame.sprite.Group()

Group中的精灵可以由^{}绘制。你知道吗

projectiles.draw(screen)

每当玩家发射子弹时,必须创建一个新的子弹实例并将其添加到子弹组中。我向我们推荐键盘事件:

for event in pygame.event.get():
    # [...]

    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_SPACE or event.key == pygame.K_w or event.key == pygame.K_UP: 
            projectiles.add(Projectile())

密钥(keys = pygame.key.get_pressed())的状态必须在主应用程序循环中进行评估。应用程序的速度可以由^{}控制:

import pygame
pygame.init()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        self.originalImage = pygame.image.load("ship.png")
        self.image = self.originalImage
        self.rect = self.image.get_rect(center = (480, 450))
        self.speed = 1

class Projectile(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__() 
        self.originalImage = pygame.image.load("shot.png")
        elf.image = self.originalImage
        self.rect = self.image.get_rect(center = player.rect.center)
        self.speed = 1

    def move(self):
        self.rect.y -= self.speed
        if self.rect.y < 0:
            self.kill()


size = width, height = 960, 540
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
background = 0, 0, 0
player = Player()
projectiles = pygame.sprite.Group()

run = True
while run:
    clock.tick(120)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
           if event.key == pygame.K_SPACE or event.key == pygame.K_w or event.key == pygame.K_UP: 
              projectiles.add(Projectile())

    keys = pygame.key.get_pressed()
    if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) == True:
        player.rect.x += player.speed
    if (keys[pygame.K_LEFT] or keys[pygame.K_a]) == True:
        player.rect.x -= player.speed

    for projectile in projectiles:
        projectile.move()

    screen.fill(background)
    projectiles.draw(screen)
    screen.blit(player.image, player.rect.topleft)
    pygame.display.flip()

相关问题 更多 >