python - Pygame Sprite 不绘图
问题描述
所以我正在创建这个小行星射击游戏,并且我有一个名为 Laser 的课程。因为我需要创建很多激光,所以我为这个类创建了一个 Sprite Group 并添加了 25 个 sprite。我正在这样做,每当用户按下空格键时,组中的最后一个激光(我设法使用精灵列表组织它)使用 Vector2D 穿过屏幕,其余的激光被“隐藏”在宇宙飞船下精灵。这是激光类的代码:
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
但是有很多我想要的东西对上面的代码不满意。首先,我希望激光射出并像在屏幕上移动一样(我知道移动是像素的重新着色)。此外,我希望它去到不同的位置,因为它将依赖于用户将他/她的宇宙飞船精灵移动到哪里以及从哪里射击。几个小时以来,我一直在努力寻找解决方案,并专门为这个问题制作了一个堆栈溢出帐户,任何帮助将不胜感激。:)
编辑:激光正在发射,但现在我需要弄清楚玩家如何发射多个激光。我的意思是玩家应该能够按空格键,等待几秒钟,然后再次按空格键,屏幕上应该会出现 2 道激光。目前,如果玩家这样做,屏幕上的激光将被擦除然后重新定位,因此看起来新的激光来自宇宙飞船。这让玩家感到困惑,因为刚刚上升的激光“消失了”。
解决方案
首先,你有一个 Sprite 组中的所有激光,但是你从组中获取所有激光并将它们放入一个列表中,然后循环遍历列表以更新和绘制它们,然后通过精灵组再次绘制它们,这是不必要的,而是将所有精灵放在 Sprite 组中并调用 lasers.update()
and 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])
到激光类中的更新功能
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
在激光类的更新功能中,我会添加
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()
当你按下空格键时,它会继续移动相同的激光,直到它到达顶部并被移除。如果这就是你想要的,它并不完美,但它会做到的。否则,您可能需要一个计数器,用于对激光进行倒计时。
所以我认为这解决了你问题的第二部分。至于按下空格时激光不显示,如果您清理代码并使用精灵组或列表,而不是两者,那么它应该可以工作,如果没有,请发布您的所有代码,以便我可以重新创建它。
推荐阅读
- navigation - 关于 href="#" 的可访问性
- python - 用于高维度的 Einsum
- python - 无法打开文件“manage.py”:[Errno 2] 没有这样的文件或目录
- c++ - 不被识别为内部或外部命令
- macos - 签名无效的 macOS kext
- python - 在容器内运行时 pipenv 安装失败
- java - 如何使用安装在 windows 中的 maven,在 windows 子系统 for Linux
- java - 如何在firebase数据库中进行多个查询?
- user-controls - UC卸载时WPF MVVM处理ViewModel
- python - 使用分隔符将一列分成三列