带有PyGame故障排除功能的Python太空入侵者

时间:2019-03-27 02:54:07

标签: python pygame sprite projectile

我正在使用pygame制作一个简单的太空入侵者游戏,并且一直在为游戏中的不同对象或精灵创建类。现在的目标是创建一个可以在x轴上来回移动并射击弹丸的角色。我设法让角色在屏幕上来回移动,但是当涉及到拍摄时,它将无法正常工作,而且我也无法使其完全运行。它告诉我x和y缺少位置参数,但是当我将镜头追加到数组时,我为其分配了值。我究竟做错了什么?

这是我认为这部分应该去的方式。 我分配了一个射击类,这就是我将要射击的弹丸。定义它时,我放置了一些参数,以便根据我的角色所在的位置改变射弹发射的位置。然后,将我拥有的图像加载到单独的文件夹中,并为弹丸分配速度。接下来,我将update部分放置在下面的主循环中,使其可以运行。通过设置if语句,可以确保如果弹丸离开屏幕,它就会消失。通过制作一个阵列,我可以一次在屏幕上拥有多个弹丸,而它们不会互相删除。如果用户按下空格键,应将新的射弹添加到阵列中并发射。由于我是新手,所以我不知道我的观念是否正确,这是否就是我正在犯的小错误。我在教程中学习的内容不是在课堂上,也不具有更新功能,所以这就是我一直试图实现的目标。

import pygame, sys
from pygame import *
pygame.init()
screen = pygame.display.set_mode((800,600))
pygame.display.set_caption("Space Invaders")
pygame.mouse.set_visible(0)
WIDTH = 800
vel = 5
width = 64
BLACK = (0, 0, 0)

all_sprites = pygame.sprite.Group()
class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("images\ship.png")
        self.rect = self.image.get_rect()
        self.rect.center = (WIDTH/2, 550)
    def update(self, keys, *args):
        if keys[pygame.K_LEFT] and self.rect.x > vel:
            self.rect.x -= vel
        if keys[pygame.K_RIGHT] and self.rect.x < 800 - width - vel:
            self.rect.x += vel 
        screen.blit(self.image, self.rect)

class Shot(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.image = pygame.image.load("images\laser.png")
        self.rect = self.image.get_rect()
        self.vel = 10
    def update(self, keys, *args):
        for shot in shots:
            if shot.x < 500 and shot.x >0:
                shot.y -= shot.vel
            else:
                self.kill()
            screen.blit(self.image, self.rect)
        if keys[pygame.K_SPACE]:
            shots.append(Shot(x, 550))

#class EnemyAlien(pygame.sprite.Sprite):
 #   def __init__(self):



player = Player() 
all_sprites.add(player)
shot = Shot(player.rect.centerx, 550)
all_sprites.add(shot)

shots = []
run = True
while run:
    pygame.time.delay(60)
    x = player.rect.centerx
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    keys = pygame.key.get_pressed()
    all_sprites.update(keys)
    pygame.display.update()
    screen.fill(BLACK)
    all_sprites.draw(screen)

    pygame.display


pygame.quit()

如果有人想看看并让我知道我可能需要更改的内容,或者我在这里完全错了。谢谢。

编辑我更新了它,现在不再收到错误消息,该文件将运行,但是当我按空格键时什么也不会发生。我不能开火,我的角色有一个奇怪的滞后,看起来每当它移动时就会有更多的人被拖到后面。

编辑我也在尝试一种不同的方法,这没有错误,但是当我按空格键时,只需在左上角生成弹丸,然后在几秒钟后消失即可。

这是该代码的一部分

class Shot(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.image = pygame.image.load("images\laser.png")
        self.rect = self.image.get_rect()
        self.vel = 10
    def update(self, keys, *args):
        screen.blit(self.image, self.rect)
        self.y -= self.vel
        if self.y < 15 or self.y > 600:
            self.kill()

run = True
while run:
    pygame.time.delay(60)
    x = player.rect.centerx
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                shot = Shot(player.rect.centerx, 550)
                shots.add(shot)
                all_sprites.add(shots)
    keys = pygame.key.get_pressed()
    all_sprites.update(keys)
    pygame.display.update()
    screen.fill(BLACK)
    all_sprites.draw(screen)

    pygame.display

哪个会更好,而这两个都错在哪里?

2 个答案:

答案 0 :(得分:1)

有一个基本的误解。 Shot源自pygame.sprite.Sprite。必须唯一的容器是pygame.sprite.Groupall_sprites)。
您不需要单独的容器shots

shots = []

因此,您不需要初始的Shot对象,因为不是Shot会生成新的Shot,而是Player会生成新的Shot:< / p>

class Player(pygame.sprite.Sprite):

    # [...]

    def update(self, keys, *args):
        if keys[pygame.K_LEFT] and self.rect.x > vel:
            self.rect.x -= vel
        if keys[pygame.K_RIGHT] and self.rect.x < 800 - width - vel:
            self.rect.x += vel 

        if keys[pygame.K_SPACE]:
            all_sprites.add(Shot(self.rect.centerx, 550)) # <---- new shot 

all_sprites = pygame.sprite.Group()
player = Player() 
all_sprites.add(player)

Shot只需要更新其位置(.rect)并更新为.kill()本身。

class Shot(pygame.sprite.Sprite):
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load("images\laser.png")
        self.rect = self.image.get_rect()
        self.rect.center = (x, y) 
        self.vel = 10
    def update(self, keys, *args):
        if self.rect.x < 500 and self.rect.x > 0:
            self.rect = self.rect.move(0, -self.vel)
        else:
            self.kill()

请注意,screen.blit(self.image, self.rect).update的{​​{1}}方法中不需要任何Player,因为pygame.sprite.Group.draw()就是这样做的

Shot

答案 1 :(得分:0)

此行导致错误:shot = Shot()

__init__的{​​{1}}方法采用Shotx的位置参数,但是您没有传递它们。