• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com专业计算机教程网站
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure
您的位置:首页 > 网页设计 >html5 > HTML5边玩边学(九)-俄罗斯方块之数据模型篇

HTML5边玩边学(九)-俄罗斯方块之数据模型篇

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-03

本文主要包含HTML5,俄罗斯方块,数据模型等相关知识,匿名希望在学习及工作中可以帮助到您
一、从数据出发还是从界面出发

要写一个俄罗斯方块小游戏,我们先来一块考虑一下下面几个问题:

1、用什么表示方块

2、怎么设置或者改变方块的颜色

3、怎么移动方块

4、怎么消除方块

请考虑一分钟后再继续向下看。。。。。。

如果你对上面几个问题思考,每一个答案都和界面、控件、平台有关的话,就是说假如你是用 .Net 的,你的每一个答案都是围绕着如何利用控件、如何使用窗体、在控件的哪个事件里面改变哪个属性等等,那么说明你被微软的 RAD 开发环境毒害的不浅,我建议你立刻扔掉 Visual Studio,改用其他轻量级的编程语言和开发平台,这样你可以更多的关注问题的本身,而不是控件。

记住:程序 = 数据结构 + 算法

界面只是数据的表象,而数据才是问题的本质。

下面,我们将一步一步建立一个俄罗斯方块小游戏的数据模型,当整个模型建立完毕后,我们会发现,虽然没有界面,仍然不妨碍这是一个功能完整的俄罗斯方块游戏,因为发生的每一件事情都很清楚,我们只是没把它画而已。当然,后面我们会给出一个操作简易的界面,等到下一篇,会专门探讨界面的问题。

二、“形状”的数据模型

俄罗斯方块是一个经久不衰的小游戏,最常见的版本中一般有七个形状,分别是:

直线型、S型、Z型、L型、反L型、T型、方形等,如下图:

那么我们在程序中如何表示这七个形状呢?我们发现每一形状都是四个小方块组成的,我们完全可以用四个点表示。

但是问题又来了,四个点的坐标分别是什么呢?我查到的方法是:每个形状都有一个自己的坐标系,比如S型,可以入下图表示:

这样,S型的数据模型可以表示为四个点组成的数组:[ [ 0, -1 ], [ 0, 0 ], [ -1, 0 ], [ -1, 1 ] ] 。

我们可以用同样的方法建立其他形状的数组模型,然后再将这七个形状的数组模型合起来组成一个大的数组。

另外,每个形状可以是单色,也可以有自己的颜色。增加颜色会增加编程的复杂度,但是也增加不了多少,所以我们的模型中也会考虑颜色。

最后,我们最好给每个形状一个编号,这样方便在形状数组和颜色数组中应用他们。

完成上面的分析后,我们就可以给出形状数据模型的代码了:

形状模型的代码 



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->//各种形状的编号,0代表没有形状
NoShape=0;
ZShape=1;
SShape=2;
LineShape=3;
TShape=4;
SquareShape=5;
LShape=6;
MirroredLShape=7

//各种形状的颜色
Colors=["black","fuchsia","#cff","red","orange","aqua","green","yellow"];

//各种形状的数据描述
Shapes=[
    [ [ 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 ] ]
];

三、定位和旋转形状

1、定位

我们上面说到每个形状都是在自己的坐标系里面描述的,另外还有一个全局坐标系,用来给形状定位,这样我们就需要一个方法将形状的四个点从自身坐标系转换到全局坐标系,从而给形状定位。

假如S型在自身坐标系中四个点的坐标为:[ [ 0, -1 ], [ 0, 0 ], [ -1, 0 ], [ -1, 1 ] ]

它当前在全局坐标系位置为:[12,8]

则,四个点转换为全局坐标系的坐标为:[ [ 0+12, -1+8 ], [ 0+12, 0+8 ], [ -1+12, 0+8 ], [ -1+12, 1+8 ] ]

这样,我们就完成了 S型 的全局坐标转换。

这里需要注意一个问题,形状自身坐标系是用 (x,y) 描述的,而全局坐标系为了逻辑上更直观,是用 (row,col) 描述的,所以我们在实际编程中并不是向上面那样转换的,而是:

[ [ -1+12, 0+8 ], [ 0+12, 0+8 ], [ 0+12, -1+8 ], [ 1+12, -1+8 ] ]

即:先将 x 变为 col ,y 变为 row ,再转换为全局坐标系。

2、旋转

旋转是在形状的自身坐标系中,并围绕形状的原点完成的,公式很简单,每个点旋转后的坐标与旋转前坐标的关系如下(向右旋转):

x' = y

y' = -x

注意:方块形状不发生旋转。

有了上面的分析,我们就可以给出两个全局方法,他们用来对形状进行全局定位和旋转:

全局定位和旋转的代码 



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->//将形状自身的坐标系转换为  Map 的坐标系,row col 为当前形状原点在 Map 中的位置
function translate(data,row,col){
    var copy=[];
    for(var i=0;i<4;i++){
        var temp={};
        temp.row=data[i][1]+row;
        temp.col=data[i][0]+col;
        copy.push(temp);
    }
    return copy;
}

//向右旋转一个形状:x'=y, y'=-x
function rotate(data){
    var copy=[[],[],[],[]];
    for(var i=0;i<4;i++){
        copy[i][0]=data[i][1];
        copy[i][1]=-data[i][0];
    }
    return copy;
}

四、移动空间

