zoukankan      html  css  js  c++  java
  • Html5小游戏之【是男人就忍30秒】

    好久没写过小游戏了,最近抽时间写了一个,看了一些高人写的游戏,无限感慨呀。。。也从中学到了不少东西。

    我不会写什么大的游戏,因为需要很多时间与精力,而且自认水平有限,个人喜欢写些小游戏。

    这次的游戏是【是男人就忍30秒】,游戏玩法很简单,就是用键盘控制飞机,飞来飞去,躲开子弹,看你能撑多久。

    本来是打算写一个教程来一步步说明的,但后来想了想,还是算了,免得误人子弟,在源码上加些注释就可以。

    没有测试过IE9,因为没有IE9。。。鄙人还是用XP的。。。所以还是请用谷歌或者FF或者Safari吧。

    刚刚修复了在FF下不能使用的问题,因为没给canvas设置tabindex属性,它就不能触发keydown事件,以及设置canvas为focus,现在可以了。。。 

    游戏预览如下:

    请使用chrome,safari,ff

    此游戏用了四个js文件。

    1。canvas.js,简单了封装了一些需要用到的画图方法,相信一看就懂了。。。

     1 //画布类
     2 var Canvas = {
     3     //画布的2d对象
     4     cxt : null,
     5     //初始化画布
     6     init : function(id){
     7         this.cxt = (typeof id=='string'?document.getElementById(id):id).getContext('2d');
     8     },
     9     //清除画布
    10     clear : function(x,y){
    11         this.cxt.clearRect(0,0,x,y);
    12     },
    13     //画图
    14     drawImg : function(obj){
    15         this.cxt.drawImage(obj.img,obj.x,obj.y);
    16     },
    17     //画文字
    18     drawText : function(string,x,y,color){
    19         
    20         this.cxt.fillStyle = color;
    21         this.cxt.font = 'bold 14px sans-serif';
    22         this.cxt.fillText(string,x,y);
    23     },
    24     //加载图片
    25     //imgs:图片对象的数组
    26     //callback:回调函数
    27     //context:上下文对象
    28     loadImgs : function(imgs,callback,context){
    29     
    30         var success_count = 0;
    31         
    32         var addCount = function(){
    33             success_count += 1;
    34             
    35             if(success_count == l)callback && callback.call(context);
    36         }
    37         
    38         for(var i=0,l=imgs.length;i<l;i++){
    39             imgs[i].onload = addCount;
    40         }
    41         
    42     }
    43 }

    2。fly.js,飞机类,采用在计时器中移动,而非一般的键盘按一下就移动一格,这样做,控制得更流畅,而且,可以支持打斜飞。

     1 var Fly = function(img,x,y){
     2     //飞机的图片
     3     this.img = img;
     4     //飞机的坐标
     5     this.x = x;
     6     this.y = y;
     7     //飞机的移动方向值
     8     this.moveDir = {
     9         left:false,
    10         right:false,
    11         up:false,
    12         down:false
    13     };
    14     //移动的速度
    15     this.movesp = 2;
    16 }
    17 Fly.prototype = {
    18     //键盘码对应移动方向
    19     keyCode2Dir : {
    20         37:'left',
    21         38:'up',
    22         39:'right',
    23         40:'down'
    24     },
    25     //键盘按下事件
    26     //keyCode:键盘码
    27     keyDown : function(keyCode){
    28         //修改对应的移动值
    29         this.moveDir[this.keyCode2Dir[keyCode]]=true;
    30     },
    31     //键盘释放事件
    32     //keyCode:键盘码
    33     keyUp : function(keyCode){
    34         //修改对应的移动值
    35         this.moveDir[this.keyCode2Dir[keyCode]]=false;
    36     },
    37     //判断是否在移动中
    38     checkMove : function(){
    39         if(this.moveDir.left || this.moveDir.right || this.moveDir.up || this.moveDir.down)return true;
    40         return false;    
    41     },
    42     //移动
    43     //gameInfo:游戏背景信息
    44     move : function(gameInfo){
    45         
    46         var This = this;
    47         //根据方向来移动
    48         if(This.moveDir.left)This.x -= This.movesp;
    49         if(This.moveDir.right)This.x += This.movesp;
    50         if(This.moveDir.up)This.y -= This.movesp;
    51         if(This.moveDir.down)This.y += This.movesp;
    52         //边界值检测
    53         if(This.x <0)This.x=0;
    54         else if(This.x >gameInfo.width-This.img.width)This.x = gameInfo.width-This.img.width;
    55         if(This.y <0)This.y=0;
    56         else if(This.y >gameInfo.height-This.img.height)This.y = gameInfo.height-This.img.height;
    57     }
    58 
    59 }

    3。bullet.js,子弹类,子弹的飞,我承认,确实做得很简单,希望大家自己改进这个算法。。。

     1 var Bullet = function(img){
     2     //子弹的图片
     3     this.img = img;
     4     //X坐标
     5     this.x = 0;
     6     //Y坐标
     7     this.y = 0;
     8     //子弹要飞的x与y的速度
     9     this.arc = {};
    10     //移动的帧数
    11     this.moveFps = 20;
    12     //帧数延迟
    13     this.moveFpsLazy = 0;
    14     //初始化
    15     this.init();
    16 }
    17 Bullet.prototype = {
    18     //方向数组
    19     arrDir : ['left','right','up','down'],
    20     //初始化
    21     init : function(){
    22         //最小位置
    23         var min = 5,
    24             //最大位置
    25             max = 395,
    26             //随机位置
    27             rnd = Math.floor(Math.random()*370+10),
    28             //移动方向
    29             dir = this.arrDir[Math.floor(Math.random()*4)];
    30         
    31         //设置子弹的初始位置与将要飞的方向与速度    
    32         switch(dir){
    33             case 'left':{
    34                 this.x = max;
    35                 this.y = rnd;
    36                 if(this.y>=max/2)this.arc = {x:-5,y:-2};
    37                 else this.arc={x:-5,y:2};
    38                 break;
    39             }
    40             case 'right':{
    41                 this.x = min;
    42                 this.y = rnd;
    43                 if(this.y>=max/2)this.arc = {x:5,y:-2};
    44                 else this.arc={x:5,y:2};
    45                 break;
    46             }
    47             case 'up':{
    48                 this.y = max;
    49                 this.x = rnd;
    50                 if(this.x>=max/2)this.arc = {x:-3,y:-5};
    51                 else this.arc={x:3,y:-5};
    52                 break;
    53             }
    54             case 'down':{
    55                 this.y = min;
    56                 this.x = rnd;
    57                 if(this.x>=max/2)this.arc = {x:-3,y:5};
    58                 else this.arc={x:3,y:5};
    59                 break;
    60             }
    61         }
    62     },
    63     //更新子弹数据
    64     //gameInfo:游戏背景信息
    65     updata : function(gameInfo){
    66         //延迟+10
    67         this.moveFpsLazy += 10;
    68         //判断延迟是否等于移动帧数
    69         if(this.moveFpsLazy == this.moveFps){
    70             //移动
    71             this.x += this.arc.x;
    72             this.y += this.arc.y;
    73             //边界值检测
    74             if(this.x <0 || this.x > gameInfo.width || this.y <0 || this.y > gameInfo.height){
    75                 this.callback();
    76                 return false;
    77             }
    78             //清0
    79             this.moveFpsLazy = 0;
    80         }
    81     },
    82     //检测是否撞到飞机
    83     //fly:飞机对象
    84     checkCrashFly : function(fly){
    85         //获取子弹与飞机的圆心坐标
    86         var bx = this.x+this.img.width/2,by = this.y+this.img.height/2,
    87             fx = fly.x+fly.img.width/2,fy = fly.y+fly.img.height/2;
    88         //判断圆心距
    89         if(Math.sqrt(Math.pow(bx-fx,2)+Math.pow(by-fy,2)) < (fly.img.width/2+this.img.width/2)){
    90             return true;
    91         }
    92         return false;
    93     },
    94     //回调函数
    95     callback : function(){}
    96 
    97 }

    4。Game.js,游戏控制类,主要控制游戏的逻辑

      1 var Game = {
      2     //游戏背景数据,主要是宽与高
      3     gameInfo :{0,height:0},
      4     //飞机对象
      5     fly : null,
      6     //子弹对象数组
      7     bullets : [],
      8     //子弹图片
      9     bulletImg : null,
     10     //子弹产生的延迟
     11     bulletLazyFps : 0,
     12     //绘画处理计时器ID
     13     processId : 0,
     14     //分数
     15     score : 0,
     16     //是否开始
     17     isStart : false,
     18     //显示开始信息
     19     showStart : function(){
     20         
     21         var This = this;
     22         //画开始字
     23         Canvas.drawText("Press Enter to Start!",120,200,'white');
     24         //绑定事件
     25         document.body.onkeydown = function(e){This.keyDown(e);};
     26         document.body.onkeyup = function(e){This.keyUp(e);};
     27     },
     28     //游戏初始化
     29     init : function(){
     30         //设置游戏背景信息
     31         var gameBg = document.getElementById('js_canvas');
     32         this.gameInfo.width = gameBg.offsetWidth;
     33         this.gameInfo.height = gameBg.offsetHeight;
     34         //初始化画布
     35         gameBg.focus();Canvas.init(gameBg);
     36         //设置飞机图片与子弹图片
     37         var flyImg = new Image();
     38         var bulletImg = new Image();
     39         flyImg.src = "img/fly.gif";
     40         bulletImg.src = "img/bullet.gif";
     41         //加载图片,成功后,回调显示开始信息
     42         Canvas.loadImgs([flyImg,bulletImg],this.showStart,this);
     43         //设置飞机对象
     44         this.fly = new Fly(flyImg,200,200);
     45         //设置Game子弹图片
     46         this.bulletImg = bulletImg;
     47     },
     48     //生成子弹
     49     createBullets : function(){
     50         
     51         var This = this;
     52         //判断延时是否200
     53         if(this.bulletLazyFps == 200){
     54             //创建子弹,添加到数组中
     55             var bullet = new Bullet(this.bulletImg);
     56             bullet.callback = function(){
     57                 This.removeBullet(this);
     58             }
     59             
     60             this.bullets.push(bullet);
     61             this.bulletLazyFps = 0;
     62         }
     63         else{
     64             this.bulletLazyFps += 10;
     65         }
     66     },
     67     //开始
     68     start : function(){
     69         
     70         var This = this;
     71         //重置数据
     72         this.reset();
     73         //设置开始
     74         this.isStart = true;
     75         //开始绘画
     76         this.process();
     77         
     78     },
     79     //重置数据
     80     reset : function(){
     81         
     82         this.score = 0;
     83         this.bullets = [];
     84     },
     85     //结束
     86     end : function(){
     87         
     88         this.isStart = false;
     89         
     90         clearInterval(this.processId);
     91         
     92         this.showStart();
     93     },
     94     //绘画函数
     95     process : function(){
     96         
     97         var This = this;
     98         //绘画计时器
     99         this.processId = setInterval(function(){
    100             
    101             if(!This.isStart)return;
    102             //清除画布
    103             Canvas.clear(This.gameInfo.width,This.gameInfo.height);
    104             //判断飞机是否移动
    105             if(This.fly.checkMove())This.fly.move(This.gameInfo);
    106             //画飞机
    107             Canvas.drawImg(This.fly);
    108             //生产子弹
    109             This.createBullets();
    110             //画出所有子弹
    111             for(var i=0,l=This.bullets.length;i<l;i++){
    112                 
    113                 var bullet = This.bullets[i];
    114                 
    115                 if(!bullet)continue;
    116                 //更新子弹信息
    117                 bullet.updata(This.gameInfo);
    118                 //画子弹
    119                 Canvas.drawImg(bullet);
    120                 //检测是否撞到飞机
    121                 if(bullet.checkCrashFly(This.fly)){
    122                     This.end();
    123                 }
    124             }
    125             //画分数
    126             Canvas.drawText(Math.floor(This.score/1000)+"秒",20,20,'white');
    127             This.score += 10;
    128         },10);
    129     },
    130     //键盘按下事件
    131     keyDown : function(e){
    132         
    133         var This =this;
    134         //游戏还没开始,而且按了回车
    135         if(e.keyCode == 13 && !this.isStart){
    136             e.preventDefault();
    137             //开始
    138             this.start();
    139         }
    140         //游戏开始而且按了方向键
    141         if(e.keyCode >= 37 && e.keyCode <= 40 && this.isStart){
    142             e.preventDefault();
    143             
    144             This.fly.keyDown(e.keyCode);
    145         }
    146     },
    147     //键盘释放事件
    148     keyUp : function(e){
    149         
    150         var This = this;
    151         //释放了方向键
    152         if(e.keyCode >= 37 && e.keyCode <= 40){
    153             e.preventDefault();
    154             
    155             This.fly.keyUp(e.keyCode);
    156         }
    157     },
    158     //移除子弹
    159     removeBullet : function(item){
    160         
    161         for(var i=0,l=this.bullets.length;i<l;i++){
    162             
    163             if(this.bullets[i] == item){
    164                 this.bullets.splice(i,1);
    165                 return true;
    166             }
    167         }
    168     }
    169 
    170 }

    突然发觉自己写的那些,为啥会那么卡了。。。因为,我以前都是计时器分开来写,后来才发现,要放在同一个计时器去做动画。。。

    希望大家喜欢,有啥不好的,欢迎指出。。。

    源码下载>>

  • 相关阅读:
    推荐!国外程序员整理的 PHP 资源大全
    PHPSTORM/IntelliJ IDEA 常用 设置配置优化
    PHPStorm下XDebug配置
    MySQL修改root密码的多种方法
    php 修改上传文件大小 (max_execution_time post_max_size)
    phpstorm8注册码
    Linux提示no crontab for root的解决办法
    网站的通用注册原型设计
    解决mysql出现“the table is full”的问题
    通过php下载文件并重命名
  • 原文地址:https://www.cnblogs.com/floyd/p/1937659.html
Copyright © 2011-2022 走看看