本篇内容介绍了“怎么用h5实现打火箭小游戏”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
一.游戏介绍
游戏介绍:
不断有携带字母炸弹的火箭撞向地面,请根据火箭身上的字母敲击键盘,每一次对应的敲击会击落携带该字母的火箭并使得分加一,每一架火箭撞到地面会使生命值减一,每击落十架火箭,火箭数会加一,并奖励一点额外生命值,生命值上限为八。
二.HTML内容
index.html里包含canvas画布和一个 介绍游戏规则的div,
当鼠标点击页面任何一个地方的时候,进入游戏界面:
index
浏览器不支持canvas
1.Click space to pause or begin game.
2.Enter the letter on the rockets to hit them.
3.Number of the hearts will add one together with the rockets after ten rockets hit.
4.Failed when the number of hearts equals zero.
5.Click anywhere to start game!
二.JS内容
1.动画实现
common.js中并未使用setTimeOut()或者setInterval()作为动画定时器,而是使用window.requestAnimationFrame,一种更为优化的方式实现动画效果。
requestAnimFrame的用法,先设置浏览器的兼容,并设置动画的帧率,这里设置为每1000/60ms执行一次回调函数
window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; })();
requestAnimFrame中的两个参数,callback为下次重画执行的函数,element为要重画的节点,即
requestAnimFrame(callback, element);
2.代码块及对象分析
(1) 在Game代码块控制游戏的开始、结束和重新开始以及动画的运行和鼠标、键盘点击事件的判定
Game.begin(),游戏开始界面,点击任意位置,调用Game.run()函数进入游戏运行界面
Game.run(),游戏运行界面,这里使用自定义兼容函数requestAnimFrame不断回调Game.transform()函数对画布重绘,并调用键盘点击监听函数Game.hit(event),判断按键是否击中火箭
Game.over(),游戏结束界面,显示游戏得分、游戏中奖励的生命值和最终火箭数,点击任意位置会调用Game.restart()函数初始化游戏参数并调用Game.begin()进入游戏开始界面
(2) Background代码块用于绘制背景,默认样式为垂直方向灰度加深的渐变色
(3) Hearts代码块,根据全局变量heartsNum设置生命值的数量,初始为5,通过迭代和设置水平偏移量offSetX创建hearts数组中对象的位置属性,而Heart对象则要保存位置和半径属性。另外,Heart对象中设置draw()函数进行自绘,而Hearts代码块中设置draw()函数控制hearts数组中所有对象的自绘 ,以此实现动画运行时生命值的状态管理 。
(4) Rockets代码块负责绘制小火箭们,火箭数量由全局变量rocketsNum控制,初始为5,火箭的具体绘制由Rocket对象完成,在这里Rocket对象的状态是随机产生的,Rockets代码块中的rockets数组负责保存所有Rocket对象的状态。Rockets代码块控制所有Rocket对象的自绘,并在键盘敲击时,循环遍历数组中的对象以判断火箭是否被击中。
(5) TextNodes代码块负责绘制文本,TextNodes.setup()函数负责设置文本的内容、位置、字体、样式和字符的偏移量,当然也可以不进行设置,这时会采用默认值。TextNode对象保存单个字符的内容和位置信息并负责文本的自绘,TextNodes代码块会负责所有nodes数组中的对象的自绘。
(6) start函数负责从介绍游戏规则的界面转到游戏开始界面。
下面就不多说了,贴代码common.js:
window.onload=function(){var canvas=document.getElementById("canvas");var ctx=canvas.getContext("2d");canvas_width=canvas.width;canvas_height=canvas.height;var heartsNum=5;//生命值数var extraHearts=0;//额外增加的生命值数var rocketsNum=5;//火箭数var score=0;//得分数window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); };})();var Game={animationID:0,//animationID,flag控制暂停和开始flag:true,begin:function(){ctx.clearRect(0,0,canvas_width,canvas_height);Background.draw("yellow");TextNodes.setup("HitRocket",100,240,"96px 楷体,arial","#000");TextNodes.draw();TextNodes.setup("Click anywhere to start",150,360,"42px 楷体,arial","#000");TextNodes.draw();Rockets.init();Hearts.init();window.addEventListener("click",Game.run);},//缓冲,移除监听器run:function(){window.removeEventListener("click",Game.run);Game.transform();window.addEventListener("keyup",Game.hit);},transform:function(){if(heartsNum>0){Game.animationID=requestAnimationFrame(Game.transform);//清空画布ctx.clearRect(0,0,canvas_width,canvas_height);//背景Background.draw();//计分TextNodes.setup("Score:"+score,640,50,"42px 楷体,arial","#f00",20);TextNodes.draw();//火箭Rockets.transform();Rockets.modify();Rockets.draw();//生命值Hearts.modify();Hearts.draw();}else Game.over();},hit:function(event){event = (event)?event:window.event;if(event.keyCode==32)//暂停开始if(Game.flag){Game.flag=false;window.cancelAnimationFrame(Game.animationID);}else{Game.flag=true;requestAnimationFrame(Game.transform);}else if(event.keyCode>=65&&event.keyCode<=90)//打击火箭Rockets.loopHit(String.fromCharCode(event.keyCode));},over:function(){window.removeEventListener("keyup",Game.hit);Background.draw("#000");TextNodes.setup("Game Over!",100,120,"96px 楷体,arial","#f00");TextNodes.draw();TextNodes.setup("Click anywhere to retry!",120,200,"48px 楷体,arial","#f00");TextNodes.draw();TextNodes.setup("Score:"+score,240,320,"90px 楷体,arial","#f00");TextNodes.draw();TextNodes.setup("Extra hearts:"+extraHearts,120,420,"42px 楷体,arial","#f00",25);TextNodes.draw();TextNodes.setup("Total rockets:"+rocketsNum,120,500,"42px 楷体,arial","#f00",25);TextNodes.draw();window.addEventListener("click",Game.restart);},restart:function(){window.removeEventListener("click",Game.restart);//initheartsNum=5;extraHearts=0;rocketsNum=5;score=0;Game.begin();}}//绘制背景//有传入绘制样式,则使用该样式,否则使用默认样式,垂直加深灰色渐变var Background={draw:function(fillStyle){if(fillStyle)ctx.fillStyle=fillStyle;else{var grd=ctx.createLinearGradient(0,0,0,canvas_height);grd.addColorStop(0,"#ccc");grd.addColorStop(1,"#777");ctx.fillStyle=grd;}ctx.fillRect(0,0,canvas_width,canvas_height);}}//绘制生命值var Heart=function(x,y){//不能初始化var x,y,radius;this.x=x;this.y=y;this.radius=20;this.draw=function(){ctx.beginPath();ctx.arc(this.x,this.y,this.radius,0,2*Math.PI);ctx.closePath();var grd=ctx.createRadialGradient(this.x,this.y,0,this.x,this.y,this.radius);grd.addColorStop(1,"#f00");grd.addColorStop(0,"#fff");ctx.fillStyle=grd;ctx.fill();}}//管理生命值的初始化和数量变化var Hearts={hearts:null,x:50,y:40,offSetX:50,init:function(){this.hearts=new Array();for(var i=0;i<heartsNum;i++)//按水平偏移排列生命值this.hearts[i]=new Heart(this.x+i*this.offSetX,this.y);},modify:function(){//修改生命值数量if(heartsNum<this.hearts.length)for(var i=heartsNum;i<this.hearts.length;i++)this.hearts[i]=null;else for(var i=this.hearts.length;i<heartsNum;i++)this.hearts[i]=new Heart(this.x+i*this.offSetX,this.y);},draw:function(){for(var i=0;i<this.hearts.length;i++)this.hearts[i].draw();}}var Rocket=function(scale){var str="ABCDEFGHIJKLMNOPQRSTUVWSYZ";var x,y,scale,letter,speed,fontColor;this.init=function(scale){this.x=Math.random()*(canvas_width-20)+10;this.y=Math.random()*canvas_height/5*2;this.scale=scale;//随机生成火箭体上的字母this.letter=str[Math.floor(Math.random()*26)];this.speed=Math.random()*2+1;this.fontColor="#000";}this.init(scale);this.draw=function(){ctx.save();ctx.translate(this.x,this.y);ctx.scale(this.scale,this.scale);//火箭火焰ctx.beginPath();ctx.moveTo(0,-80);ctx.lineTo(-25,0);ctx.lineTo(-10,30);ctx.lineTo(10,30);ctx.lineTo(25,0);ctx.closePath();var fire=ctx.createLinearGradient(-25,0,25,0);fire.addColorStop(0.2,"#f00");fire.addColorStop(0.5,"#f80");fire.addColorStop(0.8,"#f00");ctx.fillStyle=fire;ctx.fill();//火箭身体ctx.beginPath();ctx.moveTo(-10,30);ctx.lineTo(-30,160);ctx.lineTo(0,200);ctx.lineTo(30,160);ctx.lineTo(10,30);ctx.closePath();var body=ctx.createLinearGradient(-30,0,30,0);body.addColorStop(0.01,"#fff");body.addColorStop(0.5,"#00f");body.addColorStop(0.99,"#fff");ctx.fillStyle=body;ctx.fill();//火箭窗户ctx.fillStyle="#ade";ctx.fillRect(-10,150,12,20);//火箭文字ctx.fillStyle=this.fontColor;ctx.font="42px bold 楷体,arial";ctx.fillText(this.letter,-12,120);ctx.restore();}this.hit=function(key){//判断是否击中火箭//若击中,分数+1,重置火箭if(this.letter==key){score++;//每击中10个火箭,生命值+1,上限为8,火箭数+1,无上限if(score%10==0&&heartsNum<8){heartsNum++;extraHearts++;rocketsNum++;}//击中时重置火箭属性this.init(this.scale);return true;}return false;}this.move=function(){//火箭没有被击落,重置火箭属性,生命值-1if(this.y>=canvas_height){this.init(this.scale);heartsNum--;}//即将超出屏幕范围的时候,进行预警,火箭体上的字母变为红色else if(this.y>canvas_height/7*5)this.fontColor="#f00";this.y+=this.speed;}}//管理火箭的初始化,数量变化,运动var Rockets={rockets:null,scale:0.4,//控制火箭的大小init:function(){this.rockets=new Array();for(var i=0;i<rocketsNum;i++)this.rockets[i]=new Rocket(this.scale);},draw:function(){for(var i=0;i<this.rockets.length;i++)this.rockets[i].draw();},transform:function(){for(var i=0;i<this.rockets.length;i++)this.rockets[i].move();},modify:function(){//修改火箭数量for(var i=this.rockets.length;i<rocketsNum;i++)this.rockets[i]=new Rocket(this.scale);},loopHit:function(key){for(var i=0;i<this.rockets.length;i++)if(this.rockets[i].hit(key))//如果击中火箭,退出循环break;}}//绘制文本的单个字符var TextNode=function(txt,x,y){var txt,x,y;this.txt=txt;this.x=x;this.y=y;this.setup=function(txt,x,y){this.txt=txt;this.x=x;this.y=y;}this.draw=function(){ctx.fillText(this.txt,this.x,this.y);}}//管理字符串属性的变化和绘制var TextNodes={nodes:null,x:100,y:200,offSetX:60,font:"96px 楷体,arial",fillStyle:"#000",setup:function(txt,x,y,font,fillStyle,offSetX){this.x=x;this.y=y;this.font=font;this.fillStyle=fillStyle;//可选参数,字符的偏移this.offSetX=offSetX?offSetX:(canvas_width-2*x)/txt.length;this.nodes=new Array();for(var i=0;i<txt.length;i++)this.nodes[i]=new TextNode(txt[i],this.x+i*this.offSetX,this.y);},draw:function(){ctx.font=this.font;ctx.fillStyle=this.fillStyle;for(var i=0;i<this.nodes.length;i++)this.nodes[i].draw();}}var start=function(){document.getElementById("ins").style.display="none";Game.begin();window.removeEventListener("click",start);}//点击介绍,开始游戏window.addEventListener("click",start);};
“怎么用h5实现打火箭小游戏”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!