- 第1章 简介
- 第2章 步骤1 – 精灵动画
- 第3章 步骤2 – 对象模型
- 第4章 步骤3 – 游戏逻辑与控制
- 第5章 步骤4 – 杂七杂八
4.4 导弹
如果想在按键之后飞船能够发射的话,我们需要用到经典的事件驱动模型。这意味着我们需要为步骤 1 中的事件监听器增加一段小小的代码来改变飞船动画。
//...
switch(e.keyCode){
case 75: //this is shoot (k)
//shoot missile here
var playerposx = parseInt($("#player").css("left"));
var playerposy = parseInt($("#player").css("top"));
var name = "playerMissle_"+Math.ceil(Math.random()*1000);
$("#playerMissileLayer").addSprite(name,{animation: missile["player"],
posx: playerposx + 90, posy: playerposy + 14, width: 20, height: 5});
$("#"+name).addClass("playerMissiles")
break;
//...
首先是读取飞船的位置信息。然后在导弹(missile)层的正确位置添加精灵。我们使用和敌人精灵同样的方法生成导弹精灵 id。还有最后一件事:把这个新创建的精灵添加统一的类名,这对之后检测碰撞来说会很方便。
对于敌人发射导弹的处理,我们需要扩展之前写的 update 回调函数。只有 有头脑
和 boss 型敌人才能发射导弹。为了了解当前敌人是否符合,我们使用 instanceof 操作符。如果操作符左边是右边的实例,就返回 true。由于 boss 型敌人继承了 有头脑
敌人,所以前者也是后者的实例。这里我们再次用到随机数生成器来处理敌人随机发射导弹事件。
//Make the enemy fire
if(this.enemy instanceof Brainy){
if(Math.random() < 0.05){
var enemyposx = parseInt($(this).css("left"));
var enemyposy = parseInt($(this).css("top"));
var name = "enemiesMissile_"+Math.ceil(Math.random()*1000);
$("#enemiesMissileLayer").addSprite(name,{animation: missile["enemies"],
posx: enemyposx, posy: enemyposy + 20, width: 15,height: 15});
$("#"+name).addClass("enemiesMissiles");
}
}
如果你把这段代码与之前的代码片段相比较,你会发现它们几乎是一模一样的。
虽然发射导弹是件简单的事,但别忘了我们还得使导弹碰到玩家后,会对其造成伤害。我们首先看看敌人导弹:这段代码位于一个回调函数当中,并且和之前检测敌人与玩家碰撞代码很相似。对于敌人发射的每个导弹,我们都需要检测它们是否与玩家碰撞。就像之前做的那样,我们调用玩家对象的对应方法来减少护盾,并且检测飞船是否该爆炸了。如果飞船被证实爆炸,我们也想之前所做的为其设置爆炸动画与回调函数。
不要忘记,导弹也和敌人一样,在跑出屏幕的时候需要被移除。
$(".enemiesMissiles").each(function(){
var posx = parseInt($(this).css("left"));
if(posx < 0){
$(this).remove();
return;
}
$(this).css("left", ""+(posx-MISSILE_SPEED)+"px");
//Test for collisions
var collided = $(this).collision(".group,#playerBody");
if(collided.length > 0){
//The player has been hit!
collided.each(function(){
if($("#player")[0].player.damage()){
explodePlayer($("#player"));
}
})
$(this).setAnimation(missile["enemiesexplode"], function(node){$(node).remove();});
$(this).removeClass("enemiesMissiles");
}
});
对于玩家导弹,其实也差不多,我们检测敌人类在碰到导弹之后是否设置了正确的动画。不过在最后,你可能会发现一些不可思议的事情:我们不仅改变了精灵的长宽,也改变了它的位置。选取合适的动画能解决精灵在屏幕跳动的异常,就像下图所示。
当然你也可以对所有精灵使用统一的大小。不过比起画图我更偏向使用代码来解决这个问题:)
//Update the movement of the missiles
$(".playerMissiles").each(function(){
var posx = parseInt($(this).css("left"));
if(posx > PLAYGROUND_WIDTH){
$(this).remove();
return;
}
$(this).css("left", ""+(posx+MISSILE_SPEED)+"px");
//Test for collisions
var collided = $(this).collision(".group,.enemy");
if(collided.length > 0){
//An enemy has been hit!
collided.each(function(){
if($(this)[0].enemy.damage()){
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");
}
})
$(this).setAnimation(missile["playerexplode"], function(node){$(node).remove();});
$(this).css("width", 38);
$(this).css("height", 23);
$(this).css("top", parseInt($(this).css("top"))-7);
$(this).removeClass("playerMissiles");
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论