<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>迷途知返 &#187; Tetris</title>
	<atom:link href="http://pwwang.com/tag/tetris/feed/" rel="self" type="application/rss+xml" />
	<link>http://pwwang.com</link>
	<description>专注技术,用心生活!</description>
	<lastBuildDate>Wed, 08 Feb 2012 09:37:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Tetris(俄罗斯方块) in jQuery/JavaScript!</title>
		<link>http://pwwang.com/2009/10/25/tetris-in-jquery-javascript/</link>
		<comments>http://pwwang.com/2009/10/25/tetris-in-jquery-javascript/#comments</comments>
		<pubDate>Sat, 24 Oct 2009 18:09:48 +0000</pubDate>
		<dc:creator>pwwang</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tetris]]></category>

		<guid isPermaLink="false">http://pwwang.com/?p=746</guid>
		<description><![CDATA[&#160;

All in jQuery/JavaScript + HTML!

Demo：Tetris(俄罗斯方块) in jQuery/JavaScript!

<span class="readmore"><a href="http://pwwang.com/2009/10/25/tetris-in-jquery-javascript/" title="Tetris(俄罗斯方块) in jQuery/JavaScript!">Read More: 2427 Words Totally</a></span>]]></description>
			<content:encoded><![CDATA[<p>&nbsp;</p>
<p>All in jQuery/JavaScript + HTML!</p>
<p>Demo：<a target="_blank" href="http://pwwang.com/tools/tetris.html">Tetris(俄罗斯方块) in jQuery/JavaScript!</a></p>
<p>文章最后会给出源码下载。</p>
<p>先上两张图：</p>
<p><a href="http://pwwang.com/tools/tetris.html" target="_blank"><img border="0" style="clear: both;" src="http://pwwang.com/wp-content/uploads/tetris/Tetris_ready.png" alt="" /></a></p>
<p><a href="http://pwwang.com/tools/tetris.html" target="_blank"><img border="0" style="clear: both;" src="http://pwwang.com/wp-content/uploads/tetris/Tetris_running.png" alt="" /></a></p>
<p><span id="more-746"></span></p>
<p>其实很早就有这样的想法，无奈思想一直不是很成熟，各个细节没有想好。突然某一天灵光闪现，就想到办法了。相信应该也有很多人有过这样的想法，可是总是会被一些细节问题所卡住。只要思路有了，代码的实现上并不难。所以我重点说一下思路。</p>
<p>先说一下这样程序的功能吧。图里面能够看得很清楚了。基本的功能就不说了，其它的包括下一个下落形状的预览（左上角的小方块中），隐藏、显示网格线，隐藏、显示下落时对好的阴影形状。其它的就是俄罗斯方块的基本功能了。</p>
<p>很重要的一点，很多人可能受到了思维定势的影响，觉得既然是俄罗斯方块，那当然是一个个方块往下落。如果你这样想，我敢说这样就算程序的功能都可以完成，也绝对在1000行以上（我的程序不超过1000行，包括各个函数的注释），甚至要远远超过这个数。如果跳出了这个方块下落和思维定势，那问题就好解决了。</p>
<p>有人可能要问了，既然方块不动，那是什么在动呢？有人说颜色，但更确切地说是样式！每一次，让下一个方格的样式用上一个方块来替代，这样下落就成了对样式的操作了！虽然下落是位置在变，位置（top,left）也是样式，但是这可能要涉及到HTML，或者DOM元素的操作了。相比而言，前一种思路不用动任何的HTML元素！这是简化的最关键所在了。</p>
<p>再说一下其它方面。</p>
<p>方块的排列：</p>
<p>用一个float:left就能排列好了，需要注意的是，在设置容器的长宽时，要注意小方块的方框宽度，这个也要计算在内。</p>
<p>按键的处理：</p>
<p>我们知道，像DIV，SPAN（容器用的DIV，方块用的SPAN）无法直接响应按键按下的事件（onkeydown），那我们只好先用可以响应的元素来接收这个事件，我用的是document，由于我把它写在了类的内部，所以，要把事件内容的this变成实际要处理的元素（Tetris），就需要用到javascript的call函数了。</p>
<p>形状在移动（左、右、下、旋转）的时候出界或者是否压住了其他方块的判断：</p>
<p>有两种方式，第一种是先计算好方块可以移动的最小距离，然后再判断方块是否移动超过了这个最小距离。（注意我这里说的移动都是对样式的操作）。这种方式比较麻烦，因为首先要得到方块的最左，最右和最下的方块，然后再通过这些方块来计算这个最小距离，并且旋转就无法用距离来衡量了。但是如果要得到阴影（后面解释阴影的实现）的话，还是得计算这个最小距离。我的做法是移动一步（包括旋转）采取第二种方法，而直接下落和生成阴影而采用第一种方法。</p>
<p>第二种方式是先将坐标值预存起来，然后假设方块移动了，再判断这个方块是否在界内，并没在压住其它的方块。如果不符合条件，再将坐标值还原回去。这里插一句，如果预存坐标？我的坐标采用的是数组的形式储存的，不能直接用＝来赋值，这个只能将变量指向右值而成为右值的引用。要复制数组或对象，必须采用循环或者遍历对象属性，且元素或属性的值为基本类型时才能赋值。</p>
<p>下一个形状预览的问题：</p>
<p>想清楚了最关键的问题，这个问题很好解决，这个就是大容器的缩小版，当前显示形状的时候同时计算下一个形状的序列号，并存储。下次显示形状的时候调用这个序列号就行了。</p>
<p>最后说一下旋转的问题：</p>
<p>其实这是一个数学问题。</p>
<p><img border="0" alt="" src="http://pwwang.com/wp-content/uploads/tetris/rotate.gif" style="clear: both;" /></p>
<p>由于旋转前后，向量的长度（设为R）不变，所以：</p>
<p>cosA = x0/R,&nbsp; sinA = y0/R&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230; &nbsp; （2）</p>
<p>对于右图：</p>
<p>x1 = R * cos（A+B）＝R（cosAcosB &#8211; sinAsinB）</p>
<p>y1 = R|* sin（A+B）＝R（sinAcosB + cosAsinB）</p>
<p>将（2）代入得到：</p>
<p>x1 = x0 * cosB &#8211; y0 * sinB</p>
<p>y1 = x0 * sinB + y0 * cosB</p>
<p>由于我设定的是逆时针旋转，所以再将B＝-B代入上式：</p>
<p>x1 = x0 * cosB + y0 * sinB</p>
<p>y1 = -x0 * sinB + y0 * cosB</p>
<p>再者，我们旋转的角度为90度，再代入，得到：</p>
<p>x1=y0, y1=-x0&nbsp;&nbsp; &#8230;&#8230;&#8230;&#8230;. （3）</p>
<p>这是以原点为出发的向量，如果不是原点为出发点，假设这个点（旋转中心）为（cx，cy），将向量进行平移：</p>
<p>x1-cx = y0-cy, y1-cy = cx-x0，于是（3）变成：</p>
<p>x1 = cx-cy+y0, y1 = cx+cy-x0&nbsp; （4）</p>
<p>这里值得提一下的是，尽管我们的坐标系和正规的xy平面坐标系不同，我们的原点在左上角，x（二维数组第一下标）轴垂直向下，y（二维数组第二下标）轴水平向右，但是由于我们旋转的时候选取的是向量，它的方向是确定的，不随坐标系的变化而变化，所以（4）仍然适用于我们的坐标系。</p>
<p>有了公式（4）,选取适当的旋转中心（x0,y0）就可以进行转换了。为了效率，我们可以把由四个小方块组成的大方块排除在外，不用旋转。</p>
<p><a href="http://pwwang.com/wp-content/uploads/tetris/tetris.rar" target="_blank">源代码下载</a></p>
<p>&nbsp;</p>
<p>Home Page in Google Code: <a href="http://code.google.com/p/tetris-in-jquery-javascript/" target="_blank">http://code.google.com/p/tetris-in-jquery-javascript/</a></p>
<h1>Introduction</h1>
<p>jQuery.msgbox game called tetris(俄罗斯方块) in jQuery/JavaScript<a href="/p/tetris-in-jquery-javascript/w/edit/JavaScript">?</a></p>
<h1>Information</h1>
<p>pwwang <a rel="nofollow" href="http://pwwang.com">http://pwwang.com</a></p>
<p>page <a rel="nofollow" href="http://pwwang.com/technology/js-javascript/tetris-in-jquery-%0A%0Ajavascript/">http://pwwang.com/technology/js-javascript/tetris-in-  jquery-javascript/</a></p>
<p>demo <a rel="nofollow" href="http://pwwang.com/tools/tetris.html">http://pwwang.com/tools/tetris.html</a></p>
<h1>Details</h1>
<ul>
<li>It&#8217;s a classic tetris</li>
<li>It has basic functions of tetris</li>
<li>You could decide to show the grids or not</li>
<li>You could choose to show the shadow( will the falling shape will   locate ) or  not</li>
<li>Pause or resume game</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://pwwang.com/2009/10/25/tetris-in-jquery-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

