HTML5 俄罗斯方块.doc_第1页
HTML5 俄罗斯方块.doc_第2页
HTML5 俄罗斯方块.doc_第3页
HTML5 俄罗斯方块.doc_第4页
HTML5 俄罗斯方块.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

html5 提供的 canvas 接口很强大.通过简单的绘制做了一个简版的俄罗斯方块。主要训练自身的 OOP 和 数据结构 设计。canvas 的接口上面写的很丰富。写的过程中,参考了很多网上的例子,最后觉得左洸博客的比较容易好懂。主要分为数据模型,游戏控制模型和工具函数。一 数据模型首先考虑的问题就是 方块到底是什么?绘制方块,就是canvas里绘制矩形,至少需要知道 矩形的起点,宽度和高度。因此,只要确定方块的坐标点,就能根据宽度高度绘制图形。通常,俄罗斯方块有几种 T L S | 等,每个形状都有一个 属于自己的坐标系。因此,所有图形的数据结构为:123456789101112131415161718192021222324/*数据模型*/各种形状的编号,0代表没有形状noShape = 0;zShape = 1;sShape = 2;lineShape = 3;tShape = 4;squareShape = 5;lShape = 6;mirroredLShape = 7;shapesData = 0, 0 , 0, 0 , 0, 0 , 0, 0 , 0, -1 , 0, 0 , -1, 0 , -1, 1 , 0, -1 , 0, 0 , 1, 0 , 1, 1 , 0, -1 , 0, 0 , 0, 1 , 0, 2 , -1, 0 , 0, 0 , 1, 0 , 0, 1 , 0, 0 , 1, 0 , 0, 1 , 1, 1 , -1, -1 , 0, -1 , 0, 0 , 0, 1 , 1, -1 , 0, -1 , 0, 0 , 0, 1 ;形状最终要画到画布上,在画布上还需要建立一个全局坐标系,即(row, col)的坐标系,与canvas的映射一直,则 自身坐标系的 x 为全局坐标系的 col,需要一个简单的转换。例如自身坐标系为 0, -1 , 0, 0 , 1, 0 , 1, 1 全局坐标系为:12345678910111213row: -1 + row,col: 0 + col, row: 0 + row,col: 0 + col, row: 0 + row,col: 2 + col, row: 1 + row,col: 1 + col转换之后,还有变形,变形的原理是 先相对自身的坐标系中原点移动,然后再转换成全局坐标系。公式如下 x = -y, y = x即 0, -1 , 0, 0 , 1, 0 , 1, 1 变形之后为: 1, 0 , 0, 0 , 0, 1 , -1, 1 实现函数,作为工具模块的函数。其实最好写成函数式的就比较优雅和简洁1234567891011121314151617181920/转换坐标系函数function translate (data, row, col) var tranData = ;for (var i = 0; i 4; i+)var temp = ;temp.row = datai1 + row;temp.col = datai0 + col;tranData.push(temp);return tranData;/旋转图形函数function rotate(data)var rotaData = ,;for (var i = 0; i 4; i+)rotaDatai0 = -datai1;rotaDatai1 = datai0;return rotaData;数据模型,基本完成下一个是在画布上绘制图形。二 界面模型游戏的界面,绘制在canvas上,由于我们抽象方块是由点构成,canvas上需要构造一张点构成的网图来装载方块的点。算法是,这张网分为 row 行,每行有col个点。构造一个“类”的构造函数12345678910111213141516var Map = function(w, h)this.width = w;this.height = h;this.lines = ;for (var row = 0; row this.height; row+)this.linesrow = this.newLine();Mtotype.newLine = function() var singleLine = ;for (var col = 0; col this.width; col+)singleLine.push(noShape);return singleLine;三 绘制工具函数有了数据模型和界面模型,剩下就是调用 canvas 的api进行绘制。由于我们的数据是一个个点的集合。绘图的算法就是将 map 分成一个个由点加宽高构成的小方块。一个图形有四个小方块构成。123456789101112131415161718192021222324252627282930313233343536var spacing = 20;/绘制单个方块函数function drawRect(color, ctx, x, y)ctx.save();ctx.fillStyle = color;ctx.fillRect(x, y, spacing - 2, spacing - 2);ctx.restore();/渲染canvas函数,绘制map有被标记的点function genCanvas(map, ctx)var cwidth = map.width * spacing;var cheight = map.height * spacing;ctx.clearRect(0, 0, cwidth, cheight);var lines = map.lines;for (var row = 0; row map.height; row+)for (var col = 0; col map.width; col+)var shapeId = linesrowcol;if (shapeId != noShape)var x = col * spacing;var y = row * spacing;drawRect(colorsshapeId, ctx, x, y);/绘制移动方块function drawSquare(shapeId, map, ctx, data)genCanvas(ctx, map);var color = colorsshapeIdfor (var i = 0; i 4; i+)var x = datai.row * spacing;var y = datai.col * spacing;drawRect(color, ctx, x, y);四 游戏控制模型控制模型类,构造函数里实力 map对象,并初始化一个方块,拥有方向和旋转方法1234567891011121314151617181920212223242526272829var GameModel = function(w, h)this.map = new Map(w, h);this.born();GameMtotype.born = function()this.shapeId = Math.floor(Math.random() * 7) + 1;this.data = shapesDatathis.shapeId;this.row = 1;this.col = Math.floor(this.map.width / 2);drawSquare(this.shapeId, this.map, ctx, translate(this.data, this.row, this.col);GameMtotype.left = function()this.col -;var temp = translate(this.data, this.row, this.col);drawSquare(this.shapeId, this.map, ctx, temp);GameMtotype.right = function()this.col+;var temp = translate(this.data, this.row, this.col);drawSquare(this.shapeId, this.map, ctx, temp);GameMtotype.down = function()this.row+;var temp = translate(this.data, this.row, this.col);drawSquare(this.shapeId, this.map, ctx, temp);GameMtotype.rotate = function()添加键盘监听事件123456789var model = new GameModel(13, 20);/捕捉键盘控制document.onkeydown = function(e) if (e.keyCode = 37 ) model.left();if (e.keyCode = 38 ) model.rotate();if (e.keyCode = 39 ) model.right();if (e.keyCode = 40 ) model.down();添加前台1234567891011121314Title你的浏览器不支持 Canvas 标签,请使用 Chrome 浏览器 或者 FireFox 浏览器现在基本可以控制方块 左右和向下,但是没有做碰撞检测,需要更新 Map,并在 gamemode 里进行检测123456789101112/碰撞检测Mtotype.isCollide = function(data)for (var i = 0; i 4; i+)var row = datai.row;var col = datai.col;if (col 0 | col = this.width) return true;if (row = this.height) return true;if (row 0) continue;else if (this.linesrowcol != noShape) return true;return false;更新 gamemodel 类1234567891011121314151617181920212223242526272829GameMtotype.left = function()this.col -;var temp = translate(this.data, this.row, this.col);if (this.map.isCollide(temp) this.col +;else drawSquare(this.shapeId, this.map, ctx, temp);GameMtotype.right = function()this.col+;var temp = translate(this.data, this.row, this.col);if (this.map.isCollide(temp) this.col -;else drawSquare(this.shapeId, this.map, ctx, temp);GameMtotype.down = function()this.row+;var temp = translate(this.data, this.row, this.col);if (this.map.isCollide(temp) elsedrawSquare(this.shapeId, this.map, ctx, temp);GameMtotype.rotate = function()if (this.shapeId = squareShape) return;var rotatedata = rotate(this.data);var temp = translate(rotatedata, this.row, this.col);if (this.map.isCollide(temp) return;this.data = rotatedata;drawSquare(this.shapeId, this.map, ctx, temp);五 完善现在,方块方向和旋转基本完成,最后就是判断方块是否到达地面,或者遇到地下的方块。一旦方块下落时发生碰撞。就把方块的shapeID 加入map中。 循环 map的每一行,如果当行的点都有标记,则表示满了,此时消除这一行,并添加新的一个空行。更新 map添加 检测是否满行的方法12345678910111213141516171819202122232425/检测满行Mtotype.isFullLine = function(row)var lines = this.linesrow;for (var col = 0; col this.width; i+)if (linescol = noShape) return false;return true;/消除满行Mtotype.appendShape = function(shapeId, data)/将方块的标记添加到 mapfor (var i = 0; i 4; i+)var row = datai.row;var col = datai.col;this.linesrowcol = shapeId;/消除满行for (var row = 0; row this.height; row+)if (this.isFullLine(row)this.lines.splice(row, 1);this.lines.unshift(this.newLine();

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论