- 第1章 简介
- 第2章 步骤1 – 精灵动画
- 第3章 步骤2 – 对象模型
- 第4章 步骤3 – 游戏逻辑与控制
- 第5章 步骤4 – 杂七杂八
3.4 敌人对象
存在 3 中类型的敌人,它们具有共同的祖先。我们在祖先类中定义敌人的默认共同行为,在继承类中定义特殊方法。因为我想在之后调用方法的时候不必考虑对象到底是哪个类的实例,所以我们在子类中只重写那些已经存在的方法。就像玩家类一样,敌人类也需要管理 损伤
的方法。你应该会注意到,其实这个方法和玩家类的一模一样,除了检测无敌(grace)模式之外。
function Enemy(node){
this.shield = 2;
this.speedx = -5;
this.speedy = 0;
this.node = $(node);
// deals with damage endured by an enemy
this.damage = function(){
this.shield--;
if(this.shield == 0){
return true;
}
return false;
};
//...
敌人具有某些符合基本逻辑的自动行为。我们需要一些飞来使敌人移动。这里我们有一个叫 update() 的方法,它会调用在每个方向轴上移动的函数。这使子类可以轻松重写其中任何一个。你可以发现敌人的默认行为是在每个方向轴上以一定的速度移动。如果你仔细看 updateX 和 updateY 方法的话,你会发现其实背景的移动也采用了同样的方式。
下图是敌人的家族树(family tree)。我们使用继承的目标是减少代码冗余。所以如果;两个对象拥有同一行为,我们让它们从另一对象继承。
3.4.1 导弹
导弹与默认祖先敌人的差别并不大,导弹是想在屏幕中尽量停留而已。所以代码相当直观:
function Minion(node){
this.node = $(node);
}
Minion.prototype = new Enemy();
Minion.prototype.updateY = function(playerNode){
var pos = parseInt(this.node.css("top"));
if(pos > (PLAYGROUND_HEIGHT - 50)){
this.node.css("top",""+(pos - 2)+"px");
}
}
3.4.2 有头脑的敌人
对于有头脑的敌人,我们需要给它们配置更多护盾,我们只需在构造器中重新定义这个值即可。定义在子类中的同名值会重写父类,在构造器中定义的值则重写子类和父类。这种类型的敌人稍具智能,它们尝试躲避玩家。为了实现这个我们重写 updateY 方法,使得垂直速度增加,或者远离玩家的相对位置。这里也没有任何新的东西。注意 有头脑的敌人
类可不是继承至导弹(Minion)类而是敌人(Enemy)类。
function Brainy(node){
this.node = $(node);
this.shield = 5;
this.speedy = 1;
this.alignmentOffset = 5;
}
Brainy.prototype = new Enemy();
Brainy.prototype.updateY = function(playerNode){
if((this.node[0].gameQuery.posy+this.alignmentOffset) > $(playerNode)[0].gameQuery.posy){
var newpos = parseInt(this.node.css("top"))-this.speedy;
this.node.css("top",""+newpos+"px");
} else if((this.node[0].gameQuery.posy+this.alignmentOffset) < $(playerNode)[0].gameQuery.posy){
var newpos = parseInt(this.node.css("top"))+this.speedy;
this.node.css("top",""+newpos+"px");
}
}
3.4.3 boss 型敌人
boss 型敌人的行为与同有头脑的敌人一样,它们躲避玩家。不同的是:它们不会朝玩家前进,而是垂直移动,玩家得花些时间才能杀死它们(因为它们的护盾很厚)。
function Bossy(node){
this.node = $(node);
this.shield = 20;
this.speedx = -1;
this.alignmentOffset = 35;
}
Bossy.prototype = new Brainy();
Bossy.prototype.updateX = function(){
var pos = parseInt(this.node.css("left"));
if(pos > (PLAYGROUND_WIDTH - 200)){
this.node.css("left",""+(pos+this.speedx)+"px");
}
}
敌人的生成、破坏和发射导弹并不需要在对象中设定,请看下一步骤。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论