Pygame 精灵不绘制
Pygame Sprite Not Drawing
所以我正在创建这个小行星射击游戏,我有一个 class 叫做 Laser。因为我需要创建很多激光,所以我为此 class 创建了一个精灵组并添加了 25 个精灵。我正在这样做,每当用户按下 space 栏时,组中的最后一个激光(我设法使用 sprite 列表组织它)使用 Vector2D 穿过屏幕,其余激光是 "hidden" 在 space 飞船外观下。
这是激光 class:
的代码
import pygame
class Laser(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pygame.image.load("laser.png")
self.scale = 0.05
self.image = pygame.transform.smoothscale(
self.image,
(int(self.image.get_rect().width * self.scale),
int(self.image.get_rect().height * self.scale)),
)
self.rect = self.image.get_rect()
# Getting the rectangle around the image lets you move it.
self.rect.center = pos
self.speed = pygame.math.Vector2(0, -5)
self.speed.rotate_ip(0)
self.track = 0
def update(self, pos):
if self.track == 0:
self.rect.move_ip(pos)
def move(self):
self.rect.move_ip(self.speed)
self.track = self.track + 1
# self.track makes it so that the program knows not to call the update function for this Laser object.
main.py中有关激光拍摄和创作的代码片段(包含所有代码会太多):
global lasers
player.collect((width/2, height), spriteNum)
for i in range(0, 25):
lasers.add(Laser((width/2, height)))
init()
while True:
screen.fill([255, 255, 255])
bigger_img = pygame.transform.scale(background.image, (width, height))
screen.blit(bigger_img, (0, 0))
playerPosition = player.update()
lasers_list = lasers.sprites()
for i in range(0, len(lasers_list)):
lasers_list[i].update(playerPosition)
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if lasers_list[i].rect.top < 0:
lasers.remove(lasers_list[i])
enemies.update(speed)
clock.tick(60)
last_laser = lasers.sprites()[len(lasers_list) - 1]
player_hit = pygame.sprite.spritecollide(player, enemies, False)
screen.blit(player.image, player.rect)
enemies.draw(screen)
lasers.draw(screen)
screen.blit(last_laser.image, last_laser.rect)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.speed[0] = 5
if event.key == pygame.K_LEFT:
player.speed[0] = -5
if event.key == pygame.K_UP:
player.speed[1] = -5
if event.key == pygame.K_DOWN:
player.speed[1] = 5
if (event.key == pygame.K_SPACE):
if (len(lasers_list) - 1) > -1:
last_laser.move()
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.speed[0] = 0
if event.key == pygame.K_LEFT:
player.speed[0] = 0
if event.key == pygame.K_UP:
player.speed[1] = 0
if event.key == pygame.K_DOWN:
player.speed[1] = 0
if event.key == pygame.K_SPACE:
abcd = "0"
#nothing, I don't feel like I need anything here since no lasers would be launched if the spacebar was up.
好的,所以如果我更改代码,last_laser 就会显示:
if (event.key == pygame.K_SPACE):
if (len(lasers_list) - 1) > -1:
last_laser.move()
对此:
if (event.key == pygame.K_SPACE):
last_laser.rect.center = (400, 400)
# Some arbitrary x and y values (400, 400).
last_laser.track += 1
picture of laser showing up on the screen
但是有很多我想要的东西对上面的代码不满意。首先,我希望激光射出并在屏幕上移动(我知道移动是像素的重新着色)。另外,我希望它移动到不同的位置,因为它取决于用户移动 his/her space 将精灵运送到哪里并从哪里射击。几个小时以来,我一直在努力寻找解决方案,并专门为这个问题制作了一个堆栈溢出帐户,我们将不胜感激。 :)
编辑:
激光正在发射,但现在我需要弄清楚玩家如何发射多束激光。我的意思是玩家应该能够按下 space,等待几秒钟,然后再次按下 space,屏幕上应该会出现 2 道激光。目前,如果玩家这样做,屏幕上的激光将被擦除然后重新定位,因此看起来像是来自 space 飞船的新激光。这让玩家感到困惑,因为激光刚刚上升 "disappears"。
首先,你有一个Sprite组中的所有激光,但是你从该组中获取所有激光并将它们放入一个列表中,然后循环遍历列表以更新并绘制它们,然后再次绘制它们通过 sprite 组,这是不必要的,而是将所有 sprite 都放在 Sprite 组中并调用 lasers.update()
和 lasers.draw(screen)
,或者将它们放在列表中并执行您现在正在做的事情,除了这里
for i in range(0, 25):
lasers.add(Laser((width/2, height)))
变成
for i in range(0, 25):
lasers_list.append(Laser((width/2, height)))
还有很多行可以缩短,看起来更简洁
last_laser = lasers.sprites()[len(lasers_list) - 1]
last_laser = lasers.sprites()[-1] #-1 gets the last in list
if (len(lasers_list) - 1) > -1:
if len(lasers_list) > 0:
self.track = self.track + 1
self.track += 1
也会搬家
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if lasers_list[i].rect.top < 0:
lasers.remove(lasers_list[i])
到激光中的更新功能class
def update(self, pos):
if self.track == 0:
self.rect.move_ip(pos)
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if self.rect.top < 0:
self.kill() #deletes from sprite group
在激光class的更新功能中我会添加
def update(self, pos):
if self.track == 0:
self.rect.move_ip(pos)
else: #if not moving with ship
self.move() # so it moves on its own
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if self.rect.top < 0:
self.kill() #deletes from sprite group
因为这个
if (event.key == pygame.K_SPACE):
if len(lasers_list) > 0:
last_laser.move()
当您按下 space 时,它会继续移动相同的激光,直到它到达顶部并被移除。如果那是你想要的,它并不完美,但它会做。否则你可能需要一个计数器,对激光进行倒计时。
所以我认为这解决了你问题的第二部分。至于当你按下 space 时激光不显示,如果你清理你的代码并使用精灵组或列表,而不是两者,那么它应该可以工作,如果没有,post 你所有的代码所以我可以重新创建它。
所以我正在创建这个小行星射击游戏,我有一个 class 叫做 Laser。因为我需要创建很多激光,所以我为此 class 创建了一个精灵组并添加了 25 个精灵。我正在这样做,每当用户按下 space 栏时,组中的最后一个激光(我设法使用 sprite 列表组织它)使用 Vector2D 穿过屏幕,其余激光是 "hidden" 在 space 飞船外观下。 这是激光 class:
的代码import pygame
class Laser(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pygame.image.load("laser.png")
self.scale = 0.05
self.image = pygame.transform.smoothscale(
self.image,
(int(self.image.get_rect().width * self.scale),
int(self.image.get_rect().height * self.scale)),
)
self.rect = self.image.get_rect()
# Getting the rectangle around the image lets you move it.
self.rect.center = pos
self.speed = pygame.math.Vector2(0, -5)
self.speed.rotate_ip(0)
self.track = 0
def update(self, pos):
if self.track == 0:
self.rect.move_ip(pos)
def move(self):
self.rect.move_ip(self.speed)
self.track = self.track + 1
# self.track makes it so that the program knows not to call the update function for this Laser object.
main.py中有关激光拍摄和创作的代码片段(包含所有代码会太多):
global lasers
player.collect((width/2, height), spriteNum)
for i in range(0, 25):
lasers.add(Laser((width/2, height)))
init()
while True:
screen.fill([255, 255, 255])
bigger_img = pygame.transform.scale(background.image, (width, height))
screen.blit(bigger_img, (0, 0))
playerPosition = player.update()
lasers_list = lasers.sprites()
for i in range(0, len(lasers_list)):
lasers_list[i].update(playerPosition)
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if lasers_list[i].rect.top < 0:
lasers.remove(lasers_list[i])
enemies.update(speed)
clock.tick(60)
last_laser = lasers.sprites()[len(lasers_list) - 1]
player_hit = pygame.sprite.spritecollide(player, enemies, False)
screen.blit(player.image, player.rect)
enemies.draw(screen)
lasers.draw(screen)
screen.blit(last_laser.image, last_laser.rect)
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.speed[0] = 5
if event.key == pygame.K_LEFT:
player.speed[0] = -5
if event.key == pygame.K_UP:
player.speed[1] = -5
if event.key == pygame.K_DOWN:
player.speed[1] = 5
if (event.key == pygame.K_SPACE):
if (len(lasers_list) - 1) > -1:
last_laser.move()
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.speed[0] = 0
if event.key == pygame.K_LEFT:
player.speed[0] = 0
if event.key == pygame.K_UP:
player.speed[1] = 0
if event.key == pygame.K_DOWN:
player.speed[1] = 0
if event.key == pygame.K_SPACE:
abcd = "0"
#nothing, I don't feel like I need anything here since no lasers would be launched if the spacebar was up.
好的,所以如果我更改代码,last_laser 就会显示:
if (event.key == pygame.K_SPACE):
if (len(lasers_list) - 1) > -1:
last_laser.move()
对此:
if (event.key == pygame.K_SPACE):
last_laser.rect.center = (400, 400)
# Some arbitrary x and y values (400, 400).
last_laser.track += 1
picture of laser showing up on the screen
但是有很多我想要的东西对上面的代码不满意。首先,我希望激光射出并在屏幕上移动(我知道移动是像素的重新着色)。另外,我希望它移动到不同的位置,因为它取决于用户移动 his/her space 将精灵运送到哪里并从哪里射击。几个小时以来,我一直在努力寻找解决方案,并专门为这个问题制作了一个堆栈溢出帐户,我们将不胜感激。 :)
编辑: 激光正在发射,但现在我需要弄清楚玩家如何发射多束激光。我的意思是玩家应该能够按下 space,等待几秒钟,然后再次按下 space,屏幕上应该会出现 2 道激光。目前,如果玩家这样做,屏幕上的激光将被擦除然后重新定位,因此看起来像是来自 space 飞船的新激光。这让玩家感到困惑,因为激光刚刚上升 "disappears"。
首先,你有一个Sprite组中的所有激光,但是你从该组中获取所有激光并将它们放入一个列表中,然后循环遍历列表以更新并绘制它们,然后再次绘制它们通过 sprite 组,这是不必要的,而是将所有 sprite 都放在 Sprite 组中并调用 lasers.update()
和 lasers.draw(screen)
,或者将它们放在列表中并执行您现在正在做的事情,除了这里
for i in range(0, 25):
lasers.add(Laser((width/2, height)))
变成
for i in range(0, 25):
lasers_list.append(Laser((width/2, height)))
还有很多行可以缩短,看起来更简洁
last_laser = lasers.sprites()[len(lasers_list) - 1]
last_laser = lasers.sprites()[-1] #-1 gets the last in list
if (len(lasers_list) - 1) > -1:
if len(lasers_list) > 0:
self.track = self.track + 1
self.track += 1
也会搬家
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if lasers_list[i].rect.top < 0:
lasers.remove(lasers_list[i])
到激光中的更新功能class
def update(self, pos):
if self.track == 0:
self.rect.move_ip(pos)
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if self.rect.top < 0:
self.kill() #deletes from sprite group
在激光class的更新功能中我会添加
def update(self, pos):
if self.track == 0:
self.rect.move_ip(pos)
else: #if not moving with ship
self.move() # so it moves on its own
screen.blit(lasers_list[i].image, lasers_list[i].rect)
if self.rect.top < 0:
self.kill() #deletes from sprite group
因为这个
if (event.key == pygame.K_SPACE):
if len(lasers_list) > 0:
last_laser.move()
当您按下 space 时,它会继续移动相同的激光,直到它到达顶部并被移除。如果那是你想要的,它并不完美,但它会做。否则你可能需要一个计数器,对激光进行倒计时。
所以我认为这解决了你问题的第二部分。至于当你按下 space 时激光不显示,如果你清理你的代码并使用精灵组或列表,而不是两者,那么它应该可以工作,如果没有,post 你所有的代码所以我可以重新创建它。