- 第1章 简介
- 第2章 步骤1 – 精灵动画
- 第3章 步骤2 – 对象模型
- 第4章 步骤3 – 游戏逻辑与控制
- 第5章 步骤4 – 杂七杂八
4.3 敌人的行为
为了让敌人能够行动,我们已经完成了大部分的工作准备了,现在仅仅需要调用精灵节点对象上的 call()
方法。为了实现这个我们注册了一个每 30 毫秒就执行一次的回调函数(callback)。在回调函数中,我们通过 jQuery 选择了所以类名叫 enemy 的精灵。然后通过 each() 函数对每个选择到的精灵执行同一方法。当然游戏没结束之前我才需要这么做。
$.playground().registerCallback(function(){
if(!gameOver){
//Update the movement of the enemies
$(".enemy").each(function(){
this.enemy.update($("#player"));
var posx = parseInt($(this).css("left"));
if((posx + 150) < 0){
$(this).remove();
return;
}
//Test for collisions
var collided = $(this).collision("#playerBody,.group");
if(collided.length > 0){
if(this.enemy instanceof Bossy){
$(this).setAnimation(enemies[2]["explode"], function(node){$(node).remove();});
$(this).css("width", 150);
} else if(this.enemy instanceof Brainy) {
$(this).setAnimation(enemies[1]["explode"], function(node){$(node).remove();});
$(this).css("width", 150);
} else {
$(this).setAnimation(enemies[0]["explode"], function(node){$(node).remove();});
$(this).css("width", 100);
}
$(this).removeClass("enemy");
//The player has been hit!
if($("#player")[0].player.damage()){
explodePlayer($("#player"));
}
}
});
}
}, REFRESH_RATE);
我们还得好好想想敌人怎么从左边出去的问题。事实上,它们既回不来也不会再被玩家射中,所以让它们继续留在游戏里还有什么意义呢?jQuery 函数 remove()
会移除那些 没有用处的敌人
,关键字 return 使得函数在此地停下。函数的第二部分关注的是敌人与玩家飞船的碰撞检测。
gameQuery 函数 collision 返回指定对象之间发生碰撞的个体的列表。参数值是过滤器的作用。当你为其指定参数,collision 函数会检测指定元素的碰撞情况。由于碰撞检测是个开销相当大的函数,所以拜托少用点。这里我们检测的是 groups 与 player,gameQuery 为那些通过 addGroup()
方法创建的节点添加了共同的类名 group。我们需要对每个组检测,因为 player 是被嵌套在组当中而返回结果却只是精灵的集合。
在当前版本的 gameQuery 中,collision 函数把精灵认定是标准的盒子形状(这意味着没有一像素一像素的检测过去),所以会发生类似下面那样的情况。我希望更多的选项能在将来的版本中得到实现。
每当碰撞发生的时候,我们需要让敌人爆炸,让玩家掉护盾。为了实现敌人爆炸效果,我们就简单的将敌人动画替换成爆炸动画(记住如果你需要的话,你可以改变精灵的大小)。但爆炸动画只需播放一次,然后就应该被移除。这也是 Animation.CALLBACK
被被使用的原因!当设置动画的时候,你可以将函数作为第二个参数传入。这个函数将会在动画结束的时候被自动调用。在这个例子当中,我们只是简单的移除节点。在这里有个小陷阱,我们必须把退场精灵从 enemy 类中移除,否则的话下次函数被调用的时候会把爆炸对象作为一个敌人的。
我们在步骤 2 中已经写过管理玩家 伤害
的函数了,当函数返回 true 代表飞船该爆炸了。我们已经将飞船爆炸函数从中分离开来了,因为这段代码还会被使用到几次。
$.playground().registerCallback(function(){
if(!gameOver){
//Update the movement of the enemies
$(".enemy").each(function(){
this.enemy.update($("#player"));
var posx = parseInt($(this).css("left"));
if((posx + 150) < 0){
$(this).remove();
return;
}
//Test for collisions
var collided = $(this).collision("#playerBody,.group");
if(collided.length > 0){
if(this.enemy instanceof Bossy){
$(this).setAnimation(enemies[2]["explode"], function(node){$(node).remove();});
$(this).css("width", 150);
} else if(this.enemy instanceof Brainy) {
$(this).setAnimation(enemies[1]["explode"], function(node){$(node).remove();});
$(this).css("width", 150);
} else {
$(this).setAnimation(enemies[0]["explode"], function(node){$(node).remove();});
$(this).css("width", 100);
}
$(this).removeClass("enemy");
//The player has been hit!
if($("#player")[0].player.damage()){
explodePlayer($("#player"));
}
}
});
}
}, REFRESH_RATE);
由于玩家是个包含了一系列精灵的组,所以我们不能简单的为其更改动画。我们需要隐藏正常精灵,然后将其替换为新的精灵。jQuery 的 hide 函数会隐藏所有被选中的节点,获取节点是通过 jQuery 的 children 方法。然后我们就可以设置正确的游戏状态,以便游戏知道飞船现在正处于爆炸。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论