用scratch制作俄罗斯方块,html5俄罗斯方块

  用scratch制作俄罗斯方块,html5俄罗斯方块

  很久没用画布了,通过写“俄罗斯方块”这个小游戏又熟悉了一遍。如果我有一定的画布基础,实现起来并不难。

  原理详解

  查看游戏的最终界面,我们可以看到需要实现以下关键功能:

  游戏面板,即一个12 * 20的正方形,以及正方形信息是否填充;运动广场,广场需要实现运动和变形的功能。

  界面的实现

  整个面板就是以左上角(0,0)为原点,右上角(12,0),左下角(0,20),右下角(12,20)的坐标系。可以确定每个点的坐标位置。无论方块是否被填充,我们都可以把每个方块看作一个数组元素。0表示没有,1表示已经填充。12 * 20面板使用两层数组,即20个长度为12的数组。

  var maps=[[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,1,0,1,0],];画出面板的代码,用最基础的canvas api就可以实现。

  //grid for(var I=0;i12I){ for(var j=0;j20j ){ ctx.fillRect(i*40,j*40,40,40);ctx.strokeRect(i*40,j*40,40,40);If(this.maps[j][i]==1){//方块中已经有填充CTX . save();CTX . line width=4;ctx.fillStyle=hsla(200,100%,50%, 5);ctx.strokeStyle=hsla(200,100%,50%, 9);ctx.fillRect(i*40,j*40,40,40);ctx.strokeRect(i*40 2,j*40 2,38,38);CTX . restore();}}}//border ctx .线宽=4;ctx.strokeStyle=hsla(0,100%,0%, 3);ctx.moveTo(0,0);ctx.lineTo(0,20 * 40);ctx.lineTo(12*40,20 * 40);ctx.lineTo(12*40,0);CTX . stroke();CTX . restore();方块的实现

  游戏中使用了以下七种图形

  结合上面介绍的坐标系,数组[x1,y1,x2,y2,x3,y3,x4,y4]就是上图中四个点的坐标的数据表示。七个图形的坐标如下:

  var Arr=[[4,0,4,1,5,1,6,1],[4,1,5,1,6,1,6,0],[4,0,5,0,5,1,6,0],[5,0,4,1,5,1,6,1],[4,0,5,0,0,6,0,7,0],[5,0,6,0,0,5,1,6移动方块,遍历整个数组,加上位移向量,非常简单。

  class Shape { constructor(m){ this . m=object . assign([],m);} move(x,y){ //位移var m=this.m,l=m.lengthy=y 0;for(var I=0;il;I=I ^ 2){ m[I]=x;m[I 1]=y;}还这个;}正方形的旋转。在俄罗斯方块中,方块除了左右上下移动之外还会旋转,不是吗?你稍微想一想,就是矩阵变换而已,就是图形每次都是绕中心点旋转90度。这里我用数组的第三个点作为图形变换的中心点,并不完美。

  class Shape { transform(){///二维矩阵变换var m=this.m,l=m.length,c=math.ceil (l/2),x=m [c],y=m [c 1],cos=math . cos(math.pi/180 *)。for(var I=0;il;I=I ^ 2){ if(I==c)继续;var mx=m[i]- x,my=m[i 1] - y,nx=mx*cos - my*sin,ny=my * cos mx * sinm[I]=x NX;m[I 1]=y ny;}还这个;}边界条件

  它主要包括以下三个方面

  正方形的位置不能超出界面的判断;方块到达底部或放置完成的判断;比赛结束的判断。遍历数组(1)。当任意一点的Y坐标为19时,到达底部。(2)获取坐标的y 1位置在地图中的信息。如果是1,说明已经填好了。在这两种情况下,当移动方块的循环结束时,只需将方块的坐标填入地图对应的数组中。

  如果坐标的y 1已经被填满,当前坐标小于1,也就是已经在界面顶部,那么游戏结束。

  var isEnd=false,isOver=false,x,y;for(var i=0,sl=shape。m .长度;islI=I ^ 2){ x=那个。形状。m[I];y=那个。形状。m[I 1];if(y=19){ //到了底部isEnd=真打破;} if(that.maps[y 1][x]==1){ //y 1位置已经填充isEnd=true if(y=1){ is over=true;} //游戏结束打破;}}方块运动周期结束时检测每一层是否满格,以及满格后的处理。某项数组全部元素都为一则表示已经满格,那么删除该项数组,同时列表头再压入一项每个元素都为0的数组即可。

  checkPoint(){ var that=this,maps=that.mapsfor(var i=0,l=maps.lengthili ){ if(Math.min.apply(null,maps[i])==1){//表示该层已经满格that.maps.splice(i,1);that.score=10//增加分数that.maps.unshift([0,0,0,0,0,0,0,0]);} }还这个;}绑定事件

  主要就是绑定按键事件,要注意的是左移和右移事件包括了边界判断

  bind event(){ var that=this;文档。addevent listener( keydown ,function(e){ switch(e . key code){ case 13://enter cancelAnimationFrame(that。定时器);that.init().update();打破;案例80: //p that.pause=!暂停;打破;案例40://顺着那个。d=0.5打破;案例37: //left var over=false,maps=that.maps,shape=that.shape,m=shape.mfor(var i=0,l=m.lengthilI=I 2){ if(m[I]=0 maps[m[I 1]][m[I]-1]==1){ over=true;打破;} }如果(!over) shape.move(-1,0);打破;案例39: //right var over=false,shape=that.shape,maps=that.maps,m=shape.mfor(var i=0,l=m.lengthilI=I 2){ if(m[I]=11 maps[m[I 1]][m[I]1]==1){ over=true;打破;} }如果(!over) shape.move(1,0);打破;案例32://空格表示。形状。transform();打破;} },假);}总结

  这里面实现了俄罗斯方块的最基本功能,还有关卡等功能点并没有实现,同时该演示仍然有不完善的地方需要修正。

  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: