python - 添加第二个精灵不适用于 pygame 教程
问题描述
我一直在使用本教程中的这段代码https://opensource.com/article/18/5/pygame-enemy但我不能简单地通过使用来添加更多敌人
enemy = Enemy(40,100,'spr.png')# spawn enemy
enemy_list = pygame.sprite.Group() # create enemy group
enemy_list.add(enemy) # add enemy to group
原始图像来自这里 https://opengameart.org/sites/default/files/opp2_sprites.zip 但我已经在 imgur 中分开以便于解释:
内容文件夹图像:
雪人.png: https ://imgur.com/GNNcU6z
舞台.png: https ://imgur.com/YyiEJ0q
以及我想放的第二个敌人(精灵)的形象
spr.png: https ://imgur.com/1fYXa7Y
我尝试使用这个类似问题的解决方案如何在 pygame 中添加敌人?,但只是得到错误或没有结果。
我的代码:
import pygame
import sys
import os
'''
Objects
'''
class Enemy(pygame.sprite.Sprite):
'''
Spawn an enemy
'''
def __init__(self, x, y, img):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(os.path.join('images', img))
#self.image.convert_alpha()
#self.image.set_colorkey(ALPHA)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.counter = 0
def move(self):
'''
enemy movement
'''
distance = 20
speed = 8
if self.counter >= 0 and self.counter <= distance:
self.rect.x += speed
elif self.counter >= distance and self.counter <= distance * 2:
self.rect.x -= speed
else:
self.counter = 0
self.counter += 1
class Level():
def bad(lvl,eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
enemy_list = pygame.sprite.Group() # create enemy group
enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return enemy_list
class Player(pygame.sprite.Sprite):
'''
Spawn a player
'''
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.movex = 0
self.movey = 0
self.frame = 0
self.health = 10
self.frame = 0
self.images = []
for i in range(1, 5):
img = pygame.image.load(
os.path.join('images', 'hero' + str(i) + '.png')).convert()
img.convert_alpha()
img.set_colorkey(ALPHA)
self.images.append(img)
self.image = self.images[0]
self.rect = self.image.get_rect()
def control(self, x, y):
'''
control player movement
'''
self.movex += x
self.movey += y
def update(self):
'''
Update sprite position
'''
self.rect.x = self.rect.x + self.movex
self.rect.y = self.rect.y + self.movey
# moving left
if self.movex < 0:
self.frame += 1
if self.frame > 3 * ani:
self.frame = 0
self.image = self.images[self.frame // ani]
# collisions
enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
for enemy in enemy_hit_list:
self.health -= 1
print(self.health)
# moving right
if self.movex > 0:
self.frame += 1
if self.frame > 3 * ani:
self.frame = 0
self.image = self.images[(self.frame // ani)]
'''
Setup
'''
worldx = 560
worldy = 520
fps = 40 # frame rate
ani = 4 # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True
BLUE = (25, 25, 200)
BLACK = (23, 23, 23)
WHITE = (254, 254, 254)
ALPHA = (0, 255, 0)
world = pygame.display.set_mode([worldx, worldy])
backdrop = pygame.image.load(os.path.join('images', 'stage.png')).convert()
backdropbox = world.get_rect()
player = Player() # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10 # how fast to move
eloc = []
eloc = [200,20]
enemy_list = Level.bad( 1, eloc )
'''
Main loop
'''
while main == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
main = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.control(-steps, 0)
if event.key == pygame.K_RIGHT or event.key == ord('d'):
player.control(steps, 0)
if event.key == pygame.K_UP or event.key == ord('w'):
print('jump')
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == ord('a'):
player.control(steps, 0)
if event.key == pygame.K_RIGHT or event.key == ord('d'):
player.control(-steps, 0)
if event.key == ord('q'):
pygame.quit()
sys.exit()
main = False
# world.fill(BLACK)
world.blit(backdrop, backdropbox)
player.update()
player_list.draw(world) #refresh player position
enemy_list.draw(world)
for e in enemy_list:
e.move()
pygame.display.flip()
clock.tick(fps)
解决方案
您的代码有许多问题需要注意。
看看Level类。您需要在类中使用 self 来引用类函数和变量。我添加了第二个函数来添加第二个敌人(spr.png),因此我将enemy_list 放在函数之外,在类级别,这样两个函数都可以访问它。
class Level:
def __init__(self):
self.enemy_list = pygame.sprite.Group() # create enemy group
def bad_1(self, lvl, eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
self.enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return self.enemy_list
def bad_2(self, lvl, eloc):
if lvl == 1:
enemy = Enemy(eloc[0],eloc[1],'spr.png') # spawn enemy
self.enemy_list.add(enemy) # add enemy to group
if lvl == 2:
print("Level " + str(lvl) )
return self.enemy_list
我也改变了这部分。首先,您需要实例化该类(参见 l = Level()),然后您可以使用它的函数和变量。请注意,您只调用了 Level.bad() 一次,所以只有一个敌人!
steps = 10 # how fast to move
l = Level()
eloc = [200,20]
enemy_list = l.bad_1(1, eloc)
eloc = [100,10]
enemy_list = l.bad_2(1, eloc)
我的代码是一个相当“黑客”,快速且易于查看的东西,但它现在可以工作......
推荐阅读
- ios - 在模拟器上使用 iOS 14 VNRecognizeTextRequest 更好地识别文本,然后是 iPhone
- html - 如何使段落居中
- javascript - 不允许在 lib-jitsi-meet 中启动 Audiocontext
- reactjs - 如何从 React Typescript 的整个项目中删除未使用的导入/声明?
- r - 如何在 R 中解析可能使用 SRSS 生成的 XML 文件?
- html - 当定位为静态/相对时,HTML 和 body 标签如何或为什么占用视口的宽度和高度?
- r - R中DF中特定列的前几行
- data-visualization - 如何从 Tableau 中的用户登录数据进行群组用户保留分析?
- angular - 如何在角度 2 中动态设置 index.html 中的 Google 地图键?
- asp.net-core - Nlog - 无法记录 aspnet-request-ip