JS小游戏之宇宙战机源码详解


Posted in Javascript onSeptember 25, 2014

本文实例讲述了JS小游戏的宇宙战机源码,分享给大家供大家参考。具体介绍如下:

一、游戏介绍:

这是一款飞行射击游戏,纵向,共六关。

二、游戏需求:

1.战机可发射子弹,子弹可通过获取道具升级。
2.战机可放bomb,可获取道具增加数量。
3.战机可蓄力攻击。
4.道具有三种,分别是升级子弹,增加bomb数量,增加战机数量。
5.每关音乐不同。
6.战机被击落后再进入战场,有保护状态。
7.敌机AI设计。

游戏运行如下图所示:

JS小游戏之宇宙战机源码详解

JS小游戏之宇宙战机源码详解

完整实例代码点击此处本站下载。

三、Javascript源码部分:

/** 宇宙战机
*  Author: fdipzone
*  Date:  2013-02-12
*  Ver:  1.0
*/
window.onload = function(){
  var gameimg = [
    'images/fighter.png', 
    'images/fighter_p.png', 
    'images/fighter_s.png',
    'images/fighter_sp.png', 
    'images/shot.png', 
    'images/destroy.png', 
    'images/destroy_boss.png',
    'images/enemy.png', 
    'images/bullet.png', 
    'images/gift.png', 
    'images/bomb.png', 
    'images/boss1.png'];

  var callback = function(){
    var gameplane = $('gameplane');
    fighter.init();
    fighter.bgmove(gameplane);
  }
  img_preload(gameimg, callback);
};


