html5如何实现俄罗斯方块小游戏

html5如何实现俄罗斯方块小游戏

这篇文章将为大家详细讲解有关html5如何实现俄罗斯方块小游戏,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

制作思路

因为书里的俄罗斯方块比较普通,太常规了,不是很好看,所以我在网上找了上面那张图片,打算照着它来做。

然后便是游戏界面和常规的俄罗斯方块游戏逻辑。

接着便是游戏结束界面了。

原本想做个弹出层,但觉得找图片有点麻烦,所以就在网上找了文字特效,套用了一下。

代码实现:

首先是html文件和css文件,主要涉及了布局方面。作为新手,在上面真的是翻来覆去的踩坑。o(╥﹏╥)o

index.html:

俄罗斯方块/*导入外部的字体文件*/@font-face{font-family:tmb;/*为字体命名为tmb*/src:url("DS-DIGIB.TTF")format("TrueType");/*format为字体文件格式,TrueType为ttf*/}div>span{font-family:tmb;font-size:18pt;color:green;}

速度:1
当前分数:0
最高分数:0

teris.css

*{margin:0;padding:0;}html,body{width:100%;height:100%;}.bg{font-size:13pt;background-color:rgb(239,239,227);/*好看的渐变色*/background-image:radial-gradient(rgb(239,239,227),rgb(230,220,212));/*阴影*/box-shadow:#cdc8c1-1px-1px7px0px;padding-bottom:4px;}.ui_bg{border-bottom:1px#a69e9ea3solid;padding-bottom:2px;overflow:hidden;/*没有这句的话因为子div都设置了float,所以是浮在网页上的,所以父div就没有高度,这句清除了浮动,让父div有了子div的高度*/}

然后是重头戏,teris.js

游戏变量:

//游戏设定varTETRIS_ROWS=20;varTETRIS_COLS=14;varCELL_SIZE=24;varNO_BLOCK=0;varHAVE_BLOCK=1;//定义几种可能出现的方块组合varblockArr=[//Z[{x:TETRIS_COLS/2-1,y:0},{x:TETRIS_COLS/2,y:0},{x:TETRIS_COLS/2,y:1},{x:TETRIS_COLS/2+1,y:1}],//反Z[{x:TETRIS_COLS/2+1,y:0},{x:TETRIS_COLS/2,y:0},{x:TETRIS_COLS/2,y:1},{x:TETRIS_COLS/2-1,y:1}],//田[{x:TETRIS_COLS/2-1,y:0},{x:TETRIS_COLS/2,y:0},{x:TETRIS_COLS/2-1,y:1},{x:TETRIS_COLS/2,y:1}],//L[{x:TETRIS_COLS/2-1,y:0},{x:TETRIS_COLS/2-1,y:1},{x:TETRIS_COLS/2-1,y:2},{x:TETRIS_COLS/2,y:2}],//J[{x:TETRIS_COLS/2,y:0},{x:TETRIS_COLS/2,y:1},{x:TETRIS_COLS/2,y:2},{x:TETRIS_COLS/2-1,y:2}],//□□□□[{x:TETRIS_COLS/2,y:0},{x:TETRIS_COLS/2,y:1},{x:TETRIS_COLS/2,y:2},{x:TETRIS_COLS/2,y:3}],//┴[{x:TETRIS_COLS/2,y:0},{x:TETRIS_COLS/2-1,y:1},{x:TETRIS_COLS/2,y:1},{x:TETRIS_COLS/2+1,y:1}]];//记录当前积分varcurScore=0;//记录曾经的最高积分varmaxScore=1;varcurSpeed=1;//ui元素varcurSpeedEle=document.getElementById("cur_speed");varcurScoreEle=document.getElementById("cur_points");varmaxScoreEle=document.getElementById("max_points");vartimer;//方块下落控制varmyCanvas;varcanvasCtx;vartetris_status;//地图数据varcurrentFall;//当前下落的block

游戏界面的完善

//createcanvasfunctioncreateCanvas(){myCanvas=document.createElement("canvas");myCanvas.width=TETRIS_COLS*CELL_SIZE;myCanvas.height=TETRIS_ROWS*CELL_SIZE;//绘制背景canvasCtx=myCanvas.getContext("2d");canvasCtx.beginPath();//TETRIS_COSfor(leti=1;i

游戏逻辑

functionrotate(){//定义记录能否旋转的旗标varcanRotate=true;for(vari=0;i=TETRIS_COLS-1||tetris_status[afterRotateY][afterRotateX+1]!=NO_BLOCK){moveLeft();afterRotateX=currentFall[2].x+preY-currentFall[2].y;afterRotateY=currentFall[2].y+currentFall[2].x-preX;break;}if(afterRotateX>=TETRIS_COLS-1||tetris_status[afterRotateY][afterRotateX+1]!=NO_BLOCK){moveLeft();break;}}}if(canRotate){for(vari=0;i0;i--){for(letj=0;jmaxScore){//超越最高分maxScore=curScore;localStorage.setItem("maxScore",maxScore);}//加速curSpeed+=0.1;localStorage.setItem("curSpeed",curSpeed);//ui输出curScoreEle.innerHTML=""+curScore;maxScoreEle.innerHTML=""+maxScore;curSpeedEle.innerHTML=curSpeed.toFixed(1);//保留两位小数clearInterval(timer);timer=setInterval(function(){next();},500/curSpeed);}}}//判断是否触顶for(leti=0;i=TETRIS_ROWS||tetris_status[currentFall[i].y][currentFall[i].x+1]!=NO_BLOCK)return;}for(leti=0;i=TETRIS_ROWS-1||tetris_status[currentFall[i].y+1][currentFall[i].x]!=NO_BLOCK)returntrue;}for(leti=0;i

keydown事件监听

其他的详细情况可以看源代码,我就不整理了。

接下来我们看游戏结束时的特效。因为我也不是很懂,所以在这里整理的会比较详细。当做学习。

//gameendfunctiongameEnd(){clearInterval(timer);//键盘输入监听结束window.onkeydown=function(){//按任意键重新开始游戏window.onkeydown=gameKeyEvent;//初始化游戏数据initData();createBlock();localStorage.setItem("currentFall",JSON.stringify(currentFall));localStorage.setItem("tetris_status",JSON.stringify(tetris_status));localStorage.setItem("curScore",curScore);localStorage.setItem("curSpeed",curSpeed);//绘制curScoreEle.innerHTML=""+curScore;curSpeedEle.innerHTML=curSpeed.toFixed(1);//保留两位小数drawBlocks();timer=setInterval(function(){next();},500/curSpeed);//清除特效this.stage.removeAllChildren();this.textStage.removeAllChildren();};//特效,游戏结束setTimeout(function(){initAnim();//擦除黑色方块for(leti=0;i

上面代码里的localstorage是html5的本地数据存储。因为不是运用很难,所以具体看代码。

整个特效是运用了createjs插件。要引入几个文件。

easeljs-0.7.1.min.js,EasePacj.min.js,requestAnimationFrame.js和TweenLite.min.js 游戏重新开始就要清除特效。我看api里我第一眼望过去最明显的就是removeAllChildren(),所以就选了这个。其他的改进日后再说。

//清除特效this.stage.removeAllChildren();this.textStage.removeAllChildren();functioninitAnim(){initStages();initText();initCircles();//在stage下方添加文字——按任意键重新开始游戏.tmp=newcreatejs.Text("t","12px'SourceSansPro'","#54555C");tmp.textAlign='center';tmp.x=180;tmp.y=350;tmp.text="按任意键重新开始游戏";stage.addChild(tmp);animate();}initAnim

上面初始化了一个stage,用于存放特效,一个textstage,用于形成“FAILED”的像素图片。还有一个按任意键重新游戏的提示。同时开始每隔一段时间就刷新stage。

根据block的位置来初始化小圆点。

functioninitCircles(){circles=[];varp=[];varcount=0;for(leti=0;i=p.length)count=0;varcolor=colors[Math.floor(i%colors.length)];varalpha=0.2+Math.random()*0.5;circle.alpha=alpha;circle.radius=r;circle.graphics.beginFill(color).drawCircle(0,0,r);circle.x=x;circle.y=y;circles.push(circle);stage.addChild(circle);circle.movement='float';tweenCircle(circle);}}initCircles

然后再讲显示特效Failed的createText()。先将FAILED的text显示在textstage里,然后ctx.getImageData.data获取像素数据,并以此来为每个小圆点定义位置。

functioncreateText(t){curText=t;varfontSize=500/(t.length);if(fontSize>80)fontSize=80;text.text=t;text.font="900"+fontSize+"px'SourceSansPro'";text.textAlign='center';text.x=TETRIS_COLS*CELL_SIZE/2;text.y=0;textStage.addChild(text);textStage.update();varctx=document.getElementById('text').getContext('2d');varpix=ctx.getImageData(0,0,600,200).data;textPixels=[];for(vari=pix.length;i>=0;i-=4){if(pix[i]!=0){varx=(i/4)%600;vary=Math.floor(Math.floor(i/600)/4);if((x&&x%8==0)&&(y&&y%8==0))textPixels.push({x:x,y:y});}}formText();textStage.clear();//清楚text的显示}CreateText

跟着代码的节奏走,我们现在来到了formtext.

functionformText(){for(vari=0,l=textPixels.length;i

explode()就是讲已组成字的小圆点给重新遣散。

动画实现是使用了tweenlite.

functiontweenCircle(c,dir){if(c.tween)c.tween.kill();if(dir=='in'){/*TweenLite.to改变c实例的x坐标,y坐标,使用easeInOut弹性函数,透明度提到1,改变大小,radius,总用时0.4s*/c.tween=TweenLite.to(c,0.4,{x:c.originX,y:c.originY,ease:Quad.easeInOut,alpha:1,radius:5,scaleX:0.4,scaleY:0.4,onComplete:function(){c.movement='jiggle';/*轻摇*/tweenCircle(c);}});}elseif(dir=='out'){c.tween=TweenLite.to(c,0.8,{x:window.innerWidth*Math.random(),y:window.innerHeight*Math.random(),ease:Quad.easeInOut,alpha:0.2+Math.random()*0.5,scaleX:1,scaleY:1,onComplete:function(){c.movement='float';tweenCircle(c);}});}else{if(c.movement=='float'){c.tween=TweenLite.to(c,5+Math.random()*3.5,{x:c.x+-100+Math.random()*200,y:c.y+-100+Math.random()*200,ease:Quad.easeInOut,alpha:0.2+Math.random()*0.5,onComplete:function(){tweenCircle(c);}});}else{c.tween=TweenLite.to(c,0.05,{x:c.originX+Math.random()*3,y:c.originY+Math.random()*3,ease:Quad.easeInOut,onComplete:function(){tweenCircle(c);}});}}}

TweenLite.to函数第一个参数,要做动画的实例,第二个参数,事件,第三个参数,动画改变参数。

Quad.easeInOut()意思是在动画开始和结束时缓动。onComplete动画完成时调用的函数。易得,在我们的应用中,我们将开始下一次动画。

关于“html5如何实现俄罗斯方块小游戏”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

发布于 2022-03-18 22:50:51
分享
海报
28
上一篇:js如何删除数组的重复项 下一篇:在html5中表单验证特性的示例分析
目录

推荐阅读

忘记密码?

图形验证码