[转]Tetris(俄罗斯方块) in jQuery/JavaScript!
本文转自:http://pwwang.com/2009/10/25/tetris-in-jquery-javascript/
All in jQuery/JavaScript + HTML!
Demo:Tetris(俄罗斯方块) in jQuery/JavaScript!
文章最后会给出源码下载。
先上两张图:


其实很早就有这样的想法,无奈思想一直不是很成熟,各个细节没有想好。突然某一天灵光闪现,就想到办法了。相信应该也有很多人有过这样的想法,可是总是会被一些细节问题所卡住。只要思路有了,代码的实现上并不难。所以我重点说一下思路。
先说一下这样程序的功能吧。图里面能够看得很清楚了。基本的功能就不说了,其它的包括下一个下落形状的预览(左上角的小方块中),隐藏、显示网格线,隐藏、显示下落时对好的阴影形状。其它的就是俄罗斯方块的基本功能了。
很重要的一点,很多人可能受到了思维定势的影响,觉得既然是俄罗斯方块,那当然是一个个方块往下落。如果你这样想,我敢说这样就算程序的功能都可以完成,也绝对在1000行以上(我的程序不超过1000行,包括各个函数的注释),甚至要远远超过这个数。如果跳出了这个方块下落和思维定势,那问题就好解决了。
有人可能要问了,既然方块不动,那是什么在动呢?有人说颜色,但更确切地说是样式!每一次,让下一个方格的样式用上一个方块来替代,这样下落就成了对样式的操作了!虽然下落是位置在变,位置(top,left)也是样式,但是这可能要涉及到HTML,或者DOM元素的操作了。相比而言,前一种思路不用动任何的HTML元素!这是简化的最关键所在了。
再说一下其它方面。
方块的排列:
用一个float:left就能排列好了,需要注意的是,在设置容器的长宽时,要注意小方块的方框宽度,这个也要计算在内。
按键的处理:
我们知道,像DIV,SPAN(容器用的DIV,方块用的SPAN)无法直接响应按键按下的事件(onkeydown),那我们只好先用可以响应的元素来接收这个事件,我用的是document,由于我把它写在了类的内部,所以,要把事件内容的this变成实际要处理的元素(Tetris),就需要用到javascript的call函数了。
形状在移动(左、右、下、旋转)的时候出界或者是否压住了其他方块的判断:
有两种方式,第一种是先计算好方块可以移动的最小距离,然后再判断方块是否移动超过了这个最小距离。(注意我这里说的移动都是对样式的操作)。这种方式比较麻烦,因为首先要得到方块的最左,最右和最下的方块,然后再通过这些方块来计算这个最小距离,并且旋转就无法用距离来衡量了。但是如果要得到阴影(后面解释阴影的实现)的话,还是得计算这个最小距离。我的做法是移动一步(包括旋转)采取第二种方法,而直接下落和生成阴影而采用第一种方法。
第二种方式是先将坐标值预存起来,然后假设方块移动了,再判断这个方块是否在界内,并没在压住其它的方块。如果不符合条件,再将坐标值还原回去。这里插一句,如果预存坐标?我的坐标采用的是数组的形式储存的,不能直接用=来赋值,这个只能将变量指向右值而成为右值的引用。要复制数组或对象,必须采用循环或者遍历对象属性,且元素或属性的值为基本类型时才能赋值。
下一个形状预览的问题:
想清楚了最关键的问题,这个问题很好解决,这个就是大容器的缩小版,当前显示形状的时候同时计算下一个形状的序列号,并存储。下次显示形状的时候调用这个序列号就行了。
最后说一下旋转的问题:
其实这是一个数学问题。

