返回介绍

4.3 敌人的行为

发布于 2024-07-13 13:20:42 字数 3295 浏览 0 评论 0 收藏 0

为了让敌人能够行动,我们已经完成了大部分的工作准备了,现在仅仅需要调用精灵节点对象上的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文