一、构建父类
无论什么样的敌人,无论其行动、AI如何,能力强弱、大小各异,它们总会有一些共同的属性,例如无论什么样的敌人都具有生命值、攻击力等基本的属性。
从这里出发,我们可以使用类的继承来简化代码量,避免重复造轮子。
首先,我们先构建一个敌人基类:
import pygame
class Monster(pygame.sprite.Sprite):maxHp: intHp: intAd: intindex = 0status = "standing"direction = -1images: mapdef update(self):"""敌人动作"""def die(self):"""敌人死亡后事件"""
复制代码
首先,可以看到,我们先继承了pygame提供了精灵类,使该类获得了一些常用的工具函数。
然后,我们为其定义了几个属性最大生命、生命、攻击,并标注了其数据类型。
另外,对于一些通用的变量,我们直接在父类进行赋值。
最后,我们定义了一些通用的函数作为接口,提供给子类进行覆写。
二、继承父类
接下来,我们来创建第一种类型的敌人-史莱姆:
class Shrem(Monster):speed: intdef update(self):self.rect.left += self.speed * self.directionself.index = (self.index + 1) % len(self.images[self.status])self.image = self.images[self.status][self.index]if self.direction == -1:self.image = pygame.transform.flip(self.image, True, False)
复制代码
首先, 在类名称后面括号中写上刚刚的Monster,表示对总的敌人类进行一个继承。
然后,添加属于史莱姆这类怪物特有的属性(如:速度)。
接着统一定义史莱姆这类怪物的动作Ai(写在update中),上面给出了案例表示史莱姆仅单向按速度进行位移,仅作为演示。实际怪物的Ai一定比这复杂的多(可能还会加入嗅探玩家、状态动作等)。
折腾了这么多,终于可以开始构建一个可用的类了:
class GreenShrem(Shrem):def __init__(self, location=[300, 270]):pygame.sprite.Sprite.__init__(self)self.speed = 1self.maxHp = 100self.Hp = 100self.Ad = 1self.image = pygame.image.load("./resourse/monsters/shrems/green_shrem/stand/1.png")self.rect = self.image.get_rect()self.rect.left, self.rect.top = locationself.status = "moving"self.images = {"standing": [pygame.image.load(f"./resourse/monsters/shrems/green_shrem/stand/{i+1}.png") for i in range(1)],"moving": [pygame.image.load(f"./resourse/monsters/shrems/green_shrem/move/{i+1}.png") for i in range(18)],"dying": [pygame.image.load(f"./resourse/monsters/shrems/green_shrem/die/{i+1}.png") for i in range(3)]}
复制代码
继承上面的史莱姆类,添加一个绿史莱姆类GreenShrem。
由于上面已经定义了史莱姆的Ai,在此处就无需添加了。我们只需要确定怪物的属性并加载其特定的资源即可。
同理,可以快速构建一个蓝史莱姆类BlueShrem(为做出区别,速度speed设为2)。
三、加入敌人
class Game:def __init__(self, width, height):self.monsters = [GreenShrem([400, 270]), BlueShrem([500, 270])]
复制代码
在Game类下创建一个list用于存储所有敌人对象(目前先在初始化的时候加入敌人,加入方式后面会换)。
def update(self):for monster in self.monsters:self.screen.blit(monster.image, monster.rect)for monster in self.monsters:monster.update()
复制代码
在Game.update()中加入敌人的显示和更新,原来和人物一模一样,只是加了一个遍历而已。
实现效果: