前端复刻经典小游戏之飞机大战(三)

简介: 前端复刻经典小游戏之飞机大战(三)

@[toc]飞机大战

飞机大战小游戏相关说明

需求说明

  • 己方飞机与敌方飞机
  • 己方发射子弹,摧毁敌方飞机
  • 击毁一辆敌方飞机得分
  • 己方飞机碰撞敌方飞机游戏结束统计分数

功能说明

主要功能
  • 鼠标移动己方飞机
  • 己方飞机发射子弹
  • 敌方飞机随机生成,运动方向由上到下
  • 模式难度选择:敌机的数量、敌机的移动速度等
次要功能
  • 敌方不同类型飞机
  • 己方不同类型飞机

技术说明

掌握基本的前端技术,熟练使用CSS、JS代码,完成游戏的布局与动态交互作用

所用的Javascript技术介绍

1、setInterval() 是 JavaScript 中的一个内置函数,它用于在指定的间隔时间内重复执行一段代码,实现周期性操作。

2、Math.random()随机数生成

3、innerHTML 是一个用于读取或设置 HTML 元素内容的属性。通过 innerHTML 属性,可以获取或修改指定元素的 HTML 内容。

4、removeChild() 方法从子节点列表中删除某个节点。如删除成功,此方法可返回被删除的节点,如失败,则返回 NULL。

5、parentNode属性,首先需要获取到一个节点对象。可以通过getElementById、getElementsByTagName等方法获取到指定的节点对象。然后,就可以使用parentNode属性来获取该节点的父节点。

6、onmousemove 监听鼠标移动事件

飞机爆炸状态与物体碰撞检测(敌机与子弹,我机与敌机碰撞)

//爆炸函数
function boom(l,t,w,h,i){
  var oBoom = new Image();
//  oBoom.src = "img/"+["boom_small","plane_0","boom_big"][i]+".png";
  oBoom.src = "img/boom.png"
  oBoom.className ="boom";
  oBoom.width = w;
  oBoom.height = h;
  oBoom.style.left = l + "px";
  oBoom.style.top = t + 'px';
  oMap.appendChild(oBoom);
  setTimeout(function(){
    oBoom.parentNode && oMap.removeChild(oBoom);
  },[1200,2500,1200][i]);
}
//两个物体 碰撞检测
function coll( obj1 , obj2 ){
  var T1 = obj1.offsetTop,
    B1 = T1+obj1.clientHeight,
    L1 = obj1.offsetLeft,
    R1 = L1+obj1.clientWidth;
  var T2 = obj2.offsetTop,
    B2 = T2+obj2.clientHeight,
    L2 = obj2.offsetLeft,
    R2 = L2+obj2.clientWidth;
  return !( B1 < T2 || R1 < L2 || T1 > B2 || L1 > R2 );
}

敌方飞机生成

