javascript实现俄罗斯方块游戏的思路和方法


Posted in Javascript onApril 27, 2015

观摩一下《编程之美》:“程序虽然很难写,却很美妙。要想把程序写好,需要写好一定的基础知识,包括编程语言、数据结构与算法。程序写得好,需要缜密的逻辑思维能力和良好的梳理基础,而且熟悉编程环境和编程工具。”

学了几年的计算机,你有没有爱上编程。话说,没有尝试自己写过一个游戏,算不上热爱编程。

俄罗斯方块曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事,它看似简单但却变化无穷,令人上瘾。相信大多数同学,曾经为它痴迷得茶不思饭不想。

游戏规则

1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。

2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。

javascript实现俄罗斯方块游戏的思路和方法

I:一次最多消除四层

J(左右):最多消除三层,或消除二层

L:最多消除三层,或消除二层

O:消除一至二层

S(左右):最多二层,容易造成孔洞

Z (左右):最多二层,容易造成孔洞

T:最多二层

方块会从区域上方开始缓慢继续落下。玩家可以以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。

分析与解法

每块方块落下的过程中,我们可以做:

1)旋转到合适的方向

2)水平移动到某一列

3)垂直下落到底部

首先,需要用一个二维数组,area[18][10]表示18*10的游戏区域。其中,数组中值为0表示空,1表示有方块。

方块一共7种,每种有4种方向。定义activeBlock[4],在编译之前这个数组的值预定算好,在程序中直接使用。

难点

1)边界检查。

//检查左边界,尝试着朝左边移动一个,看是否合法。
function checkLeftBorder(){ 
  for(var i=0; i<activeBlock.length; i++){ 
    if(activeBlock[i].y==0){ 
      return false; 
    } 
    if(!isCellValid(activeBlock[i].x, activeBlock[i].y-1)){ 
      return false; 
    } 
  } 
  return true; 
} //同理,需要检测右边界和底边界

2)旋转, 需要数理逻辑, 一个点相对另外一个点旋转90度的问题。
3)定时和监听键盘事件机制让游戏自动运行下去。

//开始 
function begin(e){ 
  e.disabled = true; 
  status = 1; 
  tbl = document.getElementById("area"); 
  if(!generateBlock()){ 
    alert("Game over!"); 
    status = 2; 
    return; 
  } 
  paint(); 
  timer = setInterval(moveDown,1000); 
} 
document.onkeydown=keyControl;

程序过程

1)用户点开始->构造一个活动图形, 设置定时器。

//当前活动的方块, 它可以左右下移动, 变型。当它触底后, 将会更新area; 
var activeBlock; 
//生产方块形状, 有7种基本形状。 
function generateBlock(){ 
  activeBlock = null; 
  activeBlock = new Array(4); 
  //随机产生0-6数组,代表7种形态。
  var t = (Math.floor(Math.random()*20)+1)%7; 
  switch(t){ 
    case 0:{ 
      activeBlock[0] = {x:0, y:4}; 
      activeBlock[1] = {x:1, y:4}; 
      activeBlock[2] = {x:0, y:5}; 
      activeBlock[3] = {x:1, y:5}; 

      break; 
    } 
    //省略部分代码..............................
    case 6:{ 
      activeBlock[0] = {x:0, y:5}; 
      activeBlock[1] = {x:1, y:4}; 
      activeBlock[2] = {x:1, y:5}; 
      activeBlock[3] = {x:1, y:6}; 
      break; 
    } 
  } 
  //检查刚生产的四个小方格是否可以放在初始化的位置. 
  for(var i=0; i<4; i++){ 
    if(!isCellValid(activeBlock[i].x, activeBlock[i].y)){ 
        return false; 
      } 
    } 
  return true; 
}

2)每次向下移动后, 都检查是否触底, 如果触底了, 则尝试消行。

//消行 
function deleteLine(){ 
  var lines = 0; 
  for(var i=0; i<18; i++){ 
    var j=0; 
    for(; j<10; j++){ 
      if(area[i][j]==0){ 
        break; 
    } 
  } 
  if(j==10){ 
    lines++; 
    if(i!=0){ 
      for(var k=i-1; k>=0; k--){ 
        area[k+1] = area[k]; 
      } 
    } 
    area[0] = generateBlankLine(); 
    } 
  } 
  return lines; 
}

3)完了之后再构造一个活动图形, 再设置定时器。

效果图

javascript实现俄罗斯方块游戏的思路和方法

javascript实现俄罗斯方块游戏的思路和方法

javascript实现俄罗斯方块游戏的思路和方法

有待优化

1)设置不同形状方块的颜色。

