pygame精灵的移动代码无法正常工作

时间:2018-01-15 17:27:58

标签: python pygame

我正在尝试使用Pygame作为类项目的一部分创建Space Invaders克隆。我有一些让外星人正确行动的问题。

外星人应该到达边界,向下移动屏幕,他们的方向变量应该改变(1为右,2为左)。如果方向变量是正确的,它们将沿着屏幕向右移动,反之亦然向左移动,直到它们到达另一个边界并再次向下移动到屏幕上。

我使用了Alien类的单个实例,但是当尝试集成到组设置中时,它似乎根本不起作用......

为了尝试和帮助,我添加了一个“旗帜”变量,因为我认为这个问题可能是因为所有的外星人都将他们的动作从第一个外星人的运动中移开来击中“墙”,但是我我不确定它除了方向变量之外还有什么帮助......

(请原谅一塌糊涂,缺乏称职的评论!)

import pygame
import sys

class Fighter(pygame.sprite.Sprite):

    def __init__(self,life):
        pygame.sprite.Sprite.__init__(self)
        fighterImage = pygame.image.load("..\Graphics\FighterSprite.png").convert_alpha() #convert alpha makes imgs transparent
        self.image = pygame.Surface([32,32])
        self.image.set_colorkey(black) # makes surfaces transparent
        self.image.blit(fighterImage, (0,0))
        self.life = 3
        self.rect = self.image.get_rect()
        self.rect.x = 300
        self.rect.y = 700

    def move_ship(self, direction, pixels):
        if direction == 1 and self.rect.x <=560:
            self.rect.x += pixels
        if direction == 2 and self.rect.x >=10:
            self.rect.x -= pixels

class Alien(pygame.sprite.Sprite):

    def __init__(self,alive,x):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([32,32])
        self.image.set_colorkey(black)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = 400 #about midway down screen for testing purposes
        alienSprite = pygame.image.load("..\Grpahics\EnemyAlien1Static.png")
        self.image.blit(alienSprite, (0,0))
        self.alive = True

    def update(self,directional,flag):
        if self.rect.x >= 560:
            directonal = 2 #sets the direction to "left"
            flag = "LEFT" #sets the flag to "left" so all other aliens know
            self.rect.y = self.rect.y+10 #moves alien down the screen
        elif self.rect.x <= 10:
            directional = 1 #sets the direction to "right"
            flag = "RIGHT" #sets the flag to "right" so all other aliens know
            self.rect.y = self.rect.y+10
        if directional == 1 or flag == "RIGHT":
            self.rect.x += 1 #aliens move to the right
        else:
            self.rect.x -= 1 #aliens move to the left
        return directional, flag #updates direction of aliens for each loop

    def kill(self):
        self.alive = False

pygame.init()

screen = pygame.display.set_mode([600,800])
pygame.display.set_caption("Space Invaders")
background_image = pygame.image.load("..\Graphics\spaceinvbackground.png")
background_image = pygame.transform.scale(background_image, (600,800))
pygame.mouse.set_visible(False)
done = False
clock = pygame.time.Clock()
black = (0,0,0)
white = (255,255,255)
green = (122,240,112)

bullets = []
bulletgraphic = pygame.image.load("..\Graphics\FighterBullet.png")
bulletgraphic = pygame.transform.scale(bulletgraphic, (32,32))

direction = 0
directional = 1 #sets initial direction to right
flag = "RIGHT" #sets initial flag to right

score = 0

fighter_pilot = Fighter(True)
player = pygame.sprite.Group()
player.add(fighter_pilot)
alien = Alien(True,1,300)
alien1 = Alien(True,1,350)
alien2 = Alien(True,1,400)
alien3 = Alien(True,1,450)
alien4 = Alien(True,1,500)
alien5 = Alien(True,1,550)
aliens = pygame.sprite.Group() #this is the group in which all the alien enemies are in
aliens.add(alien,alien1,alien2,alien3,alien4,alien5)

