我用JavaScript写了个飞机大战小游戏

556 阅读1分钟

飞机大战效果图:

飞机大战试玩连接:

shunyue1320.github.io/fjdz (推荐谷歌浏览器打开)

飞机大战源码链接:

github.com/shunyue1320…

做游戏就要有素材的啦 ,以下是在爱给网找到的素材:

在这里插入图片描述

首先3个页面的打开我们用div来做,通过更改div的隐藏属性display: none;与显示display: block来达到页面切换的效果:

<body>
  <div id="home">
    <div id="one" style="display: none;">
      <!--<div class="haemal"><p></p></div>
      <div class="score">0</div>-->
    </div>
    <div id="tow">
      <div class="plane" >
        <ul>
          <li></li>
          <li></li>
          <li></li>
          <li></li>
        </ul>
      </div>
      <div class="list">
        <ul>
          <li>沙丘大战</li>
          <li>黑夜突袭</li>
          <li>火焰山战</li>
          <li>天空之城</li>
          <li>丘陵战争</li>
        </ul>
      </div>
    </div>
    <div id="three" style="display: none;">
        <h1>得分</h1>
        <h1 id="newscore">0</h1>
        <div id="quit">确定</div>
    </div>
  </div>

  <script src="js/main.js"></script>
</body>

就这么短短的几行样式代码足够啦!

设置完css样式后我们就可以开始js代码的编写。

首先我们创建好各个文件,存储相应的材料及代码

var one = document.getElementById('one'),
haemal = one.querySelector("p"),
score = one.getElementsByClassName("score")[0],
tow = document.getElementById('tow'),
three = document.getElementById('three'),
air = tow.querySelectorAll(".plane li"),
start = tow.querySelectorAll(".list li"),
Air = 0,	//代表哪架飞机
plane = 0,	//第几形态
index;
var arrPlane = [['img/my1.png','img/my11.png','img/my111.png'],['img/my2.png','img/my22.png','img/my222.png'],['img/my3.png','img/my33.png','img/my333.png'],['img/my4.png','img/my44.png','img/my444.png']],
    arrBullet = [['img/pd1.png','img/pd11.png','img/pd111.png'],['img/pd2.png','img/pd22.png','img/pd222.png'],['img/pd3.png','img/pd33.png','img/pd333.png'],['img/pd4.png','img/pd44.png','img/pd444.png']];
for (let i=0; i<air.length; i++) {
    air[i].onclick = function(){
        Air = i;
    }
}
for (let i=0; i<start.length; i++) {
    index = i
    start[i].onclick = function(){
        startGame(Air,i);
    }
}

startGame(Air,i)游戏开始函数传递2个参数,Air代表选则的飞机,i代表选则的关卡,接下来我们将写游戏开始函数

