Pygame,生成第二枚导弹或外星人无效
Pygame, spawn second missile or alien didn't work
我是一名大学生,我有一个游戏项目(我们可以选择任何主题),一开始很顺利,但后来遇到了一些意想不到的问题。我选择创建一个简单版本的 raiden 2(space 飞船射击游戏),但是当它开始生成导弹和外星人时,它并没有像预期的那样工作。首先,当我按下 space 按钮时,导弹将被创建并从底部移动到顶部,但是当我再次按下它时,它不会创建第二个,或者可能会创建,但我只能看到导弹重新定位在 space 船的顶部加上速度增加(不打算)相反,我想在第一个移动时创建第二个。外星人 spaceship 也有同样的问题,实例创建并移动得很好,但是当第二个生成的时候到了,第一个刚刚重新定位到新坐标,它的速度 increased.Then 对于外星人我选择用 for 循环创建更多,然后移动它们,但速度再次提高,我只能看到一个。我还有 4 个不同的 classes 外星人需要生成,但如果我不能解决这些问题,我就无法继续。我还检查了一些教程和其他问题,但是当我尝试解决方案时它不起作用,我会继续搜索,但如果有人发现错误并可以给我一个例子,我将不胜感激。最后只是告诉你我正在使用图像作为精灵等。这是代码:
外星人:
class aliens(pygame.sprite.Sprite):
def __init__(self, dw, dh, w, h):
self.display_width = dw
self.display_height = dh
self.width = w
self.height = h
super().__init__()
第一个外星人:
class alienPrivate(aliens):
def __init__(self, dw, dh, w, h):
super().__init__(dw, dh, w, h)
self.image = alienPrivateImg
self.rect = privateRect
self.rect.x = random.randrange(0, display_width - w)
self.rect.y = random.randrange(2*(-h), -h)
self.weapon = 1
self.damage = 5
self.health = 10
self.speed = 4
# Private moves top -> bottom
def update(self):
self.rect.y += self.speed
导弹:
class Missiles(pygame.sprite.Sprite):
def __init__(self, dw, dh, wpn, pwlvl):
super().__init__()
self.weapon = wpn
self.powerLevel = pwlvl
self.setFire()
def setFire(self):
if self.weapon == 1:
if self.powerLevel == 1:
self.image = bullets
self.rect = bullet
elif self.weapon == 2:
if self.powerLevel == 1:
self.image = frostLaserL1
self.rect = frLaserL1
elif self.powerLevel == 2:
self.image = frostLaserL2
self.rect = frLaserL2
else:
self.image = frostLaserL3
self.rect = frLaserL3
else:
if self.powerLevel == 1:
self.image = fireLaserL1
self.rect = fLaserL1
elif self.powerLevel == 2:
self.image = fireLaserL2
self.rect = fLaserL2
else:
self.image = fireLaserL3
self.rect = fLaserL3
def update(self):
self.rect.y -= 1
导弹生成:
missile = Missiles(display_width,display_height,weapon, powerLevel)
missile.rect.x = hero.rect.x + 35
missile.rect.y = hero.rect.y - 20
all_sprites_list.add(missile)
fire_list.add(missile)
外星人产卵:
for spawn in range(5):
private = alienPrivate(display_width, display_height, 50, 88)
all_sprites_list.add(private)
alien_list.add(private)
玩家class:
class player(pygame.sprite.Sprite):
def __init__(self, dw, dh, w, h):
super().__init__()
self.health = 100
self.stamina = 100
self.width = w
self.height = h
self.image = spaceshipImgBee
self.rect = spaceshipRect
self.rect.x = (dw / 2) - (self.width / 2)
self.rect.y = dh - h
self.weapon = 1
self.powerLevel = 1
# Methods
def setPosx(self, x):
self.rect.x = x
def setPosy(self, y):
self.rect.y = y
def moveRigth(self, x):
self.rect.x += x
def moveLeft(self, y):
self.rect.y += y
def setWeapon(self, x):
if self.weapon == x:
if self.weapon == 1 and self.powerLevel == 1:
self.damage += 10
self.powerLevel += 1
elif self.weapon == 1 and (self.powerLevel > 1 and self.powerLevel < 3):
self.powerLevel += 1
elif self.weapon == 2 and self.powerlevel < 3:
self.damage += 15
self.powerLevel += 1
elif self.weapon == 3 and self.powerLevel < 3:
self.damage += 25
self.powerLevel += 1
else:
if x == 1:
self.weapon = x
self.damage = 10
self.powerLevel = 1
elif x == 2:
self.weapon = x
self.damage = 20
self.powerLevel = 1
elif x == 3:
self.weapon = x
self.damage = 50
self.powerLevel +=1
以及游戏的其余部分(一部分),包括 while 循环:
import pygame
import random
import time
# Colors
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
# Start Pygame
pygame.init()
# Window Size and Name
display_width = 700
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Star Protector")
# Window refresh rate
fps = 60
clock = pygame.time.Clock()
#Images
spaceshipImgBee = pygame.image.load('Hero_Spaceship_Bee_80x79.png')
spaceshipRect = spaceshipImgBee.get_rect()
alienPrivateImg = pygame.image.load('Alien_Private_50x88.png')
privateRect = alienPrivateImg.get_rect()
bullets = pygame.image.load('Bullets_10x20.png')
bullet = bullets.get_rect()
all_sprites_list = pygame.sprite.Group()
alien_list = pygame.sprite.Group()
fire_list = pygame.sprite.Group()
hero = player(display_width,display_height, 80, 79)
all_sprites_list.add(hero)
killed = False
x = 0
y = 0
i = 0
l = 0
score = 0
while not killed:
weapon = hero.weapon
powerLevel = hero.powerLevel
for event in pygame.event.get():
if event.type == pygame.QUIT:
killed = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x = -10
i = 1
elif event.key == pygame.K_RIGHT:
x = 10
i = 1
elif event.key == pygame.K_UP:
y = -10
i = 2
elif event.key == pygame.K_DOWN:
y = 10
i = 2
elif event.key == pygame.K_SPACE:
if weapon == 1:
missile = Missiles(display_width,display_height,weapon, powerLevel)
missile.rect.x = hero.rect.x + 35
missile.rect.y = hero.rect.y - 20
all_sprites_list.add(missile)
fire_list.add(missile)
elif weapon == 2:
if powerLevel == 1:
frlaser = Missiles(display_width, display_height, weapon, powerLevel)
frlaser.rect.x = (hero.rect.x / 2) - 7
all_sprites_list.add(frlaser)
fire_list.add(frlaser)
elif powerLevel == 2:
frlaser = Missiles(display_width, display_height, weapon, powerLevel)
frlaser.rect.x = (hero.rect.x / 2) - 20
all_sprites_list.add(frlaser)
fire_list.add(frlaser)
else:
frlaser = Missiles(display_width, display_height, weapon, powerLevel)
frlaser.rect.x = (hero.rect.x / 2) - 40
all_sprites_list.add(frlaser)
fire_list.add(frlaser)
else:
if powerLevel == 1:
flaser = Missiles(display_width, display_height, weapon, powerLevel)
flaser.rect.x = (hero.rect.x / 2) -7
all_sprites_list.add(flaser)
fire_list.add(flaser)
elif powerLevel == 2:
flaser = Missiles(display_width, display_height, weapon, powerLevel)
flaser.rect.x = (hero.rect.x / 2) -20
all_sprites_list.add(flaser)
fire_list.add(flaser)
else:
flaser = Missiles(display_width, display_height, weapon, powerLevel)
flaser.rect.x = (hero.rect.x / 2) - 40
all_sprites_list.add(flaser)
fire_list.add(flaser)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x = 0
i = 1
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y = 0
i = 2
#Move the spaceship with boundaries
if i == 1:
hero.moveRigth(x)
elif i == 2:
hero.moveLeft(y)
if hero.rect.x > display_width - hero.width:
hero.setPosx(display_width - hero.width)
elif hero.rect.x < 0:
hero.setPosx(0)
elif hero.rect.y < 0:
hero.setPosy(0)
elif hero.rect.y > display_height - hero.height:
hero.setPosy(display_height - hero.height)
#Background Color - Image
gameDisplay.blit(backgCosmos, (0 ,l))
#gameDisplay.fill(WHITE)
if score == 100:
for spawn in range(5):
private = alienPrivate(display_width, display_height, 50, 88)
all_sprites_list.add(private)
alien_list.add(private)
if l + 600 > 600:
gameDisplay.blit(backgRepublic, (0 ,l -600))
l += 1
all_sprites_list.update()
#Print player - start the battle
all_sprites_list.draw(gameDisplay)
score += 1
pygame.display.update()
clock.tick(fps)
pygame.quit()
quit()
至于图片我不能上传它们(不知道为什么)但是你可以快速随机调整大小并测试它。感谢您的宝贵时间!
您使用不同的实例正确地生成了外星列兵,但需要对导弹执行相同的操作。 for i in range(number)
将给出单独的实例。否则,pygames sprite .add() 将假定您正在引用组中已存在的实例。
你能把你的游戏循环代码while True:
放在这里吗?
与此同时,检查将 .update() 传递给各个精灵是否会提高速度。最后,如果导弹离开显示屏,您只需 .remove() 即可。
这个 bug 修复起来很有趣,因为看起来你创建 missile
s 并将其正确添加到组中(你可以通过打印 sprite 和组看到),但问题是您将相同的全局变量 bullet
分配给导弹的 self.rect
属性,这意味着所有导弹都放置在相同的位置。因此,当您更新矩形的坐标 (missile.rect.y = hero.rect.y - 20
) 时,您会影响所有导弹精灵,因为它们共享相同的矩形。
您应该删除 bullet
矩形并仅在 __init__
方法中创建 self.rect
,这样每个导弹都有自己的矩形(图像仍然可以共享)。
此外,最好在创建实例时将 x
和 y
坐标直接传递给 __init__
方法:
missile = Missiles(
hero.rect.x+35, hero.rect.y-20,
display_width,display_height,weapon, powerLevel)
class Missiles(pygame.sprite.Sprite):
def __init__(self, x, y, dw, dh, wpn, pwlvl):
super().__init__()
self.weapon = wpn
self.powerLevel = pwlvl
self.setFire()
# You can pass the `x, y` coordinates as the `topleft`,
# `center` or another argument.
self.rect = self.image.get_rect(center=(x, y))
# Or set the coordinates afterwards.
# self.rect.center = (x, y)
def setFire(self):
if self.weapon == 1:
if self.powerLevel == 1:
self.image = bullets
elif self.weapon == 2:
if self.powerLevel == 1:
self.image = frostLaserL1
elif self.powerLevel == 2:
self.image = frostLaserL2
else:
self.image = frostLaserL3
else:
if self.powerLevel == 1:
self.image = fireLaserL1
elif self.powerLevel == 2:
self.image = fireLaserL2
else:
self.image = fireLaserL3
def update(self):
self.rect.y -= 1
你需要对外星飞船做同样的事情:
class AlienPrivate(aliens): # Use uppercase names for classes.
def __init__(self, dw, dh, w, h):
super().__init__(dw, dh, w, h)
self.image = alienPrivateImg
x = random.randrange(display_width-w)
y = random.randrange(2*(-h), -h)
self.rect = self.image.get_rect(center=(x, y))
我是一名大学生,我有一个游戏项目(我们可以选择任何主题),一开始很顺利,但后来遇到了一些意想不到的问题。我选择创建一个简单版本的 raiden 2(space 飞船射击游戏),但是当它开始生成导弹和外星人时,它并没有像预期的那样工作。首先,当我按下 space 按钮时,导弹将被创建并从底部移动到顶部,但是当我再次按下它时,它不会创建第二个,或者可能会创建,但我只能看到导弹重新定位在 space 船的顶部加上速度增加(不打算)相反,我想在第一个移动时创建第二个。外星人 spaceship 也有同样的问题,实例创建并移动得很好,但是当第二个生成的时候到了,第一个刚刚重新定位到新坐标,它的速度 increased.Then 对于外星人我选择用 for 循环创建更多,然后移动它们,但速度再次提高,我只能看到一个。我还有 4 个不同的 classes 外星人需要生成,但如果我不能解决这些问题,我就无法继续。我还检查了一些教程和其他问题,但是当我尝试解决方案时它不起作用,我会继续搜索,但如果有人发现错误并可以给我一个例子,我将不胜感激。最后只是告诉你我正在使用图像作为精灵等。这是代码:
外星人:
class aliens(pygame.sprite.Sprite):
def __init__(self, dw, dh, w, h):
self.display_width = dw
self.display_height = dh
self.width = w
self.height = h
super().__init__()
第一个外星人:
class alienPrivate(aliens):
def __init__(self, dw, dh, w, h):
super().__init__(dw, dh, w, h)
self.image = alienPrivateImg
self.rect = privateRect
self.rect.x = random.randrange(0, display_width - w)
self.rect.y = random.randrange(2*(-h), -h)
self.weapon = 1
self.damage = 5
self.health = 10
self.speed = 4
# Private moves top -> bottom
def update(self):
self.rect.y += self.speed
导弹:
class Missiles(pygame.sprite.Sprite):
def __init__(self, dw, dh, wpn, pwlvl):
super().__init__()
self.weapon = wpn
self.powerLevel = pwlvl
self.setFire()
def setFire(self):
if self.weapon == 1:
if self.powerLevel == 1:
self.image = bullets
self.rect = bullet
elif self.weapon == 2:
if self.powerLevel == 1:
self.image = frostLaserL1
self.rect = frLaserL1
elif self.powerLevel == 2:
self.image = frostLaserL2
self.rect = frLaserL2
else:
self.image = frostLaserL3
self.rect = frLaserL3
else:
if self.powerLevel == 1:
self.image = fireLaserL1
self.rect = fLaserL1
elif self.powerLevel == 2:
self.image = fireLaserL2
self.rect = fLaserL2
else:
self.image = fireLaserL3
self.rect = fLaserL3
def update(self):
self.rect.y -= 1
导弹生成:
missile = Missiles(display_width,display_height,weapon, powerLevel)
missile.rect.x = hero.rect.x + 35
missile.rect.y = hero.rect.y - 20
all_sprites_list.add(missile)
fire_list.add(missile)
外星人产卵:
for spawn in range(5):
private = alienPrivate(display_width, display_height, 50, 88)
all_sprites_list.add(private)
alien_list.add(private)
玩家class:
class player(pygame.sprite.Sprite):
def __init__(self, dw, dh, w, h):
super().__init__()
self.health = 100
self.stamina = 100
self.width = w
self.height = h
self.image = spaceshipImgBee
self.rect = spaceshipRect
self.rect.x = (dw / 2) - (self.width / 2)
self.rect.y = dh - h
self.weapon = 1
self.powerLevel = 1
# Methods
def setPosx(self, x):
self.rect.x = x
def setPosy(self, y):
self.rect.y = y
def moveRigth(self, x):
self.rect.x += x
def moveLeft(self, y):
self.rect.y += y
def setWeapon(self, x):
if self.weapon == x:
if self.weapon == 1 and self.powerLevel == 1:
self.damage += 10
self.powerLevel += 1
elif self.weapon == 1 and (self.powerLevel > 1 and self.powerLevel < 3):
self.powerLevel += 1
elif self.weapon == 2 and self.powerlevel < 3:
self.damage += 15
self.powerLevel += 1
elif self.weapon == 3 and self.powerLevel < 3:
self.damage += 25
self.powerLevel += 1
else:
if x == 1:
self.weapon = x
self.damage = 10
self.powerLevel = 1
elif x == 2:
self.weapon = x
self.damage = 20
self.powerLevel = 1
elif x == 3:
self.weapon = x
self.damage = 50
self.powerLevel +=1
以及游戏的其余部分(一部分),包括 while 循环:
import pygame
import random
import time
# Colors
BLACK = (0,0,0)
WHITE = (255,255,255)
RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
# Start Pygame
pygame.init()
# Window Size and Name
display_width = 700
display_height = 600
gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Star Protector")
# Window refresh rate
fps = 60
clock = pygame.time.Clock()
#Images
spaceshipImgBee = pygame.image.load('Hero_Spaceship_Bee_80x79.png')
spaceshipRect = spaceshipImgBee.get_rect()
alienPrivateImg = pygame.image.load('Alien_Private_50x88.png')
privateRect = alienPrivateImg.get_rect()
bullets = pygame.image.load('Bullets_10x20.png')
bullet = bullets.get_rect()
all_sprites_list = pygame.sprite.Group()
alien_list = pygame.sprite.Group()
fire_list = pygame.sprite.Group()
hero = player(display_width,display_height, 80, 79)
all_sprites_list.add(hero)
killed = False
x = 0
y = 0
i = 0
l = 0
score = 0
while not killed:
weapon = hero.weapon
powerLevel = hero.powerLevel
for event in pygame.event.get():
if event.type == pygame.QUIT:
killed = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x = -10
i = 1
elif event.key == pygame.K_RIGHT:
x = 10
i = 1
elif event.key == pygame.K_UP:
y = -10
i = 2
elif event.key == pygame.K_DOWN:
y = 10
i = 2
elif event.key == pygame.K_SPACE:
if weapon == 1:
missile = Missiles(display_width,display_height,weapon, powerLevel)
missile.rect.x = hero.rect.x + 35
missile.rect.y = hero.rect.y - 20
all_sprites_list.add(missile)
fire_list.add(missile)
elif weapon == 2:
if powerLevel == 1:
frlaser = Missiles(display_width, display_height, weapon, powerLevel)
frlaser.rect.x = (hero.rect.x / 2) - 7
all_sprites_list.add(frlaser)
fire_list.add(frlaser)
elif powerLevel == 2:
frlaser = Missiles(display_width, display_height, weapon, powerLevel)
frlaser.rect.x = (hero.rect.x / 2) - 20
all_sprites_list.add(frlaser)
fire_list.add(frlaser)
else:
frlaser = Missiles(display_width, display_height, weapon, powerLevel)
frlaser.rect.x = (hero.rect.x / 2) - 40
all_sprites_list.add(frlaser)
fire_list.add(frlaser)
else:
if powerLevel == 1:
flaser = Missiles(display_width, display_height, weapon, powerLevel)
flaser.rect.x = (hero.rect.x / 2) -7
all_sprites_list.add(flaser)
fire_list.add(flaser)
elif powerLevel == 2:
flaser = Missiles(display_width, display_height, weapon, powerLevel)
flaser.rect.x = (hero.rect.x / 2) -20
all_sprites_list.add(flaser)
fire_list.add(flaser)
else:
flaser = Missiles(display_width, display_height, weapon, powerLevel)
flaser.rect.x = (hero.rect.x / 2) - 40
all_sprites_list.add(flaser)
fire_list.add(flaser)
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
x = 0
i = 1
elif event.key == pygame.K_UP or event.key == pygame.K_DOWN:
y = 0
i = 2
#Move the spaceship with boundaries
if i == 1:
hero.moveRigth(x)
elif i == 2:
hero.moveLeft(y)
if hero.rect.x > display_width - hero.width:
hero.setPosx(display_width - hero.width)
elif hero.rect.x < 0:
hero.setPosx(0)
elif hero.rect.y < 0:
hero.setPosy(0)
elif hero.rect.y > display_height - hero.height:
hero.setPosy(display_height - hero.height)
#Background Color - Image
gameDisplay.blit(backgCosmos, (0 ,l))
#gameDisplay.fill(WHITE)
if score == 100:
for spawn in range(5):
private = alienPrivate(display_width, display_height, 50, 88)
all_sprites_list.add(private)
alien_list.add(private)
if l + 600 > 600:
gameDisplay.blit(backgRepublic, (0 ,l -600))
l += 1
all_sprites_list.update()
#Print player - start the battle
all_sprites_list.draw(gameDisplay)
score += 1
pygame.display.update()
clock.tick(fps)
pygame.quit()
quit()
至于图片我不能上传它们(不知道为什么)但是你可以快速随机调整大小并测试它。感谢您的宝贵时间!
您使用不同的实例正确地生成了外星列兵,但需要对导弹执行相同的操作。 for i in range(number)
将给出单独的实例。否则,pygames sprite .add() 将假定您正在引用组中已存在的实例。
你能把你的游戏循环代码while True:
放在这里吗?
与此同时,检查将 .update() 传递给各个精灵是否会提高速度。最后,如果导弹离开显示屏,您只需 .remove() 即可。
这个 bug 修复起来很有趣,因为看起来你创建 missile
s 并将其正确添加到组中(你可以通过打印 sprite 和组看到),但问题是您将相同的全局变量 bullet
分配给导弹的 self.rect
属性,这意味着所有导弹都放置在相同的位置。因此,当您更新矩形的坐标 (missile.rect.y = hero.rect.y - 20
) 时,您会影响所有导弹精灵,因为它们共享相同的矩形。
您应该删除 bullet
矩形并仅在 __init__
方法中创建 self.rect
,这样每个导弹都有自己的矩形(图像仍然可以共享)。
此外,最好在创建实例时将 x
和 y
坐标直接传递给 __init__
方法:
missile = Missiles(
hero.rect.x+35, hero.rect.y-20,
display_width,display_height,weapon, powerLevel)
class Missiles(pygame.sprite.Sprite):
def __init__(self, x, y, dw, dh, wpn, pwlvl):
super().__init__()
self.weapon = wpn
self.powerLevel = pwlvl
self.setFire()
# You can pass the `x, y` coordinates as the `topleft`,
# `center` or another argument.
self.rect = self.image.get_rect(center=(x, y))
# Or set the coordinates afterwards.
# self.rect.center = (x, y)
def setFire(self):
if self.weapon == 1:
if self.powerLevel == 1:
self.image = bullets
elif self.weapon == 2:
if self.powerLevel == 1:
self.image = frostLaserL1
elif self.powerLevel == 2:
self.image = frostLaserL2
else:
self.image = frostLaserL3
else:
if self.powerLevel == 1:
self.image = fireLaserL1
elif self.powerLevel == 2:
self.image = fireLaserL2
else:
self.image = fireLaserL3
def update(self):
self.rect.y -= 1
你需要对外星飞船做同样的事情:
class AlienPrivate(aliens): # Use uppercase names for classes.
def __init__(self, dw, dh, w, h):
super().__init__(dw, dh, w, h)
self.image = alienPrivateImg
x = random.randrange(display_width-w)
y = random.randrange(2*(-h), -h)
self.rect = self.image.get_rect(center=(x, y))