由于工作关系,很久没来过了。昨天无聊闲逛却看到aasddsasda写的JS俄罗斯方块代码,写得很不错。但是老有一群喊看不懂的同学,为了让更多人能获得学习的兴趣,所以写了这篇解释文,揭开JS游戏的神秘面纱。希望更多更多的同学能喜欢JS,写更多令人惊喜的代码。
首先,这一个游戏需要用到的知识,除了JS外,还有CSS和DHTML。跟网页有关的JS,基本都和这两者有关,所以这两个也是想学JS各位的必修课。
第二,解密的第一步,要理解首先是从现象再到本质的,所以大家在看到界面的时候是否有想过为什么界面会如此显示呢?因为body中的HTML的代码只有聊聊数行:
所以从这样的现象里,大家就应该注意到CSS中的定义。那就不难发现作者的意图是什么了。
第三,有人可能会问,CSS怎么看?教大家最简单的一招:试!
没错,只有实践能出真知,就那么一块长代码,大家都可能会头痛,但自己试出来,就会印象深刻了。
CSS里有三种常用模式,作者这里用到的有标签式定义,例如SPAN。ID式定义,以“#”开头的,如#body。还有一种是实际工作常用的类,以“.”开头的。有兴趣的同学可以继续研究一下。
第四,来到真正的JS块了。别因为长而害怕,更不要看到0xCC00就害怕了。其实看到CSS,大家就会发现究竟作者想做什么了。为什么会有像一个方块的SPAN和P的样式存在呢?作者要怎么把他拼凑到一块?那就需要你动动脑子了。
众所周知,你要出现某个拼凑出来的形状,首先得要定义吧?那怎么定义呢?不难发现0x801这段很长的16进制码。
什么?16进制码?干什么用?记得有人说过的一句话吗:计算机的世界是二进制的世界?那我们怎么不试试把他转成0和1看看呢?
如果你有这么想过,那么WINDOWS附带的科学计算器就能满足你的欲望:0x801其实就是100000000001。
呀!这串东西是啥?再动动脑子,哪里比较像?数数游戏中图形的方格,不难发现游戏区中除了最后一行外的每一行的方格数与这边很像。
每错,这就是每一行的点阵定义!
同理,你也能发现下面的0xCC00其实就是每一个图形的定义。只是,他将四行写成一行了。呵呵。
第五,不要看到<<和>>,还有&之类的位运算符就害怕了。
<<是左移X位,X与<<号后跟的数字有关。>>是反过来的右移。而&则是与运算,只有两个数按位都是1才能获得1的结果。
这些都是位运算,没什么难的,却是计算机CPU真正在做的事情。
第六,要对运算符的优先级有概念。我们看到乘号会知道他比加号先运行,大家在学数学都知道了。但是遇到其他运算符的情况呢?位运算符是比加减乘除的运算级别低的。
第七,作者使用了一些特殊用法,可能初学者看不懂,但是现在GOOGLE虽然移海外了,但是还是能查查的。这些使用的特殊技巧,见过一次就会记得的。多学习对自己有好处呢。
好了,就说这么多,请看代码全注释:
最后,提个希望,作品发表不应该只是为了制造崇拜吧?良好的注释是让崇拜你的人好好学习的途径哦。希望以后大家发表的作品多加点注释,让想进入这个领域的人能有路可寻。只有越来越多的人进入这一领域,这个领域才能更好的发展啊!(没人关注,有谁会投资啊?!工作都找不到这类的,当然就没人会感兴趣而很容易就末落了。)
首先,这一个游戏需要用到的知识,除了JS外,还有CSS和DHTML。跟网页有关的JS,基本都和这两者有关,所以这两个也是想学JS各位的必修课。
第二,解密的第一步,要理解首先是从现象再到本质的,所以大家在看到界面的时候是否有想过为什么界面会如此显示呢?因为body中的HTML的代码只有聊聊数行:
<body onload='G.init();'> <div id='main'> <div id='body'></div> <div id='score'></div> <div id='level'></div> <div id='next'></div> <div id='ctrl'> <button onclick="javascript:location.href=location.href;">New</button> <button onclick="javascript:this.innerHTML={'true':'Start','false':'Pause'}[G.pause=!!!G.pause];">Pause</button> </div> </GMain> </body>
所以从这样的现象里,大家就应该注意到CSS中的定义。那就不难发现作者的意图是什么了。
第三,有人可能会问,CSS怎么看?教大家最简单的一招:试!
没错,只有实践能出真知,就那么一块长代码,大家都可能会头痛,但自己试出来,就会印象深刻了。
CSS里有三种常用模式,作者这里用到的有标签式定义,例如SPAN。ID式定义,以“#”开头的,如#body。还有一种是实际工作常用的类,以“.”开头的。有兴趣的同学可以继续研究一下。
第四,来到真正的JS块了。别因为长而害怕,更不要看到0xCC00就害怕了。其实看到CSS,大家就会发现究竟作者想做什么了。为什么会有像一个方块的SPAN和P的样式存在呢?作者要怎么把他拼凑到一块?那就需要你动动脑子了。
众所周知,你要出现某个拼凑出来的形状,首先得要定义吧?那怎么定义呢?不难发现0x801这段很长的16进制码。
什么?16进制码?干什么用?记得有人说过的一句话吗:计算机的世界是二进制的世界?那我们怎么不试试把他转成0和1看看呢?
如果你有这么想过,那么WINDOWS附带的科学计算器就能满足你的欲望:0x801其实就是100000000001。
呀!这串东西是啥?再动动脑子,哪里比较像?数数游戏中图形的方格,不难发现游戏区中除了最后一行外的每一行的方格数与这边很像。
每错,这就是每一行的点阵定义!
同理,你也能发现下面的0xCC00其实就是每一个图形的定义。只是,他将四行写成一行了。呵呵。
第五,不要看到<<和>>,还有&之类的位运算符就害怕了。
<<是左移X位,X与<<号后跟的数字有关。>>是反过来的右移。而&则是与运算,只有两个数按位都是1才能获得1的结果。
这些都是位运算,没什么难的,却是计算机CPU真正在做的事情。
第六,要对运算符的优先级有概念。我们看到乘号会知道他比加号先运行,大家在学数学都知道了。但是遇到其他运算符的情况呢?位运算符是比加减乘除的运算级别低的。
第七,作者使用了一些特殊用法,可能初学者看不懂,但是现在GOOGLE虽然移海外了,但是还是能查查的。这些使用的特殊技巧,见过一次就会记得的。多学习对自己有好处呢。
好了,就说这么多,请看代码全注释:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <mce:style><!-- div {display:block;background-color:black;position:absolute;font:17px Tahoma;color:#fff;} <!-- 层 --> span {float:left;background-color:gray;width:12px;height:12px;border:4px gray outset;margin:0 1 1 0;overflow:hidden;} <!-- 游戏区单体方块 --> p {float:left;width:8px;height:8px;border:2px gray outset;overflow:hidden;margin:0;padding:0} <!-- 预览区单体方块 --> #main {width:375px;height:430px;display:block;background-color:gray;position:relative;} <!-- 全面版 --> #body {width:241px;height:401px;left:15px;top:15px;border:1px solid #999;} <!-- 主游戏区 --> #score {width:80px;height:24px;left:270px;top:15px;padding:4px;} <!-- 计分区 --> #level {width:80px;height:24px;left:270px;top:50px;padding:4px;} <!-- 等级区 --> #next {width:50px;height:50px;left:270px;top:85px;border:19px black solid;} <!-- 预览区 --> #ctrl {width:80px;height:55px;left:270px;top:360px;padding:4px;text-align:center;background-color:gray} <!-- 按钮区 --> #ctrl button{width:80px;height:25px;} <!-- 按钮 --></mce:style><style mce_bogus="1"> div {display:block;background-color:black;position:absolute;font:17px Tahoma;color:#fff;} <!-- 层 --> span {float:left;background-color:gray;width:12px;height:12px;border:4px gray outset;margin:0 1 1 0;overflow:hidden;} <!-- 游戏区单体方块 --> p {float:left;width:8px;height:8px;border:2px gray outset;overflow:hidden;margin:0;padding:0} <!-- 预览区单体方块 --> #main {width:375px;height:430px;display:block;background-color:gray;position:relative;} <!-- 全面版 --> #body {width:241px;height:401px;left:15px;top:15px;border:1px solid #999;} <!-- 主游戏区 --> #score {width:80px;height:24px;left:270px;top:15px;padding:4px;} <!-- 计分区 --> #level {width:80px;height:24px;left:270px;top:50px;padding:4px;} <!-- 等级区 --> #next {width:50px;height:50px;left:270px;top:85px;border:19px black solid;} <!-- 预览区 --> #ctrl {width:80px;height:55px;left:270px;top:360px;padding:4px;text-align:center;background-color:gray} <!-- 按钮区 --> #ctrl button{width:80px;height:25px;} <!-- 按钮</style> <mce:script type="text/javascript"><!-- //By: X!ao_f QQ:120000512 var G = { fs:[], // 游戏区点阵 fn:[], // 预览区点阵 score:0, l:['#9F0','#FF3','#F33','#C0C','#33C','#0F3','#F93'],// 颜色选择器 v:[0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0xFFFF], // 游戏区行点阵 d:[[0xCC00],[0x4444,0xF0],[0x8C40,0x6C00],[0x4C80,0xC600],[0x44C0,0x8E00,0xC880,0xE200],[0x88C0,0xE800,0xC440,0x2E00],[0x4E00,0x8C80,0xE400,0x4C40]], // 方块造型点阵 init:function(){ var body = document.getElementById('body'); var next = document.getElementById('next'); for(var i=0;i<240;i++){ // 以游戏区单体方块填充点阵 G.fs.push(body.appendChild(document.createElement("span"))); } for(var i=0;i<16;i++){ // 以预览区单体方块填充点阵 G.fn.push(next.appendChild(document.createElement("p"))); } G.domScore = document.getElementById('score'); G.domLevel = document.getElementById('level'); document.onkeydown=function(e){G.event(e||window.event,0)}; // 页面按键事件控制转移到闭包 G.rand(); G.next(); }, timeTesk:function(){ if(G.pause)return;// 如果暂停按钮按下,则停止该函数运行 if(!G.move(G.x, G.y+1, G.t)){ // 是否能继续下移 var s = 0; for(var i=0;i<19;i++){ G.v[i]=G.v[i]|G.m[i]; if(G.v[i]==0xFFF){// 根据行点阵判断是否已达到可消除行 for(var k=i;k>0;k--){ G.v[k] = G.v[k-1];// 消除已完全成行(向下移位) } G.score+=++s;// 计分 } } G.next(); return false; } G.draw(); return true; }, move:function(x,y,t){ // 位移函数 var m = []; for(var k=0;k<4;k++){ // 因为方块形状建模是4X4点阵.所以循环4次 m[y+k] = (G.d[G.n][t]>>(3-k)*4&0xF)<<Math.max(x,0)>>-Math.min(x,0); // G.d[G.n]为现在使用的方块点阵模型,[t]为第t种旋转模型点阵 // G.d[G.n][t]>>(3-k)*4&0xF为获取单行位移后的点阵 // <<Math.max(x,0)>>-Math.min(x,0)为判断x为左移还是右移 // m[y+k]对应位移点阵行 if(m[y+k] & G.v[y+k]){// 判断是否位移后点阵与游戏区现有点阵重叠 return false; } } G.x = x;// 保存当前下落点阵模型坐标 G.y = y;// 保存当前下落点阵模型坐标 G.t = t;// 保存当前下落点阵模型旋转模型 G.m = m;// 保存当前下落点阵模型在类游戏区的位置(镜像位置) G.draw(); return true; }, rand:function(){ G.n = G._n; // 获取上次生成的随机方块点阵模型 G.t = G._t; // 获取上次生成的随机方块点阵旋转系数 G.c = G._c; // 获取上次生成的随机颜色 G._n = parseInt(Math.random()*G.d.length); // 以模型长度生成随机数 G._t = parseInt(Math.random()*G.d[G._n].length); // 同上 G._c = parseInt(Math.random()*G.l.length); // 同上 }, next:function(){ G.rand(); if(parseInt(G.score/20)!=G.level){ // 分数与等级互换的概念...20分一级哦... G.level = parseInt(G.score/20); // 不等于当前等级则升级 clearInterval(G.handle); // 清楚上一计时器 G.handle = setInterval("G.timeTesk()",500/(G.level+1));// 按等级设计时器(控制速度的地方哦!) } G.domScore.innerHTML = 'Score:'+G.score; // 更新分数 G.domLevel.innerHTML = 'Level:'+G.level; // 更新等级 var i = 0; while(!(G.d[G.n][G.t]>>i*4&0xF))i++; // 将i移动到点阵模型有显示的第一行 if(!G.move(3, i-3, G.t)){// 如果在点阵模型3行内不能进行向上位移(即点阵到游戏区顶部) alert('Game over!'); // 则Game over并提示 clearInterval(G.handle); // 良好习惯,清除计时器 } }, draw:function(){ for(var i=0;i<240;i++){// 遍历游戏区全点阵,每i为全点阵中的1点 if((G.v[parseInt(i/12)]>>(11-i%12))&0x1){ // G.v[parseInt(i/12)为该点所在行 // >>(11-i%12))&0x1为整体操作,&运算前将点移后,让&运算能判断点是否显示 G.fs[i].style.visibility = ''; // 判断为真则显示 }else if((G.m[parseInt(i/12)]>>(11-i%12))&0x1){ // 同上理画下落中的模型镜像点阵 G.fs[i].style.visibility = ''; G.fs[i].style.borderColor = G.fs[i].style.background = G.l[G.c]; // 上色 }else{ G.fs[i].style.visibility ='hidden'; // 判断为假则隐藏 } } for(var i=0;i<16;i++){ // 同理画预览区点阵 if(G.d[G._n][G._t]>>(15-i)&0x1){ G.fn[i].style.visibility = ''; G.fn[i].style.borderColor = G.fn[i].style.background = G.l[G._c]; }else{ G.fn[i].style.visibility ='hidden'; } } }, event:function(e,t){ switch(e.keyCode){ case 37: // 左键 G.move(G.x + 1, G.y, G.t); break; case 39: // 右键 G.move(G.x - 1, G.y, G.t); break; case 38: // 上键 G.move(G.x, G.y, (G.t + 1) % G.d[G.n].length); break; case 40: // 下键 G.timeTesk(); break; case 32: // 空格...看了半天才知道原来按空格直接落底... while(G.timeTesk()); } } } // --></mce:script> <body onload='G.init();'><!-- 网页读取后初始化 --> <div id='main'> <div id='body'></div> <div id='score'></div> <div id='level'></div> <div id='next'></div> <div id='ctrl'> <button onclick="javascript:location.href=location.href;">New</button> <!-- 重置等于重新读取网页 --> <button onclick="javascript:this.innerHTML={'true':'Start','false':'Pause'}[G.pause=!!!G.pause];">Pause</button> <!-- 这里运用了一个很好的技巧:!!的用法,可以将为空的数据转成false,避免出现空指针异常 --> </div> </div> </body> </html>
最后,提个希望,作品发表不应该只是为了制造崇拜吧?良好的注释是让崇拜你的人好好学习的途径哦。希望以后大家发表的作品多加点注释,让想进入这个领域的人能有路可寻。只有越来越多的人进入这一领域,这个领域才能更好的发展啊!(没人关注,有谁会投资啊?!工作都找不到这类的,当然就没人会感兴趣而很容易就末落了。)
相关推荐
在这个"全新版vue.js俄罗斯方块"项目中,开发者利用Vue.js的强大功能,结合算法,创建了一个完整的俄罗斯方块游戏。让我们深入探讨这个项目中的关键知识点。 1. **Vue.js组件化开发**: - Vue.js的核心理念是组件...
【JavaScript俄罗斯方块游戏开发详解】 在编程世界中,JavaScript是一种广泛应用的脚本语言,尤其在Web开发领域,它扮演着至关重要的角色。利用JavaScript,我们可以实现许多有趣的交互功能,其中之一就是开发游戏...
【标题】"js俄罗斯方块网页游戏代码"所涉及的知识点主要集中在JavaScript编程语言和网页游戏开发上。JavaScript,简称JS,是一种轻量级的解释型编程语言,主要用于客户端的网页脚本,使得用户与网页交互更加动态和...
【标题】:HTML5+JS实现俄罗斯方块 在网页上使用HTML5和JavaScript实现俄罗斯方块是一项常见的编程挑战,它涉及到多个技术层面,包括页面布局、事件处理、动画效果以及游戏逻辑。以下是对这个项目中涉及的关键知识...
《JavaScript实现俄罗斯方块》 在编程世界里,游戏开发是一项既能锻炼逻辑思维,又能提升技术实践能力的有趣任务。本文将围绕“JavaScript实现俄罗斯方块”这一主题,深入探讨如何利用JavaScript、CSS和HTML这三种...
python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。python基于pygame的俄罗斯方块小游戏源码。...
俄罗斯方块 是一款风靡全球的电视游戏机和掌上游戏机游戏,它由俄罗斯人阿列克谢·帕基特诺夫发明,故得此名。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除...
《JavaScript实现的Canvas版俄罗斯方块》 在编程领域,JavaScript是一种广泛使用的脚本语言,尤其在Web开发中,它为网页添加了动态交互性。本项目“Javascript俄罗斯方块(canvas版)”就是利用JavaScript的强大...
俄罗斯方块JS版俄罗斯方块JS版俄罗斯方块JS版俄罗斯方块JS版
《JavaScript实现的俄罗斯方块源码解析》 俄罗斯方块是一款经典的电子游戏,自1984年诞生以来,就以其简洁的规则和无尽的挑战性吸引了无数玩家。在这个数字化时代,用JavaScript来实现俄罗斯方块是一个很好的编程...
【JavaScript实现俄罗斯方块】 俄罗斯方块是一款经典的电子游戏,起源于1984年,由俄罗斯程序员阿列克谢·帕基特诺夫设计。这款游戏简单易上手,却又富有挑战性,深受全球玩家喜爱。JavaScript作为一种广泛应用于...
**JavaScript俄罗斯方块AI版**是一款基于Web的电子游戏,由JavaScript编程语言实现,它将传统的俄罗斯方块游戏与人工智能技术结合在一起,为玩家提供了一种全新的体验。在这个版本中,用户可以选择不同的游戏模式,...
JavaScript俄罗斯方块是一款基于网页的经典游戏,通过JavaScript编程语言实现。这款游戏的核心原理是利用二维数组来表示游戏板,以及各种形状的方块。在JavaScript中,我们通常会使用DOM(Document Object Model)来...
**JavaScript编写的俄罗斯方块游戏** 在编程教育中,通过创建实际的游戏项目,如俄罗斯方块,可以帮助学生更好地理解和掌握编程概念。这个项目利用JavaScript语言,一个广泛应用于网页开发的脚本语言,来实现经典的...
JavaScript 版本的俄罗斯方块是一款使用Web技术实现的经典游戏,它主要利用了JavaScript语言的事件处理、对象和类的概念来构建。以下是关于这个项目的一些关键知识点和详细说明: 1. **JavaScript**: 作为主要编程...
【俄罗斯方块(C语言版) 俄罗斯方块】是一个基于C语言实现的经典游戏项目,它将编程技术与游戏设计巧妙结合,展示了C语言在创建交互式程序方面的潜力。在这个项目中,开发者利用C语言的基本结构,如循环、条件语句...
【标题】"简单的js俄罗斯方块游戏源码.zip"是一个包含JavaScript实现的俄罗斯方块小游戏的源代码包。这款游戏以简洁的线条设计风格呈现,旨在为玩家提供一个基础的在线娱乐体验。 【描述】提到的"简单的js俄罗斯...
在JavaScript(JS)中实现俄罗斯方块是一种对游戏编程的有趣尝试,它展示了JS作为客户端脚本语言的强大功能。俄罗斯方块是一款经典的电子游戏,玩家需要控制不同形状的方块下落并组合成完整的行来消除得分。在这个...
《原生JS实现的俄罗斯方块小游戏解析》 在编程世界中,小游戏是学习和实践技术的绝佳途径,尤其对于JavaScript这种广泛应用于网页开发的脚本语言来说。本篇文章将详细解析一个使用原生JavaScript编写的俄罗斯方块小...
javascript写的俄罗斯方块,简单易学,一看就懂