while done == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if len(aliens) == 0: 
            done = True 
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
                direction = 1
            if event.key == pygame.K_LEFT or event.key == pygame.K_a:
                direction = 2
            if event.key == pygame.K_SPACE:
                bullets.append([(fighter_pilot.rect.x+13), fighter_pilot.rect.y]) #x value is roughly centre of ship, y value is same as ship
                fired = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or event.key == pygame.K_d or event.key == pygame.K_LEFT or event.key == pygame.K_a: # only works on key up for left/right arrows & A/D keys
                direction = 0

    fighter_pilot.move_ship(direction, 5)

    directional = aliens.update(directional, flag) #this line updates the aliens direction with every time the program loops

    for b in range(len(bullets)):
        bullets[b][1]-=10
        if fired == True:
            if alien.rect.x >= (fighter_pilot.rect.x+13)-22 and alien.rect.x <= (fighter_pilot.rect.x+13)+22 and alien.alive == True:
                if alien.rect.y == bullets[b][1]:
                    aliens.remove(alien)
                    alien.kill()
                    bullets.pop()
                    score = score + 100
            if alien1.rect.x >= (fighter_pilot.rect.x+13)-22 and alien1.rect.x <= (fighter_pilot.rect.x+13)+22 and alien1.alive == True:
                if alien1.rect.y == bullets[b][1]:
                    aliens.remove(alien1)
                    alien1.kill()
                    bullets.pop()
                    score = score + 100
            if alien2.rect.x >= (fighter_pilot.rect.x+13)-22 and alien2.rect.x <= (fighter_pilot.rect.x+13)+22 and alien2.alive == True:
                if alien2.rect.y == bullets[b][1]:
                    aliens.remove(alien2)
                    alien2.kill()
                    bullets.pop()
                    score = score + 100
            if alien3.rect.x >= (fighter_pilot.rect.x+13)-22 and alien3.rect.x <= (fighter_pilot.rect.x+13)+22 and alien3.alive == True:
                if alien3.rect.y == bullets[b][1]:
                    aliens.remove(alien3)
                    alien3.kill()
                    bullets.pop()
                    score = score + 100
            if alien4.rect.x >= (fighter_pilot.rect.x+13)-22 and alien4.rect.x <= (fighter_pilot.rect.x+13)+22 and alien4.alive == True:
                if alien4.rect.y == bullets[b][1]:
                    aliens.remove(alien4)
                    alien4.kill()
                    bullets.pop()
                    score = score + 100
            if alien5.rect.x >= (fighter_pilot.rect.x+13)-22 and alien5.rect.x <= (fighter_pilot.rect.x+13)+22 and alien5.alive == True:
                if alien5.rect.y == bullets[b][1]:
                    aliens.remove(alien5)
                    alien5.kill()
                    bullets.pop()
                    score = score + 100

    for bullet in bullets:
        if bullet[0]<0:
            bullets.pop()

    screen.blit(background_image, (0,0))
    for bullet in bullets:
        screen.blit(bulletgraphic, pygame.Rect(bullet[0], bullet[1], 0, 0))
    aliens.draw(screen)
    player.draw(screen)
    scoreImg = font.render(str(score),1,green)
    screen.blit(scoreImg, (10,10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

我真的无法弄清楚为什么这不起作用 - 如果你对一个外星人使用更新功能它会起作用吗?

提前致谢。

1 个答案:

答案 0 :(得分:-1)

我修改并修复了你的代码。我发现的主要问题是代码有一些逻辑错误和不必要的变量,这些错误只会使代码膨胀并使其更难理解。

主要问题:

  • flag变量不需要。
  • 不需要将directional变量传递到update方法,并且可能导致错误。
  • directional应该是一个对象字段而不是类外的变量。更有意义的是,这个变量属于每个外星人而不是它。
  • 传递给y构造函数的初始Alien值小于10,导致Alien s在x值大于10之前自由落体。
  • 程序中使用了对象font,但未初始化。

不需要flag变量,因为每个Alien与另一个同步移动。因此,如果一个Alien知道它必须改变方向,那么它们都会这样做。

同样,将这两个全局变量传递给update方法实际上并不是最好的方法,也没有太多面向对象的意义。

关于使directional变量全局化。这不是一个好的设计决策,它使每个单独的Alien对象的一部分更加面向对象。

与我的代码存在其他差异:

  • 删除了font对象的使用。
  • 没有呈现任何图像,只是用Surfaces填充了颜色。
  • 删除了一些在帖子上下文中无用的其他代码。

我希望这个答案对您有所帮助,如果您有任何其他问题,请随时在下面发表评论!

修改后的代码:

import pygame

class Fighter(pygame.sprite.Sprite):

    def __init__(self,life):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([32,32])
        self.image.set_colorkey(black) # makes surfaces transparent
        self.image.fill((0, 255, 0))

        self.life = 3

        self.rect = self.image.get_rect()
        self.rect.x = 300
        self.rect.y = 700

    def move_ship(self, direction, pixels):
        if direction == 1 and self.rect.x <=560:
            self.rect.x += pixels
        if direction == 2 and self.rect.x >=10:
            self.rect.x -= pixels

class Alien(pygame.sprite.Sprite):

    def __init__(self,alive,x,y):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([32,32])
        self.image.set_colorkey(black)
        self.image.fill((255, 0, 0))

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y #about midway down screen for testing purposes

        self.alive = True
        self.directional = 1

    def update(self):
        if self.rect.x >= 560:
            self.directional = 2
            self.rect.y += 10

        elif self.rect.x <= 10:
            self.directional = 1
            self.rect.y += 10


        if self.directional == 1:
            self.rect.x += 1 #aliens move to the right

        else:
            self.rect.x -= 1 #aliens move to the left

    def kill(self):
        self.alive = False

pygame.init()

window_width = 600
window_height = 800

screen = pygame.display.set_mode([window_width,window_height])

done = False

black = (0,0,0)
white = (255,255,255)
green = (122,240,112)

bullets = []
bulletgraphic = pygame.Surface((32, 32))
bulletgraphic.fill((0, 0, 200))

direction = 0

score = 0

fighter_pilot = Fighter(True)

player = pygame.sprite.Group()
player.add(fighter_pilot)

alien = Alien(True,20,300)
alien1 = Alien(True,20,350)
alien2 = Alien(True,20,400)
alien3 = Alien(True,20,450)
alien4 = Alien(True,20,500)
alien5 = Alien(True,20,550)
aliens = pygame.sprite.Group() #this is the group in which all the alien enemies are in
aliens.add(alien,alien1,alien2,alien3,alien4,alien5)

while done == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if len(aliens) == 0: 
            done = True 
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
                direction = 1
            if event.key == pygame.K_LEFT or event.key == pygame.K_a:
                direction = 2
            if event.key == pygame.K_SPACE:
                bullets.append([(fighter_pilot.rect.x+13), fighter_pilot.rect.y]) #x value is roughly centre of ship, y value is same as ship
                fired = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or event.key == pygame.K_d or event.key == pygame.K_LEFT or event.key == pygame.K_a: # only works on key up for left/right arrows & A/D keys
                direction = 0

    fighter_pilot.move_ship(direction, 5)

    aliens.update() #this line updates the aliens direction with every time the program loops

    for b in range(len(bullets)):
        bullets[b][1]-=10
        if fired == True:
            if alien.rect.x >= (fighter_pilot.rect.x+13)-22 and alien.rect.x <= (fighter_pilot.rect.x+13)+22 and alien.alive == True:
                if alien.rect.y == bullets[b][1]:
                    aliens.remove(alien)
                    alien.kill()
                    bullets.pop()
                    score = score + 100
            if alien1.rect.x >= (fighter_pilot.rect.x+13)-22 and alien1.rect.x <= (fighter_pilot.rect.x+13)+22 and alien1.alive == True:
                if alien1.rect.y == bullets[b][1]:
                    aliens.remove(alien1)
                    alien1.kill()
                    bullets.pop()
                    score = score + 100
            if alien2.rect.x >= (fighter_pilot.rect.x+13)-22 and alien2.rect.x <= (fighter_pilot.rect.x+13)+22 and alien2.alive == True:
                if alien2.rect.y == bullets[b][1]:
                    aliens.remove(alien2)
                    alien2.kill()
                    bullets.pop()
                    score = score + 100
            if alien3.rect.x >= (fighter_pilot.rect.x+13)-22 and alien3.rect.x <= (fighter_pilot.rect.x+13)+22 and alien3.alive == True:
                if alien3.rect.y == bullets[b][1]:
                    aliens.remove(alien3)
                    alien3.kill()
                    bullets.pop()
                    score = score + 100
            if alien4.rect.x >= (fighter_pilot.rect.x+13)-22 and alien4.rect.x <= (fighter_pilot.rect.x+13)+22 and alien4.alive == True:
                if alien4.rect.y == bullets[b][1]:
                    aliens.remove(alien4)
                    alien4.kill()
                    bullets.pop()
                    score = score + 100
            if alien5.rect.x >= (fighter_pilot.rect.x+13)-22 and alien5.rect.x <= (fighter_pilot.rect.x+13)+22 and alien5.alive == True:
                if alien5.rect.y == bullets[b][1]:
                    aliens.remove(alien5)
                    alien5.kill()
                    bullets.pop()
                    score = score + 100

    for bullet in bullets:
        if bullet[0]<0:
            bullets.pop()

    screen.fill(black)


    for bullet in bullets:
        screen.blit(bulletgraphic, pygame.Rect(bullet[0], bullet[1], 0, 0))

    aliens.draw(screen)
    player.draw(screen)
    pygame.display.flip()

pygame.quit()
quit()