/** fighter class */
var fighter = (function(){
  
  var hiscore = 10000;          // 最高分
  var score = 0;             // 当前分
  var fighternum = 3;           // 战机数量
  var bombnum = 3;            // 炸弹数量
  var ft = null;             // 战机对象
  var is_start = 0;            // 是否已开始游戏
  var is_bombing = 0;           // 是否爆炸中
  var is_lock = 1;            // 是否锁定
  var is_over = 0;            // 是否已结束
  var is_clear = 0;            // 清屏
  var is_pile = 0;            // 是否已达成蓄力
  var is_protect = 0;           // 是否保护状态
  var pilenum = 0;            // 已蓄力数量
  var ackey = {};             // 记录键是否按下
  var keypriority = {};          // 冲突键优先级
  var gamekey = [37,38,39,40,83,65];   // 游戏的按键
  var scoretag = [0,20,30,40,50,60,500]; // 不同敌机的分数
  var level = 1;             // 关数  
  var power = 1;             // 战机子弹威力
  var cheatcode = [];           // 记录cheat输入
  var failtimes = 0;           // 挑战失败次数
  
  // boss 数据
  var bossdata = [
          {'armor':500, 'left':136, 'top':-169, 'step':30},
          {'armor':1000, 'left':136, 'top':-169, 'step':30},
          {'armor':1500, 'left':136, 'top':-169, 'step':30},
          {'armor':2000, 'left':136, 'top':-169, 'step':30},
          {'armor':2500, 'left':136, 'top':-169, 'step':30},
          {'armor':3000, 'left':136, 'top':-169, 'step':30},
          ];

  // 出现的敌机
  var enemydata = [];

  // 当前出现的boss
  var curboss = null;
  
  // 关卡数据
  var map = [
    // level 1
    {
      'ms50':[[3, 680, 1, -50, 10, 10],[3, 680, 1, -50, 290, 10]], 
      'ms2500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms3500':[[1, 10, 12, -23, 190, 10]],
      'ms5500':[[3, 800, 2, 100, -50, 10]],
      'ms7500':[[3, 800, 2, 200, 450, -10]],
      'ms8000':[[1, 10, 11, -23, 100, 10]],
      'ms9500':[[3, 800, 2, 100, -50, 10]],
      'ms11500':[[3, 800, 2, 200, 450, -10]],
      'ms13500':[[3, 800, 2, 100, -50, 10]],
      'ms15500':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms20000':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms25000':[[1, 10, 4, 150, -50, 10],[1, 10, 4, 250, 400, -10],[1, 10, 4, 100, 400, -10]],
      'ms30000':[[3, 800, 5, 692, 90, -10],[3, 800, 5, 692, 280, -10]],
      'ms35000':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms38000':[[1, 10, 11, -23, 10, 10]],
      'ms40000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms42500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms45500':[[3, 800, 2, 50, -50, 10]],
      'ms47500':[[3, 800, 2, 150, 450, -10]],
      'ms49500':[[3, 800, 2, 50, -50, 10]],
      'ms51500':[[3, 800, 2, 150, 450, -10]],
      'ms55500':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms60000':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms65000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms68000':[[3, 800, 5, 692, 110, -10],[3, 800, 5, 692, 260, -10]],
      'ms71000':[[1, 10, 13, -23, 220, 10]],
      'ms76000':[]
    },
    // level 2
    {
      'ms50':[[3, 680, 1, -50, 10, 10],[3, 680, 1, -50, 290, 10]], 
      'ms2500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms3500':[[1, 10, 12, -23, 190, 10]],
      'ms5500':[[3, 800, 2, 100, -50, 10]],
      'ms7500':[[3, 800, 2, 200, 450, -10]],
      'ms8000':[[1, 10, 11, -23, 100, 10]],
      'ms9500':[[3, 800, 2, 100, -50, 10]],
      'ms11500':[[3, 800, 2, 200, 450, -10]],
      'ms13500':[[3, 800, 2, 100, -50, 10]],
      'ms15500':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms20000':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms25000':[[1, 10, 4, 150, -50, 10],[1, 10, 4, 250, 400, -10],[1, 10, 4, 100, 400, -10]],
      'ms30000':[[3, 800, 5, 692, 90, -10],[3, 800, 5, 692, 280, -10]],
      'ms35000':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms38000':[[1, 10, 11, -23, 10, 10]],
      'ms40000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms42500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms45500':[[3, 800, 2, 50, -50, 10]],
      'ms47500':[[3, 800, 2, 150, 450, -10]],
      'ms49500':[[3, 800, 2, 50, -50, 10]],
      'ms51500':[[3, 800, 2, 150, 450, -10]],
      'ms55500':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms60000':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms65000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms68000':[[3, 800, 5, 692, 110, -10],[3, 800, 5, 692, 260, -10]],
      'ms71000':[[1, 10, 13, -23, 220, 10]],
      'ms76000':[]
    },
    // level 3
    {
      'ms50':[[3, 680, 1, -50, 10, 10],[3, 680, 1, -50, 290, 10]], 
      'ms2500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms3500':[[1, 10, 12, -23, 190, 10]],
      'ms5500':[[3, 800, 2, 100, -50, 10]],
      'ms7500':[[3, 800, 2, 200, 450, -10]],
      'ms8000':[[1, 10, 11, -23, 100, 10]],
      'ms9500':[[3, 800, 2, 100, -50, 10]],
      'ms11500':[[3, 800, 2, 200, 450, -10]],
      'ms13500':[[3, 800, 2, 100, -50, 10]],
      'ms15500':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms20000':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms25000':[[1, 10, 4, 150, -50, 10],[1, 10, 4, 250, 400, -10],[1, 10, 4, 100, 400, -10]],
      'ms30000':[[3, 800, 5, 692, 90, -10],[3, 800, 5, 692, 280, -10]],
      'ms35000':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms38000':[[1, 10, 11, -23, 10, 10]],
      'ms40000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms42500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms45500':[[3, 800, 2, 50, -50, 10]],
      'ms47500':[[3, 800, 2, 150, 450, -10]],
      'ms49500':[[3, 800, 2, 50, -50, 10]],
      'ms51500':[[3, 800, 2, 150, 450, -10]],
      'ms55500':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms60000':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms65000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms68000':[[3, 800, 5, 692, 110, -10],[3, 800, 5, 692, 260, -10]],
      'ms71000':[[1, 10, 13, -23, 220, 10]],
      'ms76000':[]
    },
    // level 4
    {
      'ms50':[[3, 680, 1, -50, 10, 10],[3, 680, 1, -50, 290, 10]], 
      'ms2500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms3500':[[1, 10, 12, -23, 190, 10]],
      'ms5500':[[3, 800, 2, 100, -50, 10]],
      'ms7500':[[3, 800, 2, 200, 450, -10]],
      'ms8000':[[1, 10, 11, -23, 100, 10]],
      'ms9500':[[3, 800, 2, 100, -50, 10]],
      'ms11500':[[3, 800, 2, 200, 450, -10]],
      'ms13500':[[3, 800, 2, 100, -50, 10]],
      'ms15500':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms20000':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms25000':[[1, 10, 4, 150, -50, 10],[1, 10, 4, 250, 400, -10],[1, 10, 4, 100, 400, -10]],
      'ms30000':[[3, 800, 5, 692, 90, -10],[3, 800, 5, 692, 280, -10]],
      'ms35000':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms38000':[[1, 10, 11, -23, 10, 10]],
      'ms40000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms42500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms45500':[[3, 800, 2, 50, -50, 10]],
      'ms47500':[[3, 800, 2, 150, 450, -10]],
      'ms49500':[[3, 800, 2, 50, -50, 10]],
      'ms51500':[[3, 800, 2, 150, 450, -10]],
      'ms55500':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms60000':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms65000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms68000':[[3, 800, 5, 692, 110, -10],[3, 800, 5, 692, 260, -10]],
      'ms71000':[[1, 10, 13, -23, 220, 10]],
      'ms76000':[]
    },
    // level 5
    {
      'ms50':[[3, 680, 1, -50, 10, 10],[3, 680, 1, -50, 290, 10]], 
      'ms2500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms3500':[[1, 10, 12, -23, 190, 10]],
      'ms5500':[[3, 800, 2, 100, -50, 10]],
      'ms7500':[[3, 800, 2, 200, 450, -10]],
      'ms8000':[[1, 10, 11, -23, 100, 10]],
      'ms9500':[[3, 800, 2, 100, -50, 10]],
      'ms11500':[[3, 800, 2, 200, 450, -10]],
      'ms13500':[[3, 800, 2, 100, -50, 10]],
      'ms15500':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms20000':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms25000':[[1, 10, 4, 150, -50, 10],[1, 10, 4, 250, 400, -10],[1, 10, 4, 100, 400, -10]],
      'ms30000':[[3, 800, 5, 692, 90, -10],[3, 800, 5, 692, 280, -10]],
      'ms35000':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms38000':[[1, 10, 11, -23, 10, 10]],
      'ms40000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms42500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms45500':[[3, 800, 2, 50, -50, 10]],
      'ms47500':[[3, 800, 2, 150, 450, -10]],
      'ms49500':[[3, 800, 2, 50, -50, 10]],
      'ms51500':[[3, 800, 2, 150, 450, -10]],
      'ms55500':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms60000':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms65000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms68000':[[3, 800, 5, 692, 110, -10],[3, 800, 5, 692, 260, -10]],
      'ms71000':[[1, 10, 13, -23, 220, 10]],
      'ms76000':[]
    },
    // level 6
    {
      'ms50':[[3, 680, 1, -50, 10, 10],[3, 680, 1, -50, 290, 10]], 
      'ms2500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms3500':[[1, 10, 12, -23, 190, 10]],
      'ms5500':[[3, 800, 2, 100, -50, 10]],
      'ms7500':[[3, 800, 2, 200, 450, -10]],
      'ms8000':[[1, 10, 11, -23, 100, 10]],
      'ms9500':[[3, 800, 2, 100, -50, 10]],
      'ms11500':[[3, 800, 2, 200, 450, -10]],
      'ms13500':[[3, 800, 2, 100, -50, 10]],
      'ms15500':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms20000':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms25000':[[1, 10, 4, 150, -50, 10],[1, 10, 4, 250, 400, -10],[1, 10, 4, 100, 400, -10]],
      'ms30000':[[3, 800, 5, 692, 90, -10],[3, 800, 5, 692, 280, -10]],
      'ms35000':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms38000':[[1, 10, 11, -23, 10, 10]],
      'ms40000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms42500':[[3, 680, 1, -50, 70, 10],[3, 680, 1, -50, 220, 10]],
      'ms45500':[[3, 800, 2, 50, -50, 10]],
      'ms47500':[[3, 800, 2, 150, 450, -10]],
      'ms49500':[[3, 800, 2, 50, -50, 10]],
      'ms51500':[[3, 800, 2, 150, 450, -10]],
      'ms55500':[[3, 800, 3, -50, 90, 10],[3, 800, 3, -50, 280, 10]],
      'ms60000':[[3, 800, 3, -50, 30, 10],[3, 800, 3, -50, 340, 10]],
      'ms65000':[[1, 10, 4, 100, 400, -10],[1, 10, 4, 300, -50, 10]],
      'ms68000':[[3, 800, 5, 692, 110, -10],[3, 800, 5, 692, 260, -10]],
      'ms71000':[[1, 10, 13, -23, 220, 10]],
      'ms76000':[]
    }
  ];


  // 初始化
  init = function(){
    ft = $('fighter');
    reset();
    key_event();
  }


  // 开始游戏
  start = function(){
    is_clear = 0;
    is_protect = 0;
    disp(ft.id, 'show');
    reset_fighter();
    reset_pile();
    process();
    bgsound(level, true);
    bgchange(level);
    fighter_init();
  }


  // 设置事件
  key_event = function(){

    document.onkeydown = function(e){
      var e = e || window.event;
      var curkey = e.keyCode || e.which || e.charCode;

      if(is_start==0){ 
        if(cheatcode.length>12){
          cheatcode.shift();
        }
        cheatcode.push(curkey); // 记录用户输入的cheatcode
      }
      
      if(is_start==1 && in_array(curkey,gamekey)){
        if(ackey[curkey.toString()]==0 || typeof(ackey[curkey.toString()])=='undefined' || !in_array(curkey,[83,65])){  // 射击与炸弹连按屏蔽
          ackey[curkey.toString()] = 1;  // save key down
          switch(curkey){
            case 37:
            case 39:
              keypriority.left = curkey;  // left right
              break;
            case 38:
            case 40:
              keypriority.top = curkey;  // up down
              break;
          }
        }else{
          return false;
        }
      }
      
      if(curkey==13 || is_start==1 && is_lock==0){  // game is start or key=13
        switch(curkey){
          case 13: // enter
            if(is_start==0){
              is_start=1;
              disp('op', 'hide');
              msg_show();
              setTimeout(function(){
                msg_hide();
                cheat();
                start();
              }, 1500);
            }
            break;

          case 83: // 射击
            shot();
            break;

          case 65: // 炸弹
            bomb();
            break;
        }
      }
    }

    document.onkeyup = function(e){
      var e = e || window.event;
      var curkey = e.keyCode || e.which || e.charCode;
      if(is_start==1 && in_array(curkey,gamekey)){
        ackey[curkey.toString()] = 0;  // release key down
        
        if(curkey==83){// 释放蓄力攻击
          if(is_pile==1){
            pile_shot();
          }
          reset_pile();
        }
      }
    }

  }


  // 循环执行的动作
  action = function(){
    var movestep = 5;  // 移动步长
    var et = setInterval(function(){
      if(is_start==0 || is_lock==1){
        clearInterval(et);
      }
      
      // 移动
      if(ackey['37']==1 && (ackey['39']==0 || keypriority.left==37)){  // 冲突时判断优先级
        if(getPosition(ft,'left')<movestep){
          setPosition(ft, 'left', 0);  // left
        }else{
          setPosition(ft, 'left', getPosition(ft,'left') - movestep);
        }
      }
      if(ackey['38']==1 && (ackey['40']==0 || keypriority.top==38)){
        if(getPosition(ft, 'top')<movestep){
          setPosition(ft, 'top', 0);  // top
        }else{
          setPosition(ft, 'top', getPosition(ft,'top') - movestep);
        }
      }
      if(ackey['39']==1 && (ackey['37']==0 || keypriority.left==39)){
        if(400-(getPosition(ft,'left')+50)<movestep){
          setPosition(ft, 'left', 350);  //width-fighter.width
        }else{
          setPosition(ft, 'left', getPosition(ft,'left') + movestep);
        }
      }
      if(ackey['40']==1 && (ackey['38']==0 || keypriority.top==40)){
        if(640-(getPosition(ft,'top')+50)<movestep){
          setPosition(ft, 'top', 590);  // height-fighter.height
        }else{
          setPosition(ft, 'top', getPosition(ft,'top') + movestep);
        }
      }

      // 蓄力攻击
      if(ackey['83']==1){
        if(pilenum<1000){
          pilenum = pilenum + 20;
        }else if(is_pile==0){
          is_pile = 1;
          if(is_protect==1){
            setClass(ft, 'fighter_sp');
          }else{
            setClass(ft, 'fighter_s');
          }
        }
      }

    }, 20);
  }


  // 战机射击
  shot = function(){
    // 创建子弹
    var bullet = document.createElement('div');
    var offsetx;

    switch(power){
      case 1:
        offsetx = 20;
        break;
      case 2:
        offsetx = 15;
        break;
      case 3:
        offsetx = 10;
        break;
      case 4:
        offsetx = 4;
        break;
    }

    setClass(bullet, 'shot' + power);

    // 设置子弹初始位置
    setPosition(bullet, 'top', getPosition(ft, 'top')-30);
    setPosition(bullet, 'left', getPosition(ft, 'left') + offsetx);
    
    ft.parentNode.appendChild(bullet);
    
    // 设置子弹运动
    var et = setInterval(function(){
      if(getPosition(bullet,'top')<=-30 || is_lock==1){
        clearInterval(et);
        ft.parentNode.removeChild(bullet);  // 释放子弹
      }

      for(var i=0; i<enemydata.length; i++){
        if(enemydata[i]!=null){
          if(impact(bullet, enemydata[i])){  // 打中敌机
            destroy(enemydata[i]);
            scoreup(enemydata[i].type);
            enemydata[i] = null;
            clearInterval(et);
            ft.parentNode.removeChild(bullet);
          }
        }
      }

      if(curboss!=null){  // boss 战
        if(impact(bullet, curboss['obj'])){ // 打中boss
          curboss['armor']=parseInt(curboss['armor'])-power*10;
          clearInterval(et);
          ft.parentNode.removeChild(bullet);
        }
      }

      setPosition(bullet, 'top', getPosition(bullet, 'top')-15);

    }, 30)
  }


  // 蓄力射击
  pile_shot = function(){
    var pilebullet = document.createElement('div');
    setClass(pilebullet, 'pileshot');

    // 设置子弹初始位置
    setPosition(pilebullet, 'top', getPosition(ft, 'top')-30);
    setPosition(pilebullet, 'left', getPosition(ft, 'left'));
    
    ft.parentNode.appendChild(pilebullet);

    var et = setInterval(function(){
      if(getPosition(pilebullet,'top')<=-85 || is_lock==1){
        clearInterval(et);
        ft.parentNode.removeChild(pilebullet); // 释放子弹
      }

      for(var i=0; i<enemydata.length; i++){
        if(enemydata[i]!=null){
          if(impact(pilebullet, enemydata[i])){  // 打中敌机
            destroy(enemydata[i]);
            scoreup(enemydata[i].type);
            enemydata[i] = null;
          }
        }
      }

      if(curboss!=null){  // boss 战
        if(impact(pilebullet, curboss['obj'])){ // 打中boss
          curboss['armor']=parseInt(curboss['armor'])-100;
          clearInterval(et);
          ft.parentNode.removeChild(pilebullet); // 释放子弹
        }
      }

      setPosition(pilebullet, 'top', getPosition(pilebullet, 'top')-20);

    }, 30)
  }


  // 放炸弹
  bomb = function(){
    if(is_bombing==0 && bombnum>0){  // 不是爆炸中且有炸弹数
      is_bombing = 1;
      bombnum --;
      setHtml('bombnum', bombnum);  // 自减1

      var opacity = 100;
      setOpacity($('bomb'), opacity);
      disp('bomb', 'show');

      // 清除所有敌机及敌方子弹
      is_clear = 1;

      // 打击boss
      if(curboss!=null){
        curboss['armor'] = parseInt(curboss['armor'])-300;
      }

      var step = 0;
      var et = setInterval(function(){  // 炸弹效果
        if(step<11){
          setBgPosition($('bomb'), 0, step*(-280));
        }else{
          clearInterval(et);
          disp('bomb', 'hide');
          is_bombing = 0;
          is_clear = 0;
        }
        step ++;
      }, 70);
    }
  }


  // 游戏进程
  process = function(){
    var leveldata = map[level-1], processed = 0, step = 10;
    var levelstep = 0;  // 每关开始清0
    var et = setInterval(function(){
      if(is_lock==0){
        processed += step;
        if(attrcount(leveldata)>levelstep){  // 未完成本关
          if(leveldata['ms'+processed]){
            for(var i=0; i<leveldata['ms'+processed].length; i++){
              var msdata = leveldata['ms'+processed][i];
              create(msdata);
            }
            levelstep ++;  // 进度
          }
        }else{  // 已完成本关,进入Boss战
          bosswar();
          clearInterval(et);
        }
      }

      if(is_over==1){
        clearInterval(et);
      }

    }, step);
  }


  /* 创建关卡元素
  /* msdata:{
    num:出现的数量
    interval:间隔
    type:类型
    top:原始top坐标
    left:原始left坐标
    step:移动距离
    }
  */
  create = function(msdata){
    var num = msdata[0],
      interval = msdata[1],
      type = msdata[2],
      top = msdata[3],
      left = msdata[4],
      step = msdata[5];

    var et = setInterval(function(){
        if(num>0){
          var enft = document.createElement('div');
          setClass(enft, 'element' + type);
          enft.type = type;
          setPosition(enft, 'top', top);
          setPosition(enft, 'left', left);
          ft.parentNode.appendChild(enft);
          if(type<=10){
            enemydata.push(enft);
          }
          route(enft, type, step);
          num--;
        }else{
          clearInterval(et);
        }
      }, interval);
  }


  // 元素运动轨迹
  route = function(enft, type, step){
    var et = null;
    switch(type){
      case 1: // 曲线
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'top', getPosition(enft,'top')+Math.abs(step));
            setPosition(enft, 'left', getPosition(enft,'left')+step);
            count<5? count++ : (count=0, step*=-1);
            if(getPosition(enft, 'top')>640 || is_over==1 || is_clear==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            impact_handle(enft, et);
          }else{
            clearInterval(et);
          }
        }, 80);
        break;

      case 2: // 横向
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'left', getPosition(enft,'left')+step);
            count<9? count++ : (count=0, attack(enft,1,17,47));
            if(getPosition(enft,'left')>400 && step>0 || getPosition(enft,'left')<-50 && step<0 || is_over==1 || is_clear==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            impact_handle(enft, et);
          }else{
            clearInterval(et);
          }
        }, 80);
        break;

      case 3: // 竖向
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'top', getPosition(enft,'top')+step);
            count<9? count++ : (count=0, attack(enft,1,17,47));
            if(getPosition(enft,'top')>640 || is_over==1 || is_clear==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            impact_handle(enft, et);
          }else{
            clearInterval(et);
          }
        }, 75);
        break;

      case 4: // 左右循环移动攻击
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'left', getPosition(enft,'left')+step);
            count<10? count++ : (count=0, attack(enft,4,17,31));
            
            if(getPosition(enft,'left')>=350 && step>0 || getPosition(enft,'left')<=0 && step<0){
              step*=-1;
            }

            if(is_over==1 || is_clear==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            impact_handle(enft, et);
          }else{
            clearInterval(et);
          }
        }, 80);
        break;

      case 5: // 从后面攻击
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'top', getPosition(enft,'top')+step);
            count<9? count++ : (count=0, attack(enft,1,17,-17));
            if(getPosition(enft,'top')<-32 || is_over==1 || is_clear==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            impact_handle(enft, et);
          }else{
            clearInterval(et);
          }
        }, 75);
        break;

      case 11: // power gift
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'top', getPosition(enft,'top')+Math.abs(step));
            setPosition(enft, 'left', getPosition(enft,'left')+step);
            count<5? count++ : (count=0, step*=-1);
            if(getPosition(enft, 'top')>640 || is_over==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            if(impact(enft, ft) && is_lock==0){  // 奖励与战机相撞
              powerup();
              ft.parentNode.removeChild(enft);
              clearInterval(et);
            }
          }else{
            clearInterval(et);
          }
        }, 80);
        break;

      case 12: // bomb gift
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'top', getPosition(enft,'top')+Math.abs(step));
            setPosition(enft, 'left', getPosition(enft,'left')+step);
            count<5? count++ : (count=0, step*=-1);
            if(getPosition(enft, 'top')>640 || is_over==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            if(impact(enft, ft) && is_lock==0){  // 奖励与战机相撞
              bombup();
              ft.parentNode.removeChild(enft);
              clearInterval(et);
            }
          }else{
            clearInterval(et);
          }
        }, 80);
        break;

      case 13: // fighter gift
        var count = 0;
        et = setInterval(function(){
          if(node_exist(enft)){
            setPosition(enft, 'top', getPosition(enft,'top')+Math.abs(step));
            setPosition(enft, 'left', getPosition(enft,'left')+step);
            count<5? count++ : (count=0, step*=-1);
            if(getPosition(enft, 'top')>640 || is_over==1){
              clearInterval(et);
              ft.parentNode.removeChild(enft);
            }
            if(impact(enft, ft) && is_lock==0){  // 奖励与战机相撞
              fighterup();
              ft.parentNode.removeChild(enft);
              clearInterval(et);
            }
          }else{
            clearInterval(et);
          }
        }, 80);
        break;
    }
  }


  // 销毁
  destroy = function(dobj){  // dobj:被销毁的对象
    var dest = document.createElement('div');
    setClass(dest, 'destroy');
    setPosition(dest, 'top', getPosition(dobj, 'top'));
    setPosition(dest, 'left', getPosition(dobj, 'left'));
    ft.parentNode.appendChild(dest);

    if(dobj.id=='fighter'){  // 战机被击中
      disp(dobj.id, 'hide');
      power = 1;
      bombnum = 3;
      fighternum--;
      setHtml('fighternum', fighternum);
      setHtml('bombnum', bombnum);
      is_lock = 1;
    }else{
      dobj.parentNode.removeChild(dobj);
    }
    
    var step = 0;
    var et = setInterval(function(){
      if(step<11){
        setBgPosition(dest, step*(-48), 0);
        step++;
      }else{
        if(dobj.id=='fighter'){
          setTimeout(function(){
            if(fighternum>0){
              levelcontinue();
            }else{
              if(curboss!=null){
                obj = curboss['obj'];
                obj.parentNode.removeChild(obj);
              }
              gameover();  //战机全部被击中,游戏结束
            }
          },1000);
        }
        dest.parentNode.removeChild(dest);
        clearInterval(et);
      }
    }, 50);
  }


  // boss war
  bosswar = function(){
    var boss = bossdata[level-1];
    var bossft = document.createElement('div');
    setClass(bossft, 'boss' + level);
    setPosition(bossft, 'left', boss['left']);
    setPosition(bossft, 'top', boss['top']);
    ft.parentNode.appendChild(bossft);
    
    curboss = {"armor":boss['armor'],"obj":bossft};

    switch(level){
      case 1: // boss 1
      case 2: // boss 2
      case 3: // boss 3
      case 4: // boss 4
      case 5: // boss 5
      case 6: // boss 6
        var step = -3;
        var count = 0;
        var et = setInterval(function(){
          if(getPosition(bossft,'top')<50){  // boss 进场
            setPosition(bossft, 'top', getPosition(bossft, 'top')+5);
          }else{

            if(curboss['armor']<=0){  // boss over
              clearInterval(et);
              bossover();
            }else{

              if(step<0){ // 左移动
                if(getPosition(bossft,'left')>10){
                  setPosition(bossft, 'left', getPosition(bossft, 'left')+step);
                }else{
                  step*=-1;
                }
              }

              if(step>0){ // 右移动
                if(getPosition(bossft,'left')<260){
                  setPosition(bossft, 'left', getPosition(bossft, 'left')+step);
                }else{
                  step*=-1;
                }
              }

              if(count>=35 && count%35==0){
                 attack(bossft, 1, 30, 30);
                 attack(bossft, 1, 80, 30);
              }
              
              if(count>=60 && count%60==0){
                attack(bossft, 2, 15, 75);
                attack(bossft, 2, 105, 75);
              }

              if(count>=100 && count%100==0){
                attack(bossft, 3, 60, 92);
              }

              count<8400? count++ : count=0;

            }
          }
        }, boss['step']);
        break;
    }
  }


  /* attack
  * obj 敌机
  * type 攻击类型
  * left 子弹初始left
  * top 子弹初始top
  */
  attack = function(obj, type, left, top){
    if(is_lock==1){
      return false;  // 如已锁定不射击
    }

    var oleft = getPosition(obj, 'left')+left;
    var otop = getPosition(obj, 'top')+top;

    switch(type){

      case 1: //向战机攻击

        // 子弹初始位置与战机位置
        var opoint = {x:oleft+7, y:otop+7};
        var dpoint = {x:getPosition(ft,'left')+25, y:getPosition(ft,'top')+25};
        var p = vector(opoint, dpoint, 8);

        enftbullet('bullet', oleft, otop, p[0], p[1], 35);
        break;

      case 2: //直线攻击
        var num = 3;
        var st = setInterval(function(){
          if(num>0){
            enftbullet('bullet', oleft, otop, 0, 8, 35);
            num --;

          }else{
            clearInterval(st);
          }
        }, 150);
        break;

      case 3: // 散开攻击
        var num = 3;
        var st = setInterval(function(){
          if(num>0){
            switch(num){
              case 1:
                enftbullet('sbullet', oleft, otop, 0, 8, 35);
                break;

              case 2:
                enftbullet('sbullet', oleft, otop, 3, 8, 35);
                break;

              case 3:
                enftbullet('sbullet', oleft, otop, -3, 8, 35);
                break;
            }

            num --;

          }else{
            clearInterval(st);
          }
        }, 0);
        break;

      case 4: // 小散开攻击
        var num = 3;
        var st = setInterval(function(){
          if(num>0){
            switch(num){
              case 1:
                enftbullet('bullet', oleft, otop, 0, 8, 35);
                break;

              case 2:
                enftbullet('bullet', oleft, otop, 3, 8, 35);
                break;

              case 3:
                enftbullet('bullet', oleft, otop, -3, 8, 35);
                break;
            }

            num --;

          }else{
            clearInterval(st);
          }
        }, 0);
        break;
    }
  }


  /* enft bullet
  * type 子弹类型
  * oleft,otop 子弹初始位置
  * left,top 子弹?桃
  * speed 速度
  */
  enftbullet = function(type, oleft, otop, left, top, speed){
    var bullet = document.createElement('div');
    setClass(bullet, type);
    setPosition(bullet, 'left', oleft);
    setPosition(bullet, 'top', otop);
    ft.parentNode.appendChild(bullet);

    var et = setInterval(function(){
      setPosition(bullet, 'top', getPosition(bullet,'top')+top);
      setPosition(bullet, 'left', getPosition(bullet,'left')+left);

      if(getPosition(bullet,'left')>400 || getPosition(bullet,'left')<-30 || getPosition(bullet,'top')<-30 || getPosition(bullet,'top')>640 || is_lock==1 || is_clear==1){
        clearInterval(et);
        ft.parentNode.removeChild(bullet);
      }

      impact_handle(bullet, et);
    }, speed);
  }


  // boss over
  bossover = function(){
    obj = curboss['obj'];
    obj.parentNode.removeChild(obj);

    scoreup(6); // boss score

    var dest = document.createElement('div');
    setClass(dest, 'destroyboss');
    setPosition(dest, 'top', getPosition(obj, 'top'));
    setPosition(dest, 'left', getPosition(obj, 'left'));
    ft.parentNode.appendChild(dest);

    var step = 0;
    var et = setInterval(function(){
      if(step<21){
        setBgPosition(dest, step*(-150), 0);
      }else if(step==21){
        dest.parentNode.removeChild(dest);
      }else if(step==50){
        clearInterval(et);
        levelup();
      }
      step++;
    }, 50);
  }


  // continue
  levelcontinue = function(){
    reset_fighter();
    disp(ft.id, 'show');
    setProtect();
    fighter_init();
  }


  // 过关
  levelup = function(){
    keypriority = {};
    enemydata = [];
    curboss = null;
    level ++;

    bgsound('pass', false);

    var processed = 0;
    var et = setInterval(function(){
      is_lock = 1;
      processed = processed + 15;
      
      if(getPosition(ft, 'top')>-50){
        setPosition(ft, 'top', getPosition(ft, 'top')-15);
      }
      
      if(processed>=2500){
        clearInterval(et);
        disp(ft.id, 'hide');
        
        if(level<=map.length){
          bgchange(0);
          msg_show();
          setTimeout(function(){
            msg_hide();
            start();
          }, 1500);
        }else{
          gameclear();  // 通关
        }
      }
    }, 25);
  }


  // 更新分数
  scoreup = function(type){
    if(typeof(scoretag[type])!='undefined'){
      score = score + scoretag[type] * level;
      setHtml('score', score);
      if(score > hiscore){
        hiscore = score;
        setHtml('hiscore', hiscore);
      }
    }
  }


  // 子弹升级
  powerup = function(){
    power = power+1>4? 4 : power+1;
  }  


  // 炸弹增加
  bombup = function(){
    bombnum ++;
    setHtml('bombnum', bombnum);
  }


  // 战机增加
  fighterup = function(){
    fighternum ++;
    setHtml('fighternum', fighternum);
  }


  // 保护状态
  setProtect = function(){
    is_protect = 1;
    if(is_pile==1){
      setClass(ft, 'fighter_sp');
    }else{
      setClass(ft, 'fighter_p');
    }
    setTimeout(function(){
      is_protect = 0;
      if(is_pile==1){
        setClass(ft, 'fighter_s');
      }else{
        setClass(ft, 'fighter');
      }
    }, 3000)
  }


  // 碰撞处理
  impact_handle = function(obj, et){  // et 定时器
    if(impact(obj, ft) && is_lock==0){  // 产生碰撞
      if(is_protect==0){
        destroy(ft);
        clearInterval(et);
        ft.parentNode.removeChild(obj);
      }
    }
  }


  // 全部通关
  gameclear = function(){
    is_over = 1;
    disp('gameclear', 'show');
    setHtml('clearcon', 'Game Clear' + '<br>' + 'SCORE : ' + score);
    bgsound('clear', false);
    bgchange('clear');
    setTimeout(function(){
      bgsound();
      init();
    }, 16000);
  }


  // 游戏结束
  gameover = function(){
    is_over = 1;
    disp('gameover', 'show');
    setHtml('overcon', 'LEVEL : ' + level + '<br>' + 'SCORE : ' + score);
    bgsound('over', false);
    bgchange('over');
    failtimes++;
    setTimeout(function(){
      if(failtimes==3){
        alert('在游戏开始画面依次输入 ↑ ↑ ↓ ↓ ← → ← → a s a s,再开始游戏,会有惊喜^_^');
      }
      bgsound();
      init();
    }, 8000);
  }


  // 显示讯息
  msg_show = function(){
    setHtml('level', 'LEVEL - ' + level);
    disp('level', 'show');
    is_lock = 1;
  }


  // 隐藏讯息
  msg_hide = function(){
    disp('level', 'hide');
  }


  // 重置
  reset = function(){
    is_start = 0;
    is_bombing = 0;
    is_lock = 1;
    is_over = 0;
    is_clear = 0;
    is_protect = 0;
    level = 1;
    power = 1;
    ackey = {};
    keypriority = {};
    enemydata = [];
    score = 0;
    fighternum = 3;
    bombnum = 3;

    setHtml('hiscore', hiscore);
    setHtml('score', score);
    setHtml('fighternum', fighternum);
    setHtml('bombnum', bombnum);

    reset_fighter();
    reset_pile();

    disp('op', 'show');
    disp('gameover', 'hide');
    disp('gameclear', 'hide');

    bgchange(0);
  }


  // 重置战机位置
  reset_fighter = function(){
    setPosition(ft, 'top', 640);
    setPosition(ft, 'left', 175);
    setClass(ft, 'fighter');
  }


  // 重置蓄力
  reset_pile = function(){
    is_pile = 0;
    pilenum = 0;
    if(is_protect==1){
      setClass(ft, 'fighter_p');
    }else{
      setClass(ft, 'fighter');
    }
  }


  // 战机初始化
  fighter_init = function(){
    var et = setInterval(function(){
      if(getPosition(ft, 'top')>400){
        setPosition(ft, 'top', getPosition(ft, 'top')-12);
      }else{
        clearInterval(et);
        is_lock = 0;
        action();
      }
    }, 30);
  }


  // 密技30命
  cheat = function(){
    if(cheatcode.join(',')=='38,38,40,40,37,39,37,39,65,83,65,83,13'){
      fighternum = 30;
      setHtml('fighternum', fighternum);
    }
    cheatcode = [];
  }


  // 背景控制
  bgmove = function(obj){
    var step = 1;
    var et = setInterval(function(){
      var bgpos = getBgPosition(obj);
      if(bgpos['top']==640){
        setBgPosition(obj, 0, 0);  // reset
      }else{
        setBgPosition(obj, bgpos['left'], bgpos['top']+step);
      }
    }, 50);
  }


  // 背景切换
  bgchange = function(file){
    var obj = $('gameplane');
    setClass(obj, 'gameplane bg'+file);
  }


  // 音乐控制
  bgsound = function(file, loop){
        var id = 'audioplayer';
        
        if(typeof(file)!='undefined'){
            if(typeof(loop)=='undefined'){
                loop = false;
            }

            var audiofile = [];
            audiofile['mp3'] = 'music/' + file + '.mp3';
            audiofile['ogg'] = 'music/' + file + '.ogg';
            audioplayer(id, audiofile , loop);
        }else{
            audioplayer(id);
        }
  }

  return this;

})();

