原生javascript开发仿微信打飞机小游戏

  今天闲来无事,于是就打算教一个初学javascript的女童鞋写点东西,因此为了兼顾趣味性与简易程度,果断想到了微信的打飞机小游戏。。

本来想用html5做的,但是毕竟人家才初学,连jquery都还不会,所以最终还是决定用原生的javascript。虽说相对于园内的高手们而言代码算不上优雅,效率算不上高,不过对于初学者来练手还是足以。。

 

   三个文件,main.js(主函数),entity.js(实体类与工厂类),util.js(工具类),基本原理就是把位置信息保存在对象里面,然后在setInterval里面统一对所有对象进行更新显示。程序所用到的飞机与子弹图片都是从微信上截屏得来的。

 

先上图:

 

再上代码:

index.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>打飞机</title>
<script type="text/javascript" src="js/util.js"></script>
<script type="text/javascript" src="js/entity.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">

window.onload=function(){
    Main.init();
    Util.g("startBtn").onclick=function(){
        Main.start();
        this.style.display="none";
    }
}
</script>
</head>
<body>
<div id="parent" style="
        margin: 0 auto; 
        width:350px; height:480px; 
        background-color:#c3c9c9; 
        position: relative;
        overflow:hidden;">
    <div style="
        position:absolute;
        left:5px;
        top:5px;">积分:<span id="score">0</span></div>
    <button 
        style=" 
            position:absolute; 
            left:150px;
            top:240px;
            display:block;" 
        id="startBtn">
    点击开始
    </button>

</div>
</body>
</html>
View Code

 

main.js:

// JavaScript Document
var Main={
    init:function(){
        Util.init();
    },
    _totalEnemies:8,
    start:function(){
        //初始化敌机
        enemyPlaneFactory.creatEnemyPlane(this._totalEnemies);
        
        //初始化自己
        selfPlane.init();
        
        //初始化子弹
        bulletFactory.creatBullet(100);
        //开始渲染画面
        this._render();
        //开始射击子弹
        this._startShoot();
        
        //初始化键盘事件响应
        this._initEvent();
    },
    
    //渲染定时器
    _render_t:null,
    _render:function(){
        this._render_t=setInterval(function(){
            var enemys=enemyPlaneFactory.enemys;
            for(var i in enemys){
                var enemy=enemys[i];
                enemy.move(0,enemy.speed);
                
                if(enemy.x+enemy.e.width>selfPlane.x+10
                    &&enemy.x<selfPlane.x+selfPlane.e.width-10
                    &&enemy.y+enemy.e.height>selfPlane.y+selfPlane.e.height/2
                    &&enemy.y<selfPlane.y+selfPlane.e.height){
                        enemy.isDied=true;
                        clearInterval(Main._render_t);
                        clearInterval(Main._startShoot_t);
                        var b=window.confirm("对不起,您已经挂了,是否重玩?")
                        if(b){
                            window.location.reload();
                        }
                }
                
                if(enemy.y>Util.windowHeight||enemy.isDied){
                    enemy.restore();
                }
            }
            
            var bullets=bulletFactory.bullets;
            for(var i in bullets){
                var bullet=bullets[i];
                bullet.move(0,-bullet.speed);
                
                for(var i in enemys){
                    var enemy=enemys[i];
                    //判断子弹是否击中敌机,如果击中则隐藏子弹,杀死敌机,增加积分..
                    if(bullet.y>10
                        &&bullet.x>enemy.x
                        &&bullet.x<enemy.x+enemy.e.width
                        &&bullet.y<enemy.y+enemy.e.height){
                            enemy.isDied=true;
                            bullet.e.style.top=-bullet.e.height;
                            selfPlane.score+=50;
                            Util.scoreSpan.innerHTML=selfPlane.score+"";
                    }
                }
            }
            
            
        },1000/15);
    },
    //射击定时器
    _startShoot_t:null,
    _startShoot:function(){
        var i=0;
        var bullets=bulletFactory.bullets;
        var bulletsCount=bullets.length;
        this._startShoot_t=setInterval(function(){
            if(i>=bulletsCount){
                i=0;
            }
            var bullet=bullets[i];
            bullet.moveTo(selfPlane.x+selfPlane.e.width/2-bullet.e.width/2,selfPlane.y-bullet.e.height-3);
            i++;
        },300);
    },
    keyMove:10,
    _initEvent:function(){
        window.onkeydown=function(e){
            /*
            37:左
            38:上
            39:右
            40:下
            */
            var keynum;
            var left=37,up=38,right=39,down=40;

            if(window.event){// IE
              keynum = e.keyCode
            }else if(e.which) {// Netscape/Firefox/Opera
              keynum = e.which
            }
            
            switch(keynum){
                case left:
                selfPlane.move(-Main.keyMove,0);
                break;
                case up:
                selfPlane.move(0,-Main.keyMove);
                break;
                case right:
                selfPlane.move(Main.keyMove,0);
                break;
                case down:
                selfPlane.move(0,Main.keyMove);
                break;
                
                default:
                break;
            }
            
            //console.log(keynum);
        }
        
    }
    
    
}
View Code

 

