用Pygame写游戏-从入门到精通14
用Pygame写游戏-从入门到精通14
上一次稍微说了一下AI,为了更好的理解它,我们必须明白什么是状态机。有限状态机(英语:finite-state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。太抽象了,我们看看上一次的机器人的状态图,大概是长的这个样子:
状态定义了两个内容:
- 当前正在做什么
- 转化到下一件事时候的条件
状态同时还可能包含进入(entry)和退出(exit)两种动作,进入时间是指进入某个状态时要做的一次性的事情,比如上面的怪,一旦进入攻击状态,就得开始计算与玩家的距离,或许还得大吼一声“我要杀了你”等等;而退出动作则是与之相反的,离开这个状态要做的事情。
我们来创建一个更为复杂的场景来阐述这个概念——一个蚁巢世界。我们常常使用昆虫来研究AI,因为昆虫的行为很简单容易建模。在我们这次的环境里,有三个实体(entity)登场:叶子、蜘蛛、蚂蚁。叶子会随机的出现在屏幕的任意地方,并由蚂蚁回收至蚁穴,而蜘蛛在屏幕上随便爬,平时蚂蚁不会在意它,而一旦进入蚁穴,就会遭到蚂蚁的极力驱赶,直至蜘蛛挂了或远离蚁穴。
尽管我们是对昆虫建模的,这段代码对很多场景都是合适的。把它们替换为巨大的机器人守卫(蜘蛛)、坦克(蚂蚁)、能源(叶子),这段代码依然能够很好的工作。
游戏实体类
这里出现了三个实体,我们试着写一个通用的实体基类,免得写三遍了,同时如果加入了其他实体,也能很方便的扩展出来。
一个实体需要存储它的名字,现在的位置,目标,速度,以及一个图形。有些实体可能只有一部分属性(比如叶子不应该在地图上瞎走,我们把它的速度设为0),同时我们还需要准备进入和退出的函数供调用。下面是一个完整的GameEntity类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class GameEntity(object): def __init__(self, world, name, image): self.world = world self.name = name self.image = image self.location = Vector2(0, 0) self.destination = Vector2(0, 0) self.speed = 0. self.brain = StateMachine() self.id = 0 def render(self, surface): x, y = self.location w, h = self.image.get_size() surface.blit(self.image, (x-w/2, y-h/2)) def process(self, time_passed): self.brain.think() if self.speed > 0 and self.location != self.destination: vec_to_destination = self.destination - self.location distance_to_destination = vec_to_destination.get_length() heading = vec_to_destination.get_normalized() travel_distance = min(distance_to_destination, time_passed * self.speed) self.location += travel_distance * heading |