思路:在创建方块函数内,设定activeBlockColor颜色,七种不同形态方块颜色各异(除了修改generateBlock方法之外,还需要修改paintarea方法。因为一开始考虑不周全,消除一行后,重绘方块的同时将颜色统一,因此可以考虑移除表格n行,然后在顶部增添n行,以保证没消除方块的完整性)。

2)当当前方块下落时,可以提前查看下一个方块。

思路:将generateBlock方法拆分成两部分,一部分用于随机尝试下一个方块,一部分用于缓存当前所要描绘的方块。当当前方块碰到底部被固定后,下一方块开始描绘,同时又再次随机产生新方块。如此反复。

以上所述就是本文给大家分享的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
JQuery 学习笔记 选择器之一
Jul 23 Javascript
js判断IE6/IE7/FF的代码[XMLHttpRequest]
Feb 16 Javascript
js 代码优化点滴记录
Feb 19 Javascript
jquery的ajax()函数传值中文乱码解决方法介绍
Nov 08 Javascript
轻松掌握JavaScript中介者模式
Aug 26 Javascript
easyui form validate总是返回false的原因及解决方法
Nov 07 Javascript
ReactNative Image组件使用详解
Aug 07 Javascript
JS实现520 表白简单代码
May 21 Javascript
js实现鼠标拖拽缩放div实例代码
Mar 25 Javascript
微信小程序页面渲染实现方法
Nov 06 Javascript
node.js中path路径模块的使用方法实例分析
Feb 13 Javascript
vue+vant使用图片预览功能ImagePreview的问题解决
Apr 10 Javascript
JQuery记住用户名密码实现下次自动登录功能
Apr 27 #Javascript
JavaScript使用cookie实现记住账号密码功能
Apr 27 #Javascript
使用console进行性能测试
Apr 27 #Javascript
浅谈javascript实现八大排序
Apr 27 #Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
Apr 27 #Javascript
jQuery插件Tmpl的简单使用方法
Apr 27 #Javascript
javascript关于运动的各种问题经典总结
Apr 27 #Javascript
You might like
joomla内置的表单验证功能使用方法
2010/06/11 PHP
php长字符串定义方法
2012/07/12 PHP
php引用计数器进行垃圾收集机制介绍
2012/09/19 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
PHP判断远程图片或文件是否存在的实现代码
2014/02/20 PHP
浅谈PHP中Stream(流)
2015/06/08 PHP
PHP操作FTP类 (上传、下载、移动、创建等)
2016/03/31 PHP
PHP缩略图生成和图片水印制作
2017/01/07 PHP
PHP简单实现防止SQL注入的方法
2018/03/13 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
浅析javascript中function 的 length 属性
2014/05/27 Javascript
Node.js中安全调用系统命令的方法(避免注入安全漏洞)
2014/12/05 Javascript
AngularJS入门教程之Select(选择框)详解
2016/07/27 Javascript
JS中关于事件处理函数名后面是否带括号的问题
2016/11/16 Javascript
js微信支付实现代码
2016/12/22 Javascript
JavaScript遍历数组和对象的元素简单操作示例
2019/07/09 Javascript
前端vue如何使用高德地图
2020/11/05 Javascript
[02:17]快乐加倍!DOTA2食人魔魔法师至宝+迎霜节活动上线
2019/12/22 DOTA
Python读写Excel文件方法介绍
2014/11/22 Python
python使用tensorflow保存、加载和使用模型的方法
2018/01/31 Python
Python面向对象之类的内置attr属性示例
2018/12/14 Python
Python OpenCV实现测量图片物体宽度
2020/05/27 Python
魔幻般冒泡背景的CSS3按钮动画
2016/02/27 HTML / CSS
HTML5调用手机摄像头拍照的实现思路及代码
2014/06/15 HTML / CSS
西雅图的买手店:Totokaelo
2019/10/19 全球购物
写出SQL四条最基本的数据操作语句(DML)
2012/12/12 面试题
如何在.net Winform里面显示PDF文档
2012/09/11 面试题
社区十八大感言
2014/01/19 职场文书
生日寿宴答谢词
2014/01/19 职场文书
毕业生自荐书
2014/02/02 职场文书
国际贸易专业个人职业生涯规划
2014/02/15 职场文书
《千年梦圆在今朝》教学反思
2014/02/24 职场文书
Go语言 go程释放操作(退出/销毁)
2021/04/30 Golang
一劳永逸彻底解决pip install慢的办法
2021/05/24 Python
vue自定义右键菜单之全局实现
2022/04/09 Vue.js
MySQL事务的ACID特性以及并发问题方案
2022/07/15 MySQL