entity.js:

//自身的对象
var selfPlane={
    x:0,
    y:0,
    score:0,
    e:null,
    init:function(){
        this.x=(Util.windowWidth-Util.selfPlaneElement.width)/2;//相对于父窗体的x偏移(css:left)
        this.y=Util.windowHeight-Util.selfPlaneElement.height;//相对于父窗体的y偏移(css:top)
        this.e=Util.selfPlaneElement;//对应的dom元素
        Util.selfPlaneElement.style.left=this.x+"px";
        Util.selfPlaneElement.style.top=this.y+"px";
        Util.parentElement.appendChild(this.e);
    },
    move:function(moveX,moveY){
        var x=this.x+moveX;
        var y=this.y+moveY;
        
        if(x<0-this.e.width/2||x>Util.windowWidth-this.e.width/2){
            return ;
        }
        if(y<0-this.e.height/2||y>Util.windowHeight-this.e.height/2){
            return ;
        }
        this.x=x;
        this.y=y;
        
        this.e.style.left=this.x+"px";
        this.e.style.top=this.y+"px";
    },
    moveTo:function(x,y){
        
        if(x<0-this.e.width/2||x>Util.windowWidth-this.e.width/2){
            return ;
        }
        if(y<0-this.e.height/2||y>Util.windowHeight-this.e.height/2){
            return ;
        }
        this.x=x;
        this.y=y;
        
        this.e.style.left=this.x+"px";
        this.e.style.top=this.y+"px";
    }
}


//敌机的类
var enemyPlane=function(x,y,speed){
    this.x=x;
    this.y=y;
    this.e=Util.enemyPlaneElement.cloneNode(true);
    this.e.style.left=x;
    this.e.style.top=y;
    this.e.style.display="none";
    Util.parentElement.appendChild(this.e);
    this.e.style.display="block";
    this.speed=speed;
    this.isDied=false;
}
//prototype:原型
enemyPlane.prototype.move=function(moveX,moveY){
    this.x+=moveX;
    this.y+=moveY;
    this.e.style.left=this.x+"px";
    this.e.style.top=this.y+"px";
}
//敌人复活
enemyPlane.prototype.restore=function(){
    this.x=Math.random()*(Util.windowWidth-Util.enemyPlaneElement.width);
    this.y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
    this.speed=2+Math.random()*4;
    this.e.style.left=this.x+"px";
    this.e.style.top=this.y+"px";
    this.isDied=false;
}
//敌机工厂
var enemyPlaneFactory={
    enemys:[],
    creatEnemyPlane:function(n){
        for(var i=0;i<n;i++){
            //0~1 乘以窗口宽度,得到的就是从0~窗口宽度的一个随机x值
            var x=Math.random()*(Util.windowWidth-Util.enemyPlaneElement.width);
            var y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
            var speed=2+Math.random()*4;
            var ep=new enemyPlane(x,y,speed);
            this.enemys.push(ep);
        }
    }
}
//子弹
var bullet=function(x,y,speed){
    this.x=x;
    this.y=y;
    this.speed=speed;
    this.e=Util.bulletElement.cloneNode(true);
    this.e.style.left=this.x+"px";
    this.e.style.top=this.y+"px";
    Util.parentElement.appendChild(this.e);
    this.isUsed=false;
}

bullet.prototype.move=function(moveX,moveY){
    this.x+=moveX;
    this.y+=moveY;
    this.e.style.left=this.x+"px";
    this.e.style.top=this.y+"px";
}
bullet.prototype.moveTo=function(X,Y){
    this.x=X;
    this.y=Y;
    this.e.style.left=this.x+"px";
    this.e.style.top=this.y+"px";
}


//子弹恢复
bullet.prototype.restore=function(){
    this.x=Main.self
    this.y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
    this.speed=2+Math.random()*4;
    this.e.style.left=this.x+"px";
    this.e.style.top=this.y+"px";
}
//子弹工厂
var bulletFactory={
    bullets:[],
    creatBullet:function(n){
        for(var i=0;i<n;i++){
            var b=new bullet(0,-Util.bulletElement.height,20);
            this.bullets.push(b);
        }
    }
}
View Code

 

util.js:

// JavaScript Document
var Util={
    windowWidth:350,
    windowHeight:480,
    selfPlaneElement:null,
    enemyPlaneElement:null,
    bulletElement:null,
    parentElement:null,
    scoreSpan:null,
    g:function(id){
        return document.getElementById(id);
    },
    
    init:function(){
        this.parentElement=this.g("parent");
        
        this.selfPlaneElement=this._loadImg("images/self.gif");
        
        this.enemyPlaneElement=this._loadImg("images/boss.gif");
        
        this.bulletElement=this._loadImg("images/bullet.jpg");
        
        this.scoreSpan=this.g("score");
    },
    
    _loadImg:function(src){
        var e=document.createElement("img");
        e.style.position="absolute";
        e.src=src;
        return e;
    }
}
View Code

 

 在线预览:预览

源码下载地址:打飞机小游戏原生javascript版

posted @ 2014-02-03 23:58  Zane Young  阅读(5933)  评论(18编辑  收藏  举报