大家都知道俄罗斯方块是一款大众化的游戏了,我很小的时候就玩过,今年已经25岁了,可以说俄罗斯方块确实是历史悠久,做俄罗斯方块是我上个星期开始的想法。也许是由于自己从来没有写过这种东西吧,所以有生疏。代码的话,只完成了一小部分,大概1/5左右吧。今天还是决定先写一部分思路。

  至于俄罗斯方块的话,有很多的难点,如果有JS去写的话,要考虑到碰撞啊,边界啊,下落等问题,本文这些问题大部分不会考虑到,只是提供一部分思路而已,开始已经说了,因为自己还没写完这个游戏,但是又出于想写博客记录,所以才有了这一系列的博客。

  回到正题,我们首先想一想,俄罗斯方块需要什么?我做一个简单的归纳。如果我简单点说的话,就是一个俄罗斯方块对象,那么这个对象里又有些什么东西呢?我们可以想象一下,有一个平面直角坐标系,这个平面直角坐标系有X轴,有Y轴,也有“每一等分”的距离(unit),而俄罗斯方块就是一个一个的“格子”,这些格子从某一个地方开始下落,某一个地方停止下落,于是我们就规定了俄罗斯方块的“下落区域”(Area)。但是下落是一个“动作”,所以我们还要有一个类(这里定义为operate),来控制动作的下落。

  好了,先就介绍到这里,我们再来做一段代码性质的归纳,表示对上面的代码做一段归纳。

/*俄罗斯方块实体类*/
function Tetris()
{var self =this; //自身this.area=null;//区域this.operate=null; //操作/*初始化X,Y,单元为5或者20*/this.x=5;this.y=5;this.unit=20;this.running=null; //是否在运行中//俄罗斯方块实体IDthis.id="tempid";//开始游戏this.start=function(){this.area=new getArea(this.x,this.y,this.unit,"tempid"); //获得Area对象   ,其中TEMPID是俄罗斯方块实体类IDthis.operate=new OperateTetris(this.area,self);//是否替换俄罗斯方块if(this.operate.mayPlace()){//alert(1);this.operate.place(); }}  //开始游戏document.getElementById("startGame").οnclick=function(){self.start()};
}

  那么,当我们点击StartGame的时候,开始游戏,即运行start()方法。好,我们现在开始考虑Area对象里面到底需要什么东西 function getArea(x,y,unit,id)参数需要带入4个,前面3个刚才已经说了,第四个参数就是Area的ID。我们需要area这个对象,所以通过HTML代码来设置ID。大家玩过俄罗斯方块的都知道,每一次触底,都会新加一个元素,而新的元素是“随机”的,每当一行是满的(这里不考虑颜色不同的情况),就会消掉一行,当然我们一次形成了多行可消掉的方块的时候,那么我们就可以消掉多行。下面的是代码,算是对上面的文字的一个小小的总结,还没有完成的代码。