由于旋转前后,向量的长度(设为R)不变,所以:
cosA = x0/R, sinA = y0/R …… (2)
对于右图:
x1 = R * cos(A+B)=R(cosAcosB – sinAsinB)
y1 = R|* sin(A+B)=R(sinAcosB + cosAsinB)
将(2)代入得到:
x1 = x0 * cosB – y0 * sinB
y1 = x0 * sinB + y0 * cosB
由于我设定的是逆时针旋转,所以再将B=-B代入上式:
x1 = x0 * cosB + y0 * sinB
y1 = -x0 * sinB + y0 * cosB
再者,我们旋转的角度为90度,再代入,得到:
x1=y0, y1=-x0 …………. (3)
这是以原点为出发的向量,如果不是原点为出发点,假设这个点(旋转中心)为(cx,cy),将向量进行平移:
x1-cx = y0-cy, y1-cy = cx-x0,于是(3)变成:
x1 = cx-cy+y0, y1 = cx+cy-x0 (4)
这里值得提一下的是,尽管我们的坐标系和正规的xy平面坐标系不同,我们的原点在左上角,x(二维数组第一下标)轴垂直向下,y(二维数组第二下标)轴水平向右,但是由于我们旋转的时候选取的是向量,它的方向是确定的,不随坐标系的变化而变化,所以(4)仍然适用于我们的坐标系。
有了公式(4),选取适当的旋转中心(x0,y0)就可以进行转换了。为了效率,我们可以把由四个小方块组成的大方块排除在外,不用旋转。
Home Page in Google Code: http://code.google.com/p/tetris-in-jquery-javascript/
Introduction
jQuery.msgbox game called tetris(俄罗斯方块) in jQuery/JavaScript?
Information
pwwang http://pwwang.com
page http://pwwang.com/technology/js-javascript/tetris-in- jquery-javascript/
demo http://pwwang.com/tools/tetris.html
Details
- It’s a classic tetris
- It has basic functions of tetris
- You could decide to show the grids or not
- You could choose to show the shadow( will the falling shape will locate ) or not
- Pause or resume game
[转]Tetris(俄罗斯方块) in jQuery/JavaScript!的更多相关文章
- [JS]jQuery,javascript获得网页的高度和宽度
[JS]jQuery,javascript获得网页的高度和宽度网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeigh ...
- jQuery UI 是建立在 jQuery JavaScript 库上的一组用户界面交互、特效、小部件及主题
jQuery UI 是建立在 jQuery JavaScript 库上的一组用户界面交互.特效.小部件及主题.无论您是创建高度交互的 Web 应用程序还是仅仅向窗体控件添加一个日期选择器,jQuery ...
- Visual Studio 2012设置Jquery/Javascript智能提示
Visual Studio 2012设置Jquery/Javascript智能提示 在Visual Studio 2008 Visual Studio 2010中微软已经开始支持jquery/java ...
- jQuery JavaScript Library v3.2.1
/*! * jQuery JavaScript Library v3.2.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzle ...
- x01.Tetris: 俄罗斯方块
最强大脑有个小孩玩俄罗斯方块游戏神乎其技,那么,就写一个吧,玩玩而已. 由于逻辑简单,又作了一些简化,所以代码并不多. using System; using System.Collections.G ...
- jQuery/javascript实现全选全不选
<html> <head> <meta charset="utf-8"> <title>Checkbox的练习</title& ...
- jQuery/javascript实现网页注册的表单验证
<html> <head> <meta charset="utf-8"> <title>注册表单验证</title> & ...
- jQuery/javascript实现简单网页计算器
<html> <head> <meta charset="utf-8"> <title>jQuery实现</title> ...
- JQuery & Javascript
Jquery 是一个优秀的javascript框架,是轻量级的js库 jQuery简化了javascript 编程 jQuery很容易学习
随机推荐
- DROOLS相关资料
这个地址可以教你如何配置drools的workbench http://blog.csdn.net/u012373815/article/details/53526287 这篇文章教你如何搭建一个简单 ...
- c++特别要点:多态性与虚函数
本来是准备在工厂模式中顺便整理.但粗略浏览了,内容还是很多,需要单独开一篇. 一.什么是多态性? 多态性可以概括为“一个接口,多种方法”. 多态与非多态的区别在于“成员函数调用地址的早绑定和晚绑定”. ...
- winFrom程序更新自动安装
我就以一个计算字符长度的程序为例子吧界面如下 代码如下 [C#] 纯文本查看 复制代码 ? 01 02 03 04 private void button1_Click(object sender, ...
- Django之QuerySet 查询
首先来看下如何查询.我们在网页中增加书名的查询链接 后端的查询处理代码:这里由于authors是manytomanyfiled,因此我们这里用r.authors.all().first()来查询符合条 ...
- 167. Two Sum II - Input array is sorted两数之和
1. 原始题目 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明 ...
- POJ - 2528Mayor's posters (离散化+线段树区间覆盖)
The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign h ...
- C语言数据结构-循环队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作
1.数据结构-循环队列的实现-C语言 #define MAXSIZE 100 //循环队列的存储结构 typedef struct { int* base; //基地址 int _front; //头 ...
- 牛客nowcoder NOIP普及组第三场
qtmd AK了 直接题解吧 题目链接 A-十七边形 牛牛想在一个半径为r的圆中,找到一个内接的十七边形,使他的面积最大.输入半径r,输出最大的面积. 1 <= r <= 10000 在1 ...
- 2-28 if...else
- node.js 服务器
http-server 是一个简单的零配置命令行HTTP服务器, 基于 nodeJs. 如果你不想重复的写 nodeJs 的 web-server.js, 则可以使用这个. 安装 (全局安装加 -g) ...