葭丁山与樊梨花电视剧:Html5小游戏之【是男人就忍30秒】

来源:百度文库 编辑:九乡新闻网 时间:2024/05/03 12:30:37
好久没写过小游戏了,最近抽时间写了一个,看了一些高人写的游戏,无限感慨呀。。。也从中学到了不少东西。

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

  这次的游戏是【是男人就忍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
  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 :{width: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 = "http://blog.soso.com/qz.q/img/fly.gif";

  40 bulletImg.src = "http://blog.soso.com/qz.q/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.hei ght);

  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
  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
  162

  163 if(this.bullets[i] == item){

  164 this.bullets.splice(i,1);

  165 return true;

  166 }

  167 }

  168 }

  169

  170 }

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

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

  源码下载>>