//获得区域的横坐标和纵坐标
function getArea(x,y,unit,id)
{this.x=x;this.y=y;this.unit=unit; //每个单元的大小,单位为像素this.el=document.getElementById(id); //得到ID对象this.board=[]; //面板,即在区域范围内的元素(俄罗斯方块)//添加元素this.addElement=function(){//得到起始元素的X开始坐标和Y开始坐标的位置(错误)//得到X坐标的下落次数,和Y轴的左右移动的次数var xBegin=parseInt(el.offsetLeft/unit);    var yBegin=parseInt(el.offsetTop/unit);if(xBegin>=0&&xBegin<=this.x&&yBegin>=0&&yBegin<=this.y){board[yBegin][xBegin]=el; //确定元素的位置}}//消掉所有的行this.removeFullLines=function(){var lines=0;for(var i=this.y-1;y>0;y--){if(this.linesRelated(y)){lines++;this.y++;}}   }//和线性有关的东西(判断是否满了)this.linesRelated=function(y){for(var x=this.x;x>0;x--){this.removeLines(y);if(this.board[y][x]){return false;}    //不明觉厉}return true;};//去掉行this.removeLines=function(y){for(var x=0;x<this.x;x++){this.el.removeChild(this.board[y][x]);this.board[y][x]=0; }y--;for(;y>0;y--){/*今天暂时写到这里*/  }};
}

  需要注意的一点是,俄罗斯方块是“二维性质”的,所以我这里定义了一个board类型的二维数组,即board[行][列](board[y][x]).好了,这里我们当然还需要一个类,这个类就是控制元素下落的“动作”的类,那么这个下落“动作“的类里应该有一些什么东西呢?我们需要考虑边界,于是有了(区域),我们要考虑俄罗斯方块于是有了俄罗斯方块对象(tetris),因为方块的种类不同,有各种不同的形状于是我们必须考虑方块的类别(types),还有下一个类别(NEXTTYPE),因为方块有下一个提示;我们需要考虑方块在AREA中的位置于是有了(position),我们需要判断游戏是否暂停于是有了running,当然了,方块下落的速度SPEED肯定也是要考虑到的,如果GAME OVER了那么就要判断游戏是否停止stopped,当然了,方块是一个一个的元素于是我们要考虑elements,当然了,最重要的还是下落(falldown).下面是定义的代码:

  var self=this; //当前对象this.area=area;this.tetris=tetris;this.types=null; //方块的类型;this.nextType=null; //下一个类型//初始化X和Ythis.x=null;this.y=null;this.position=0; //初始位置this.board=[]; //用来填充HTML元素的this.elements=[];this.running=null; //是否在运行中this.stopped=null; //是否停止this.fallDownId=null; //往下掉落的this.speed=null; //速度

  这么一说有点头晕,我们选一个切入点吧,我们的切入点就是如何构造方块。大家应该知道俄罗斯方块的几种形状吧,比如T形,L形,口形等等,那么我们可以想象一下,把俄罗斯方块定义成一个二维数组,然后有元素的地方为1,没元素的地方为0来构造形状,如下面的代码:

 /*方块的组合方式,用数组进行组合(二维数组)用0,1表示是否有方块存在,如果是0:不存在,1:存在,以下的逻辑就可以非常的清楚了。*/this.blockComplex=[[[0,0,1],[1,1,1],[0,0,0]  //_|],[[1,0,0],[1,1,1],[0,0,0] //L],[[0,1,0],[1,1,1],[0,0,0]  //T],[[0,0,0],[1,1,1],[0,0,0] //--],[[0,0,0],[0,1,1],[0,1,1] //口],[[0,1,1],[0,1,0],[1,1,0] //Z]];

  好了,形状构造好之后,我们当然需要考虑程序的性能方面的问题,于是我创建了如下的GETTER方法,来判断是游戏是否在运行中等。

/*一连串的GETTER方法分别是速度,X,Y轴,运行和停止的GETTER方法*/this.getSpeed=function(){return this.speed;  }this.getX=function(){return this.x;   }this.getY=function(){return this.y;   }this.isRunning=function(){return this.running;    }this.isStopped=function(){return this.stopped;}

  当然了,我们如果要”重新开始游戏“,肯定是要建立一个方法reset(),说白一点,就是恢复游戏开始的状态。

   //重置(初始化)this.reset=function(){this.nextType=random(this.blockComplex.length);this.types=this.nextType;this.position=0;this.board=[];this.elements=[];this.x=null;this.y=null;}

  如果这个俄罗斯方法触底的话,那么肯定是会触发下一个俄罗斯方块的开始于是我们这里肯定要有一个方法, 内容我还没想好,就给一个架子吧。我直接返回TRUE了。

   this.mayPlace=function(){return true;}

  下面的是最重要的方法,就是我们的替换方块的方法。先来简单做一个介绍,我也不知道自己能不能讲好,大家想想在一个坐标系中,方块如果下落了,肯定是Y--,毕竟方块是向下方下落的,当然,我们还需要有线条,假设我们一直在堆方块的话,这个线肯定是会增加的,还有我们的方块本身就是DIV,肯定是一个掉落DIV的过程,而这些DIV,肯定是在AREA范围内的。我们不妨想一想,第一步,我们来创建一个空的BOARD,就是面板,然后往这个面板里面填充东西呢?

 //创建空对象,即所有的都为0的对象,并返回对象this.createEmpty=function(x,y){var elements=[];for(var y2=0;y2<y;y2++){elements.push(new Array());for(var x2=0;x2<x;x2++){elements[y2].push(0);   }}return elements;}

  我们如果想下落元素的话,肯定是要知道开始下落的坐标,当然Y轴肯定是0,X轴可以依据自己的喜好来设定。当然了,下落的DIV肯定是属于这个AREA下面的子元素的,所以我们等下肯定要把这个APPENDCHILD到这里面去。下面是代码:

    /*替换*/this.place=function(){//初始化var operate=this.blockComplex[this.types];//区域开始X轴的位置var AreaXStartPos=parseInt(this.area.x-operate[0].length);//区域开始Y轴的位置//var AreaYStartPos=parseInt(this.area.y-operate[0]);var AreaYStartPos=1; //因为X轴的位置可能变化,而Y轴总是从最上面下来的,所以是1this.x=AreaXStartPos; //把新的位置赋给X;this.y=AreaYStartPos; //把新的位置赋给y;//构建空对象,并存入BOARD/*y:行,x:列*///alert(operate[0].length+" "+operate.length);this.board=this.createEmpty(operate[0].length,operate.length);/*线条,往下掉落,初始化*/var lines=0;var foundLines=false;//循环遍历,先遍历行,每一行再来遍历列for(var yAxis=this.board.length-1;yAxis>=0;yAxis--){for(var xAxis=0;xAxis<=this.blockComplex[yAxis].length;xAxis++){if(this.blockComplex[yAxis][xAxis]){var el=document.createElement("div");el.className="block"+this.types; //确定这个元素的CLASSNAME  //确定左边距和上边距el.style.left=(this.x+xAxis)*this.area.unit+"px";el.style.top=(this.y+yAxis)*this.area.unit+"px";this.area.el.appendChild(el); //这个EL去APPEND主要的EL。this.board[yAxis][xAxis]=el;this.elements.push(el); //推入elements中}}/*个人感觉这个功能应该是加速往下掉落的方法?不明觉厉*/if(lines){yAxis--;   }if(foundLines){lines++; }}

  需要注意的是,当下一个俄罗斯方块(随机)的形成是随机的,所以我们需要定义一个RANDOM方法。其实每次下落都是一个RESET的循环,只是游戏还没有结束而已。

//随机数,产生1~6的
function random(i)
{return Math.floor(Math.random()*i);
}

  好了,今天只介绍一个思路,当然了,我也没写出来这个游戏,等下一篇出来的时候应该游戏会有一个大的架子了,还有一些代码我都不好意思放出来了,写得太差了。其实这个俄罗斯方块不完全是我自己写的,我也参考了下别人的东西,但不是抄袭,我想通过自己的努力,做一个游戏出来,这是我多年的梦想,努力!

  至于全部的代码我就不贴了,因为还没写完,只是对这几天写代码的一个总结而已,高手可以无视我写的代码。

用纯JS做俄罗斯方块 - 简要思路介绍(1)相关推荐

  1. 纯js实现俄罗斯方块详解与源码

    对于小白来说用js实现俄罗斯方块还是有难度的,网上找了很多代码看,有的很长难懂,有的短小精悍,但不只用到了js还用到了框架,对于还未接触框架的小白宝宝,也只能无奈自己是小白了,自己写不出来那就找一篇纯 ...

  2. php 写一个大富翁游戏,抽奖系列:如何用纯js做一个大富翁游戏

    话不多说,先上效果图: 功能点: 礼品的位置 小怪兽位置的变化(走路.转身和回退) 小怪兽的跳跃弧度 确定好功能点,接下来就是逐个击破: 1.渲染奖品 获取奖品数据后,建一个数组存放奖品的位置,通过遍 ...

  3. 如何用纯js做一个大富翁游戏

    下面这张是效果图: 先立个flag,一个星期内把这个坑填了 今天7月1号,建党节,在这个伟大的节日,我来填坑了. 这个游戏有以下几个难点: 1.礼品的位置 2.小怪兽位置的变化(走路.转身和回退) 3 ...

  4. qt web混合编程_QT做界面真是绝美,并且还可嵌入HTML与JS做界面(许多案例)

    1. 这年头想要酷炫, 还是用web最方便, QT自带嵌入式webkit, 然后用d3.js D3.js - Data-Driven Documents什么的, 各种酷炫的互动表随手而来. 这里有各种 ...

  5. java 前台播放视频_「纯js项目」海康视频项目,java后台+前台web显示的,望提供思路!...

    纯js项目: 海康视频项目,java后台+前台web显示的,望提供思路! 如果只是实现BS架构,可以向海康要web开发包,直接使用浏览器通过ocx访问海康设备浏览视频,如果需要的功能不全,再使用JNI ...

  6. KingPager,自己做的分页控件,纯JS,支持所有语言

    效果图如下: 简介: 1.JQuery分页控件,纯JS,支持任何语言 2.全部样式可通过CSS自定义(默认的就很好看) 3.非常灵活,1行代码即可实现分页 调用示例: <html xmlns=& ...

  7. 纯js实现html转pdf

    项目开发中遇到了一个变态需求,需要把一整个页面导出为pdf格式,而且要保留页面上的所有的表格.svg图片和样式. 简而言之,就是希望像截图一样,把整个页面截下来,然后保存成pdf. 咋不上天呢-- 查 ...

  8. js纯ajax,自动完成JS类(纯JS, Ajax模式)

    自动完成JS类(纯JS, Ajax模式) 更新时间:2009年03月12日 23:51:15   作者: 自动完成JS类,用户体验较好.封装成类,方便使用.本站 一. 封装的JS文件 //****** ...

  9. 纯js实现瀑布流布局及ajax动态新增数据

    本文用纯js代码手写一个瀑布流网页效果,初步实现一个基本的瀑布流布局,以及滚动到底部后模拟ajax数据加载新图片功能. 缺点: 1. 程序不是响应式,不能实时调整页面宽度: 2. 程序中当新增ajax ...

最新文章

  1. 【MySQL】面试官:如何添加新数据库到MySQL主从复制环境?
  2. 病案编码员需要计算机的什么知识,前辈分享:优秀编码员必须经历的成长过程,你到哪一级了?...
  3. Scrum 项目7.0
  4. python怎么安装xlrd库_Python第三方库xlrd/xlwt的安装与读写Excel表格
  5. 分区怎么4k对齐_电脑升级SSD后,依然卡顿怎么解决?
  6. K8S认证、授权与准入控制(RBAC)详解
  7. Unity Ragdoll 实现死亡效果 心得+坑点总结
  8. 解决GLIDE4.0和圆角裁剪CENTERCROP冲突
  9. 使用腾讯云短信SDK发送验证码
  10. tcp 抓包出现spurious retransmission
  11. python绘制聚类树状图
  12. 总结谷歌身份验证器 Google Authenticator 的详细使用方法
  13. 【高数】变上限积分的等价无穷小替换
  14. 使用Unity制作一个RPG游戏(1)
  15. matlab-高数 diff 求在(x0,y0)处偏导数 数值
  16. 23年教资面试开始啦个人报名流程
  17. mac常见问题(五) Mac 无法开机
  18. element表格固定表头
  19. for in 、for of详解
  20. 埃森哲全球“技术展望2018”报告解析(附下载链接)

热门文章

  1. 解读2018年诺贝尔化学奖成果:用进化的力量解决化学问题
  2. 一文读懂:深扒人脸识别60年技术发展史
  3. 学界 | DeepMind论文解读:通过删除神经元来了解深度学习
  4. Uber致人死亡或为自动驾驶肇事责任 没有判例可循
  5. Nature Human Behavior:大脑对不公平的反应有助预测抑郁症
  6. 从京东裸辞 2 年后,我的一些改变
  7. 45 岁,2 万亿身价,苹果的人生才刚刚开始
  8. 这可能是东半球最保姆级的后台服务器开发学习路线
  9. 10 年 bloger 教你如何优雅玩转博客!
  10. 连肝 7 个晚上,总结了 66 条计算机网络的知识点