相信本文所述对大家javascript游戏设计有一定的借鉴价值。

Javascript 相关文章推荐
Javascript下的keyCode键码值表
Apr 10 Javascript
javascript开发中因空格引发的错误
Nov 08 Javascript
javascript中通过arguments参数伪装方法重载
Oct 08 Javascript
javascript正则表达式中的replace方法详解
Apr 20 Javascript
JS基于Mootools实现的个性菜单效果代码
Oct 21 Javascript
jQuery中的通配符选择器使用总结
May 30 Javascript
深入理解jQuery事件绑定
Jun 02 Javascript
判断输入的字符串是否是日期格式的简单方法
Jul 11 Javascript
基于AngularJS前端云组件最佳实践
Oct 20 Javascript
angularJS模态框$modal实例代码
May 27 Javascript
浅谈angular4.0中路由传递参数、获取参数最nice的写法
Mar 12 Javascript
vue print.js打印支持Echarts图表操作
Nov 13 Javascript
JS小游戏之极速快跑源码详解
Sep 25 #Javascript
JS小游戏之象棋暗棋源码详解
Sep 25 #Javascript
我用的一些Node.js开发工具、开发包、框架等总结
Sep 25 #Javascript
jquery中使用循环下拉菜单示例代码
Sep 24 #Javascript
用C/C++来实现 Node.js 的模块(二)
Sep 24 #Javascript
用C/C++来实现 Node.js 的模块(一)
Sep 24 #Javascript
JS实现一个列表中包含上移下移删除等功能
Sep 24 #Javascript
You might like
php学习笔记 PHP面向对象的程序设计
2011/06/13 PHP
php-fpm配置详解
2014/02/12 PHP
CodeIgniter框架过滤HTML危险代码
2014/06/12 PHP
ThinkPHP3.1新特性之对页面压缩输出的支持
2014/06/19 PHP
ecshop后台编辑器替换成ueditor编辑器
2015/03/03 PHP
JavaScript DOM 学习第五章 表单简介
2010/02/19 Javascript
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
尝试动手制作javascript放大镜效果
2015/12/25 Javascript
javascript获取select标签选中的值
2016/06/04 Javascript
微信小程序 五星评分(包括半颗星评分)实例代码
2016/12/14 Javascript
bootstrap表单按回车会自动刷新页面的解决办法
2017/03/08 Javascript
Vue.js中extend选项和delimiters选项的比较
2017/07/17 Javascript
vue自定义过滤器创建和使用方法详解
2017/11/06 Javascript
js逆向解密之网络爬虫
2019/05/30 Javascript
JavaScript 继承 封装 多态实现及原理详解
2019/07/29 Javascript
vue界面发送表情的实现代码
2020/09/11 Javascript
Python使用微信SDK实现的微信支付功能示例
2017/06/30 Python
Python随机生成手机号、数字的方法详解
2017/07/21 Python
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
PYTHON基础-时间日期处理小结
2018/05/05 Python
pandas 实现字典转换成DataFrame的方法
2018/07/04 Python
浅谈Django中view对数据库的调用方法
2019/07/18 Python
centos7中安装python3.6.4的教程
2019/12/11 Python
如何使用Python多线程测试并发漏洞
2019/12/18 Python
matplotlib 对坐标的控制,加图例注释的操作
2020/04/17 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
Footshop罗马尼亚:最好的运动鞋选择
2019/09/10 全球购物
学校介绍信范文
2014/01/14 职场文书
产品质量承诺书范文
2014/03/27 职场文书
银行行长竞聘演讲稿
2014/04/23 职场文书
留守儿童工作方案
2014/06/02 职场文书
文员转正自我鉴定怎么写
2014/09/29 职场文书
师德师风个人整改措施
2014/10/27 职场文书
2015年行政人事工作总结
2015/05/21 职场文书