function enemy(level , oPlane) {
  var w = oMap.clientWidth,
    h = oMap.clientHeight;
  var speed = [5,6,7,8][level]; //根据不同模式确认敌军下落速度
  
  var num = 1;
  oBox.enemyIntetval = setInterval(function () {
    var index = num%30?1:0;
        var tu = Math.floor(Math.random() * 4);//0-3个随机数
    
    //生成敌军
    var oEnemy = new Image();
    oEnemy.tu = tu;
    oEnemy.index = index;
    oEnemy.HP = [1,1,1,10][tu];
    oEnemy.speed = speed + (Math.random()*0.6 - 0.3)*speed;
    oEnemy.speed *= index?1:0.5;
    oEnemy.src = "img/enemy_"+["1","2","3","boss"][tu]+".png";
    oEnemy.className = "enemy";
    oEnemy.width = [54,54,54,104][tu];
    oEnemy.height = [40,40,40,80][tu];
    oEnemy.style.left = Math.random()*w - oEnemy.width/2 + 'px';
    oEnemy.style.top = -oEnemy.height + 'px';
    oMap.appendChild(oEnemy);
    num ++;

敌方飞机运动轨迹设定(敌机安全下落分数减少)及与子弹的碰撞与移除(分数增加,敌方飞机爆炸与移除)

//敌军运动
  function m(){
  if ( oEnemy.parentNode ){
  var top = oEnemy.offsetTop;
  top += oEnemy.speed;
    if ( top >= h ){
      oBox.score --; //漏掉飞机减分
      oScore.innerHTML = oBox.score;
      oMap.removeChild(oEnemy);
    }else{
      oEnemy.style.top = top + 'px';
      //子弹碰撞检测
      for (var i = allBiu.length - 1 ; i >= 0; i--) {
        var objBiu = allBiu[i];
        if ( coll(oEnemy , objBiu) ){
          oBiuAll.removeChild(objBiu);//移除子弹
          oEnemy.HP --;
          if ( !oEnemy.HP ){
            oBox.score += oEnemy.index?2:20; //打掉敌方飞机加分
            oScore.innerHTML = oBox.score;
          boom(oEnemy.offsetLeft,oEnemy.offsetTop,oEnemy.width,oEnemy.height,index?0:2);//敌军爆炸图
          oMap.removeChild(oEnemy);//移除敌军
          return;
      }
      }
    }
    requestAnimationFrame(m);
  },[350,150,120,40][level]);
  }

运行截图:

游戏结束与分数结算、游戏重新开始

游戏结束:即敌机与我机碰撞(其实还可以使敌机发射子弹,子弹碰撞我机减血,血量为零)游戏结束:

一、我机与敌机碰撞我机与所碰撞敌机一同销毁

//我军碰撞检测
if ( oPlane.parentNode && coll(oEnemy,oPlane) ){
  boom(oEnemy.offsetLeft,oEnemy.offsetTop,oEnemy.width,oEnemy.height,index?0:2);//敌军爆炸图
  boom(oPlane.offsetLeft,oPlane.offsetTop,oPlane.width,oPlane.height,1);//我军爆炸图
  oMap.removeChild(oEnemy);//移除敌军
  oMap.removeChild(oPlane);//移除我军
  GameOver();
  return;
}

敌机与我机碰撞运行截图:

二、游戏结束与分数结算

//游戏结束
function GameOver(){
  document.onmousemove = null; //清除移动事件
  clearInterval(oBox.biuInterval);//不再产生新子弹
  clearInterval(oBox.enemyIntetval);//不再产生新敌军
  restart();
}
//结算+重新开始
function restart(){
  oScore.style.display = "none";
  var s = oBox.score;
  var honor;
  if ( s < -300 ){
    honor = "青铜";
  }else if ( s < 10 ){
    honor = "白银";
  }else if ( s < 30 ){
    honor = "黄金";
  }else if ( s < 100 ){
    honor = "钻石";
  }else if ( s < 200 ){
    honor = "星耀";
  }else if ( s < 500 ){
    honor = "初级大师";
  }else if ( s < 1000 ){
    honor = "中级大师";
  }else if ( s < 5000 ){
    honor = "高极大师";
  }else{
    honor = "孤独求败!!!";
  }
  oRe.style.display = "block";
  allReChild[0].children[0].innerHTML = s;
  allReChild[1].children[0].innerHTML = honor; 
}   

总结

BUG:

敌方飞机卡在上面没有下来。

原因:打注释的时候不小心把功能介绍的注释给删了。注释回来就好了。

总体构思很重要,本篇笔者参考了多份飞机大战小游戏,导致了自己的思路混乱,然后函数方法具有跳跃性,前期还是要先构思好,对各个功能的实现做详细的思考,使代码不要高耦合。

目录
相关文章
|
1月前
|
前端开发 JavaScript
前端复刻经典小游戏之飞机大战(一)
前端复刻经典小游戏之飞机大战(一)
31 1
|
1月前
|
前端开发 JavaScript 测试技术
前端复刻经典小游戏之飞机大战(二)
前端复刻经典小游戏之飞机大战(二)
50 0
|
移动开发 前端开发 Android开发
第22/90步《前端篇》第4章 编写一个简单的HTML5小游戏:移植及优化 第13课
今天学习《前端篇》第4章移植及优化的第13课,移植文本与图像。
107 0
|
移动开发 前端开发 JavaScript
第21/90步《前端篇》第4章 编写一个简单的HTML5小游戏:移植及优化 第12课
今天学习《前端篇》第4章移植及优化的第12课,移植音频和事件。
105 0
|
移动开发 前端开发 开发者
第20/90步《前端篇》第4章 编写一个简单的HTML5小游戏:移植及优化 第11课
今天学习《前端篇》第4章移植及优化的第11课,处理移植准备工作。
129 0
|
移动开发 前端开发 JavaScript
第19/90步《前端篇》第3章 编写一个简单的HTML5小游戏:完成交互功能 第10课
今天学习《前端篇》第3章完成交互功能的第10课,控制游戏音效,添加单击音效和背景音乐。
63 0
|
移动开发 前端开发 HTML5
第18/90步《前端篇》第3章 编写一个简单的HTML5小游戏:完成交互功能 第9课
今天学习《前端篇》第3章完成交互功能的第9课,实现游戏的重启功能。
53 0
|
移动开发 前端开发 JavaScript
第17/90步《前端篇》第3章 编写一个简单的HTML5小游戏:完成交互功能 第8课
今天学习《前端篇》第3章完成交互功能的第8课,监听用户事件,让挡板动起来。
58 0
|
18天前
|
前端开发 JavaScript 数据库
如何实现前后端分离-----前端笔记
如何实现前后端分离-----前端笔记
|
18天前
|
前端开发 安全 NoSQL
技术笔记:Security前端页面配置
技术笔记:Security前端页面配置