添加敌人
希望现在你已经对添加精灵和动画很熟悉了。所以为了简明,步骤不再完整重复。让我们添加敌人精灵。
1. 在图层中添加新精灵
2. 导入精灵带图Enemies\Snail
3. 删除动画的第一帧
4. 设置动画循环,速度15
5. 设置敌人图像原点,应用在全部动画
6. 裁剪多余的空白((shift + crop)
7. 关闭动画编辑器兵重名对象为SnailEnemy'
8. 在地面上放置Snail
现在我们想应用以下逻辑:
- 如果玩家撞上了snail,玩家角色闪烁且受伤。
- 如果玩家跳到了snail的上方,snail被杀死。
为了使玩家角色闪烁,选择玩家并且添加add the Flash behavior。记住选择正确的玩家角色,而不是玩家角色盒子。我们要使用Flash行为。
转回到事件表单,添加新事件。
PlayerBox -> On collision with another object -> SnailEnemy
当我们和敌人在任何角度碰撞时,事件就会触发。我们可以用二级事件去检测玩家是跳跃到了敌人头上还是撞到了边上。
给碰撞添加一个二级事件:
PlayerBox -> Is falling
我们应该检测玩家是否在敌人正上方。这能避免敌人被意外杀死,例如我们只是碰撞到了边缘。右击条件 the 'Is falling然后选择'Add another condition。记住,所有条件都得被满足才能运行。添加条件:
PlayerBox -> Compare Y -> Less than, SnailEnemy.Y
Y值向下增加,所以如果玩家的Y值比snail的更小,玩家就是在snail上方。
在此事件里添加条件:
SnailEnemy -> Destroy
我们也能添加其他行动来使玩家角色弹起来:
PlayerBox -> Set vector Y -> -700
设置向量Y基本意味着设置平台运动的垂直速度。设为负值意味着向上(Y向下增加),700是一个比跳跃强度1100小的值。因此这会让玩家角色弹起好像在做一个小跳。
我们还没完全干完—右击事件'Is falling的空白处,然后选择Add -> Else。否则是一个特殊的条件,如果事件没运行,它就会运行。所以当我们和snail碰撞但是没有跳到它头上时就会运行,比方说我们从边上上去。在这里我们希望玩家角色受伤。添加行动。
Player -> Flash -> (leave default values and click Done)
记住玩家角色对象要闪烁,不是玩家角色盒子。
现在玩家角色永远不会死,他们只是闪烁而已。但是我们已经能判断出他们是否跳在了正上方。教程不会覆盖全部,但是希望你能增加杀死效果(尝试在敌人死后创建poof精灵,使用Spawn object'行动),让玩家减血(在使玩家角色闪烁的事件里,你可以用增加变量的方法见例子top-down shooter tutorial )。
现在让敌人snail在平台上来回移动。
移动敌人
移动snail的主要问题是怎么判定到达了平台边缘。最简单的方法是添加一个不可见的边缘标志。可以在平台的边缘设置不可见的对象作为边缘,触碰它们就会返回。
我们也可以为snail设置平台行为。这有以下便利:
- 它能从左到右移动。
- 它能像玩家一样上下。
- 如果你想的话,它也能从边缘掉下去。
- 如果你想要一个跳跃的敌人,可以用simulate control使它自动跳跃
给snail敌人精灵添加平台行为。因为我们在这个对象上不会用太复杂的动画,我们可以直接用本身,不需要添加盒子。注意如果你制作了一个不同的平台游戏,敌人有复杂动画的话,你要把它当玩家角色处理。
我们不想让玩家角色控制snail敌人。我们想让它自动控制。我们可以设置Default controls属性为No,然后用行动Simulate control。因为snail的动作很慢,所以把最大速度设为50,把加速度和减速度设为100.
我们也需要边缘标签。添加一个新的精灵对象载入不透明的长方形,命名为EdgeMarker。把大小改为40 x 40,把Initial visibility设为Invisible。这样就看不见。把它放在每个snail平台的边缘处(别忘了拖动批量复制)。
snail也需要知道它现在移动的路线-朝左或朝右,我们要设置instance variables。每个对象的实例都有简单的数字或文字。如果我们有多个snail,它们每一个都单独储存了变量。这使每个snail都有不同的血量、方向等等。一个简单的自动控制敌人的方法是创建行动实例变量去储存当前的情况。比如,它可以跑开,追踪玩家角色或者休闲。我们现在只需要设置朝左或朝右。
选择snail敌人对象,在属性面板里,在Instance variables里点击Add / Edit。
所有对象的实例变量会在一个对话列表里显示。点击添加按钮加一个。把名字设为action,类型为文本,初始值为右(往右移动)。
点击OK,关闭实例变量对话窗。回到事件表单。
我们想实现以下逻辑:
- 如果行动是向右,模拟平台移动使snail向右移动。
- 如果行动是向左,模拟平台移动使snail向左移动。
而且:
- 如果snail达到了边缘标志,反转它的行动方向(左变右,右变左)。
我们可以用以下两个事件来达成这个行动:
Event SnailEnemy -> Compare instance variable -> action equal to "right" (双击显示文本)
Action SnailEnemy -> Simulate control -> Right
向左也是一样。我们也想让它镜像,就像我们对玩家角色做的。所以在left事件里添加*SnailEnemy -> Set mirrored,在right事件里添加SnailEnemy -> Set not mirrored。看起来会是这样:
现在在边缘处反转snail的方向:
Event: SnailEnemy -> On collision with another object -> EdgeMarker
Subevent: SnailEnemy -> Compare instance variable -> action equal to "right"
Action: SnailEnemy -> Set value -> action to "left"
Subevent: Else
Action: SnailEnemy -> Set value -> action to "right"
在这里用else很重要,因为事件都是从头到底运行的。如果不用else,行动就等同于left,注意以前的事件已经这么设置。所以它会重设,整体没有效果变化。使用了else,我们就阻止了第二个事件的运行。
运行工程。注意snail在平台上来回移动。这让跳跃变得难了!这是个非常初步的AI系统,所以希望你能创建出更智能的AI来,你可以用更多的事件去控制行动,比方说允许它们从边缘上落下,或者用跳跃扳机使它们知道什么时候该跳上一个平台。
试着在平台上创建两个snail。注意到它们是如何自我控制的,因为有不同的实例变量。希望你能明白实例变量对于控制实例独立是多么重要—你可不想让它们都看起来一模一样!