//开始游戏
function startGame(Air,index){
	one.innerHTML = "";	//清空初始页面
	plane = 0;
	var haemal = document.createElement("div");
	haemal.className = "haemal";
	var score = document.createElement("div");
	score.className = "score";
	var p = document.createElement("p");
	haemal.appendChild(p)
	one.appendChild(haemal);
	one.appendChild(score);
 	tow.style.display = 'none';
 	one.style.display = 'block';
 	one.style.backgroundImage = ['url(img/context1.jpg)','url(img/context2.jpg)','url(img/context3.jpg)','url(img/context4.jpg)','url(img/context5.jpg)'][index];

通过document.createElement("div"),我们可以在页面上创建相应的标签,图片,可以用来实现生成飞机,通过定时器setInterval我们可以实现,背景的移动效果,从而感觉飞机在移动!

audio()函数为实现背景音乐的生成我们来看看该函数里面有啥

//声音效果
function audio(n){
  var music = ["audio/bgm.mp3","audio/boom.mp3","audio/bullet.mp3"],
      dio = document.createElement("audio");
  if(n != 1){
      dio.className = "dio"
  }
  dio.src = music[n];
  dio.autoplay = "autoplay";
  dio.loop = "loop";
  one.appendChild(dio);
  if (n==1) {
      setTimeout(function(){
          one.removeChild(dio);
      },800)
  }
}

可见参数n是用与播放哪一个背景音乐而设计的,本游戏一共用了3个背景音乐,分别是 爆炸音效,发射子弹音效, 背景音乐。

如何实现生成我方飞机呢,接下来我们来看看:

function myAir(Air){
  var myAirPlane = document.createElement("img");
  var speed = 4;	//速度
  myAirPlane.className = "myplane";
  myAirPlane.src = arrPlane[Air][plane];
  myAirPlane.width = 70;
  myAirPlane.height = 50;
  myAirPlane.style.bottom = 5 + 'px';
  myAirPlane.style.left = home.clientWidth/2 - myAirPlane.width/2 + 'px';
  one.appendChild(myAirPlane);
  //键盘移动事件
  document.onkeydown = function (e) {
      e = e || window.event;
      switch (e.keyCode){
          case 37:
          case 65:
              myAirPlane.style.left = Math.max(0,myAirPlane.offsetLeft-5) +'px';
              break;
          case 39:
          case 68:
              myAirPlane.style.left = Math.min(home.clientWidth - myAirPlane.width,myAirPlane.offsetLeft+5) +'px';
              break;
          default:break;
      }
  }
  //触摸移动事件
  one.ontouchstart = function(e){
      if(e.touches[0].screenX < home.clientWidth/2){
          myAirPlane.style.left = Math.max(0,myAirPlane.offsetLeft-5) +'px';
      }else{
          myAirPlane.style.left = Math.min(home.clientWidth - myAirPlane.width,myAirPlane.offsetLeft+5) +'px';
      }
  }

让我们来生成子弹吧

//生成子弹
one.bulletTimer = setInterval(function(){
    var myAirBullet = document.createElement("img");
    myAirBullet.className = "myAirBullet";
    myAirBullet.src = arrBullet[Air][plane];
    myAirBullet.width = 10*(1+plane);
    myAirBullet.height = 20*(1+plane);
    myAirBullet.style.top = myAirPlane.offsetTop - myAirBullet.height + 'px';
    myAirBullet.style.left = myAirPlane.offsetLeft + myAirPlane.clientWidth/2 - myAirBullet.width/2 + 'px';
    one.appendChild(myAirBullet);
    //子弹发射
    bulletEmit();
    function bulletEmit(){
        let top = myAirBullet.offsetTop -speed;
        myAirBullet.style.top = top + 'px';
        if(top <= 0){
            //cancelAnimationFrame(motion);//清除运动函数
            one.removeChild(myAirBullet);//清除
            return false;
        }else{
            myAirPlane.parentNode && (myAirBullet.timer = requestAnimationFrame(bulletEmit));
        }
    }
},400);

设置完我方飞机我们就开始制作 生成敌军 啦,这个故事是一个漫长的事情,让我们来简单分析一下:

1.生成敌军,也就是通过创建img标签实现 位置Math.random()实现

2.敌军下落,通过改变img标签的top值可以实现哦

3.敌军与我方子弹碰撞 敌军消失 子弹消失 生成爆炸效果img标签

4.生成我军补给 子弹击中升级我军的 形态 与 子弹形态

4.敌军撞到我方飞机 关闭所有运动函数 背景声音 游戏结束 弹出得分

下面是碰撞判断

//敌军与子弹碰撞
for(let i=0; i<aBiu.length; i++){
    if(isCollision(aBiu[i],enemyPlane)){
        scoreis++;
        score.innerHTML = scoreis;
        Boom(enemyPlane);	//爆炸效果
        audio(1)	//声音效果
        cancelAnimationFrame(aBiu[i].timer);//清除子弹运动函数
        one.removeChild(enemyPlane);//清除飞机
        one.removeChild(aBiu[i]);//清除子弹
        return false;
    }
}
//敌军与我军碰撞 游戏结束
if(myPlane.parentNode && isCollision(myPlane,enemyPlane)){	//判断我方飞机是否存在 && 是否碰撞
    let dio = one.getElementsByClassName("dio");
    var pp = one.querySelector("p");
    pp.style.width = 0 +"px";
    one.removeChild(dio[0]);
    one.removeChild(dio[0]);
    Boom(enemyPlane);	//敌军爆炸效果
    Boom(myPlane);	//我军爆炸效果
    audio(1);
    clearInterval(one.enemyTimer);	//停止生成敌军
    clearInterval(one.bulletTimer);	//停止生成子弹
    clearInterval(one.backgroundMove);//背景停止
    clearInterval(one.supplyTimer);//补给生成停止
    one.removeChild(myPlane);
    one.removeChild(enemyPlane);
    document.onkeydown = null;	//清除移动事件
    one.ontouchstart = null;
    newscore.innerHTML = scoreis;
    three.style.display = "block";
    return false;
}

接下来我们来了解以下碰撞判断函数: isCollision()

//碰撞过程
function isCollision(obj,enemy){	//obj:我军或子弹 	 enemy:敌军
  var t1 = obj.offsetTop,
      b1 = obj.offsetTop + obj.height,
      l1 = obj.offsetLeft,
      r1 = obj.offsetLeft + obj.width;

  var t2 = enemy.offsetTop,
      b2 = enemy.offsetTop + enemy.height,
      l2 = enemy.offsetLeft,
      r2 = enemy.offsetLeft + enemy.width;

  return !(t1 > b2 || l1 > r2 || b1 < t2 || r1 < l2);
}

通过一个矩形体左边距离是否大于另一个矩形右边距离的方法来监测是否没有碰撞: return false(没有碰撞) / true(碰撞) 这是比较重要的一步哦!