前面我们说过,形状是由四个点组成的,而形状的移动空间也是由 m * n 个点组成的一个二维数组。

这里为了更直观的描述,我将 n 个点组成一条线 Line,再将 m 条 Line 组成形状的移动空间,我把它叫做 Map 。

我们有了这 m * n 个点有什么用呢?用处很简单,就是保存形状的编号,如果一个点没有被形状占用,则编号为 NoShape。这就是前面给出形状编号的用处,同时也是为什么要有一个 NoShape 编号的原因。

Map 应该具有什么功能呢?下面我列举了一些:

1、构造函数:这不用说了,n 个点组成一行 Line, m 行 Line 组成Map,每个点初始化成 NoShape

2、newLine:生成新的一行。为什么需要这个方法呢,因为除了构造函数中,游戏运行过程中我们也需要用到它,当一行或者几行被消除以后,我们需要在顶部假如一行或者几行新的Line

3、isFullLine(row):这个方法用来判断第 row 行是否满了,每次一个形状落地后,就需要对每一行进行这个判断,满了当然是消除了。

4、isCollide(data): data 是一个定位后的形状数据,这样我们就可以检查这些数据是否超出移动空间的上下左右边界,另外还检查数据的四个点是否已经被占用,这就是碰撞检测。

5、appendShape(shape_id,data):当一个形状落地以后,我们就应该将运行空间中某些点的值改变为这个形状的编号,我把这称为占用。

6、消除操作:这个功能没有单独列为一个方法,我把它放在 appendShape 方法中了。消除操作也很简单,发现某一行 isFullLine 了以后,在 lines 数组中移除这一行,并在 lines 数组的顶部加入一个空行即可。

有了上面的分析,我们就可以给出移动空间的代码了:

移动空间的代码 



Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->/*
 * 说明:由 m 行 Line 组成的格子阵
 */
function  Map(w,h){
    //游戏区域的长度和宽度
    this.width=w;
    this.height=h;
    //生成 height 个 line 对象,每个 line 宽度为 width
    this.lines=[];
    for(var row=0;row<h;row++)
        this.lines[row]=this.newLine();
}

//说明:间由 n 个格子组成的一行
Map.prototype.newLine=function(){
    var shapes=[];
    for(var col=0;col<this.width;col++)
        shapes[col]=NoShape;
    return shapes;
}

//判断一行是否全部被占用
//如果有一个格子为 NoShape 则返回 false
Map.prototype.isFullLine=function(row){
    var line=this.lines[row];
    for(var col=0;col<this.width;col++)
        if(line[col]==NoShape)
            return false
    return true;
}
/*
 * 预先移动或者旋转形状,然后分析形状中的四个点是否有碰撞情况:
 *      1:col<0 || col>this.width 超出左右边界
 *      2:row==this.height ,说明形状已经到最底部
 *      3:任意一点的 shape_id 不为 NoShape ,则发生碰撞
 *  如果发生碰撞则放弃移动或者旋转
 */
Map.prototype.isCollide=function(data){
    for(var i=0;i<4;i++){
        var row=data[i].row;
        var col=data[i].col;
        if(col<0 || col==this.width) return true;
        if(row==this.height) return true;
    
  


 

您可能想查找下面的文章:

  • HTML5知识点总结
  • HTML5的本地存储
  • HTML5本地存储之IndexedDB
  • Html5实现文件异步上传功能
  • Html5新标签datalist实现输入框与后台数据库数据的动态匹配
  • 详解HTML5 window.postMessage与跨域
  • HTML5拖放API实现拖放排序的实例代码
  • 解决html5中video标签无法播放mp4问题的办法
  • HTML5新特性 多线程(Worker SharedWorker)
  • Html5新增标签有哪些

相关文章

  • 2018-12-03html5使用canvas画三角形_html5教程技巧
  • 2018-12-03将HTML5封装成android应用APK文件的几种方法
  • 2018-12-03混合移动开发框架详解
  • 2017-08-06HTML5通过调用canvas对象的getContext()方法来获取绘图环境
  • 2018-12-03html5 自定义播放器核心代码_html5教程技巧
  • 2018-12-03HTML5中属性download的详细介绍
  • 2018-12-03HTML5新增加的标签和表单新增属性的代码实例
  • 2018-12-03HTML5 游戏移植为 iOS 原生应用,需要注意哪些地方?有什么经验可以分享?
  • 2018-12-03Web 平台是否会在移动平台上最终超过应用平台?为什么?
  • 2018-12-03JS案例联系之留言板

文章分类

  • html/xhtml
  • html5
  • CSS
  • XML/XSLT
  • Dreamweaver教程
  • Frontpage教程
  • 心得技巧
  • bootstrap
  • vue
  • AngularJS
  • HBuilder教程
  • css3
  • 浏览器兼容
  • div/css
  • 网页编辑器
  • axure

最近更新的内容

    • 抽出1个小时制作一款简单的物理小游戏(绳子原理)
    • html5将图片转换成base64的实例代码
    • HTML5 Canvas阴影使用方法实例演示
    • 通过H5实现拍照功能的实例详解
    • html5 touch事件实现页面上下滑动效果【附代码】
    • HTML5 embed标签定义和用法详解
    • HTML5幻灯片系统:H5Slides
    • HTML5之SVG 2D入门7—SVG元素的重用与引用_html5教程技巧
    • 详解HTML5中canvas支持触摸屏的签名面板的示例代码
    • 详细介绍WebSocket API HTML5规范翻译

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有