JS实战之俄罗斯方块详解.docx
《JS实战之俄罗斯方块详解.docx》由会员分享,可在线阅读,更多相关《JS实战之俄罗斯方块详解.docx(17页珍藏版)》请在冰豆网上搜索。
JS实战之俄罗斯方块详解
目录
俄罗斯方块编写思路2
纯净代码2
代码注释4
程序一;简单计算器8
程序二,九九乘法表11
俄罗斯方块编写思路
要实现一个功能首先要明确这个功能有哪些动作,然后分解动作,一一实现
俄罗斯方块要分为下面这几块
场景地图、俄罗斯方块图案、随机生成俄罗斯方块、俄罗斯方块下落、左右移动、旋转、检查方块是否与场景重合,是否到底,是否与以后图案重合、更新场景,以及游戏结束,大致这么几块内容,
纯净代码
下面附上原有代码以代码分析
注:
这个适合有一定JS编程基础的人来看
原有60行代码:
只可以实现简单的俄罗斯方块功能,没有暂停,保存,重新开始,等级,调节降落速度这些。
画面如下;
doctypehtml>
252px;font:25px/25px宋体;background:#000;color:#9f9;border:#99920pxridge;text-shadow:2px3px1px#0f0;">
252px;font:
25px/25px宋体;background:
#000;color:
#9f9;border:
#99920pxridge;text-shadow:
2px3px1px#0f0;">
varmap=eval("["+Array(23).join("0x801,")+"0xfff]");
vartatris=[[0x6600],[0x2222,0xf00],[0xc600,0x2640],[0x6c00,0x4620],[0x4460,0x2e0,0x6220,0x740],[0x2260,0xe20,0x6440,0x4700],[0x2620,0x720,0x2320,0x2700]];
varkeycom={"38":
"rotate
(1)","40":
"down()","37":
"move(2,1)","39":
"move(0.5,-1)"};
vardia,pos,bak,run;
functionstart(){
dia=tatris[~~(Math.random()*7)];
bak=pos={fk:
[],y:
0,x:
4,s:
~~(Math.random()*4)};
rotate(0);
}
functionover(){
document.onkeydown=null;
clearInterval(run);
alert("GAMEOVER");
functionupdate(t){
bak={fk:
pos.fk.slice(0),y:
pos.y,x:
pos.x,s:
pos.s};
if(t)return;
for(vari=0,a2="";i<22;i++)
a2+=map[i].toString
(2).slice(1,-1)+"";
for(vari=0,n;i<4;i++)
if(/([^0]+)/.test(bak.fk[i].toString
(2).replace(/1/g,"\u25a1")))
a2=a2.substr(0,n=(bak.y+i+1)*15-RegExp.$_.length-4)+RegExp.$1+a2.slice(n+RegExp.$1.length);
document.getElementById("box").innerHTML=a2.replace(/1/g,"\u25a0").replace(/0/g,"\u3000");
functionis(){
for(vari=0;i<4;i++)
if((pos.fk[i]&map[pos.y+i])!
=0)returnpos=bak;
functionrotate(r){
varf=dia[pos.s=(pos.s+r)%dia.length];
pos.fk[i]=(f>>(12-i*4)&15)<update(is());}functiondown(){++pos.y;if(is()){for(vari=0;i<4&&pos.y+i<22;i++)if((map[pos.y+i]|=pos.fk[i])==0xfff)map.splice(pos.y+i,1),map.unshift(0x801);if(map[1]!=0x801)returnover();start();}update();}functionmove(t,k){pos.x+=k;for(vari=0;i<4;i++)pos.fk[i]*=t;update(is());}document.onkeydown=function(e){eval(keycom[(e?e:event).keyCode]);};start();run=setInterval("down()",400);代码注释下面是带注释的代码:水平有限,只能到这一步doctypehtml>
update(is());
functiondown(){
++pos.y;
if(is()){
for(vari=0;i<4&&pos.y+i<22;i++)
if((map[pos.y+i]|=pos.fk[i])==0xfff)
map.splice(pos.y+i,1),map.unshift(0x801);
if(map[1]!
=0x801)returnover();
start();
update();
functionmove(t,k){
pos.x+=k;
pos.fk[i]*=t;
document.onkeydown=function(e){
eval(keycom[(e?
e:
event).keyCode]);
};
run=setInterval("down()",400);
代码注释
下面是带注释的代码:
水平有限,只能到这一步
#box{
width:
252px;
font:
25px/25px宋体;/*style为normalsize为25像素行高为25像素字体为宋体*/
background:
#000;
color:
#99FF99;
border:
#99920pxridge;/*根据color的值画3D凸槽。
线宽为20像素的999颜色的3D凸槽*/
text-shadow:
2px3px1px#0f0;/*字体阴影模糊效果由颜色、水平方向、垂直方向、模糊效果的作用距离*/
--id为boxhtml中注释用这种-->
varmap=eval("["+Array(23).join("0x801,")+"0xfff]");//eval的功能是把字符串编程实际运行时的JS代码,eval检查JS代码并执行,并赋值给map。
map顾名思义就是地图也就是说先把地图给出来。
array是存储数组中元素的个数,23就是说数组中一共有23个元素。
join是用于把数组中的所有元素放入一个字符创,例子中是放入了“0x801,”这个字符串,最后以“0xfff为结尾”组合成数组如下所示。
//varmap=[0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0x801,0xfff]
//把十六进制的数字换算成二进制如下
//100000000001对应16进制0x801
//111111111111对应16进制0xfff
//地图为U型地图数字1包围的区域为数据存贮区22行10列
vartatris=[[0x6600],
[0x2222,0x0f00],
[0xc600,0x2640],
[0x6c00,0x4620],
[0x4460,0x2e0,0x6220,0x740],
[0x2260,0xe20,0x6440,0x4700],
[0x2620,0x720,0x2320,0x2700]];
//这个数组里面定义的是方块的7种形状(即7个子数组),二进制分四行表示
//0x66000x22220xf00
//011000101111
//011000100000
//000000100000
//0xc6000x26400x6c000x4620
//1100001001100100
//0110011011000110
//0000010000000010
//0000000000000000
//其余同理太累了不想写了可以自己写着试试
varkeycom={
"38":
(1)",
"40":
"down()",
"37":
"move(2,1)",
"39":
"move(0.5,-1)"
//38,40,37,39对应着上下左右按键的数值,将他们与需要调用的函数一一对应。
vardia,pos,bak,run;//dia存储选取的俄罗斯方块类型;pos是正在下落的方块的团对象;bak存储pos团对象的备份,在需要的时候可以实现对于pos运动的撤销。
dia=tatris[~~(Math.random()*7)];//在7种图案中随机选择一种,~在JS中是位取反运算,间接实现了浮点数到整形的转换,也就是取整。
因为取反应该是只能对整数取反。
[],//一个数组,存贮的是图案转化之后的二进制数据
y:
0,//初始Y坐标
x:
4,//初始X坐标
s:
~~(Math.random()*dia.length)};//在选中的方块类型中随机选择一个团
//pos与bak分别是前后台,实现俄罗斯方块的备份与撤销
rotate(0);//初始不旋转
}//在游戏场景上方产生一个新的俄罗斯方块
document.onkeydown=null;//撤销onkeydown事件
clearInterval(run);//清理之前设置的方块下落定时器
alert("GAMEOVER");//显示游戏结束
}//游戏结束
pos.s};//把pos备份到bak中,slice(0)意为从0号开始到结束的数组,即全部数组
if(t){return;}
(2).slice(1,-1)+"";//2是参数,制定基地,2的话就是返会二进制串的形式。
slice(-1,1)参数-1,1作用是取除了墙之外的中间场景数据
//根据map进行转换,得到的是01加上换行的字符串
(2).replace(/1/g,"\u25a1")))//这里涉及到正则表达式我还没有学到,只能复制别人的
//对于a2字符串进行替换,并且显示在div之中,这里是应用////\u25a0是黑色方块\u3000是空,这里实现的是替换div之中的文本,由数字替换成为两种方块或者空白
a2=a2.substr(0,n=(bak.y+i+1)*15-RegExp.$_.length-4)+RegExp.$1+a2.slice(n+RegExp.$1.length);//这里是对字符串替换处理,把原始的0,1换成方块字符串
}//此函数用于绘制场景的字符串,并且写入到div中完成游戏场景的更新
varf=dia[pos.s=(pos.s+r)%dia.length];//把pos.s值与r相加然后和dia.lenght求余,赋值给pos.s,实现旋转
pos.fk[i]=(f>>(12-i*4)&0x000f)<update(is());//更新场景}//旋转图案,functionis(){for(vari=0;i<4;i++)if((pos.fk[i]&map[pos.y+i])!=0)returnpos=bak;//对当前俄罗斯方块图案进行逐行分析,把俄罗斯方块图案的每一行的二进制与场景内的二进制进行位与(位与:相同才可以,具体自己查),如果结果非0(即都是1,说明与墙重合了或者是落底了),那么就证明图案与场景中的实体重合了,重合了就把之前备份的bak来实现对pos的恢复//如果没有重合,那么这里默认返回空。}//判断有没有重叠functiondown(){++pos.y;//Y坐标增加,相当于下落if(is()){for(vari=0;i<4&&pos.y+i<22;i++)if((map[pos.y+i]|=pos.fk[i])==0xfff){//如果行满了map.splice(pos.y+i,1);map.unshift(0x801);}//首航添加一行0x801,unshift的作用就是在数组的第0好元素之前添加新的元素,新的元素作为数组首元素if(map[1]!=0x801)returnover();//如果最上面一行不是空行,则执行over()命令start();//重新产生一个新的俄罗斯方块}//如果方块与场景重合的话is(),update();//全局更新}//方块下落functionmove(t,k){pos.x+=k;for(vari=0;i<4;i++)pos.fk[i]*=t;//*=t实现了左右平移update(is());//位移完了判断是否重合,重合的话就不更新场景}//左右位移document.onkeydown=function(e){eval(keycom[(e?e:event).keyCode]);};//eval生成的代码在这里执行start();run=setInterval("down()",500);//定时器,500ms下落一次下面附上两个外带小程序:程序一;简单计算器功能可以计算简单的+-*/可以清楚,其余功能没有代码如下doctypehtml>
update(is());//更新场景
}//旋转图案,
=0)
returnpos=bak;
//对当前俄罗斯方块图案进行逐行分析,把俄罗斯方块图案的每一行的二进制与场景内的二进制进行位与(位与:
相同才可以,具体自己查),如果结果非0(即都是1,说明与墙重合了或者是落底了),那么就证明图案与场景中的实体重合了,重合了就把之前备份的bak来实现对pos的恢复
//如果没有重合,那么这里默认返回空。
}//判断有没有重叠
++pos.y;//Y坐标增加,相当于下落
if((map[pos.y+i]|=pos.fk[i])==0xfff){//如果行满了
map.splice(pos.y+i,1);
map.unshift(0x801);}//首航添加一行0x801,unshift的作用就是在数组的第0好元素之前添加新的元素,新的元素作为数组首元素
=0x801)returnover();//如果最上面一行不是空行,则执行over()命令
start();//重新产生一个新的俄罗斯方块
}//如果方块与场景重合的话is(),
update();//全局更新
}//方块下落
pos.fk[i]*=t;//*=t实现了左右平移
update(is());//位移完了判断是否重合,重合的话就不更新场景
}//左右位移
};//eval生成的代码在这里执行
run=setInterval("down()",500);//定时器,500ms下落一次
下面附上两个外带小程序:
程序一;简单计算器
功能可以计算简单的+-*/可以清楚,其余功能没有
代码如下
*{
padding:
0;
margin:
1px;
.numberkey{
cursor:
pointer;
40px;
height:
30px;
border-bottom:
solid1px#FFFFFF;
#2371D3;
#ffffff;
text-align:
center;
font-weight:
bold;
font-family:
黑体;
#display{
100%;
solid4px#2371D3;
#193D83;
padding-left:
2px;
#equality{
#calculater{
auto;
margin-top:
solid6px#2371D3;
border-spacing:
0
1
2
3
+
←
4
5
6
-
=
7
8
9
*
+/-
.
/
varresults="";
varcalresults="";
functioncalculater(){
if(event.srcElement.innerText=="←"){
results="";
display.innerText="0";
return;
}if(event.srcElement.innerText=="="){
results+=event.srcElement.innerText;
display.innerText=results;
functionresultcalcaulte(){
calresults=eval(results);
display.innerText=calresults;
界面如下:
程序二,九九乘法表
table{
100px;
varstr="";
str+='';
for(vari=1;i<=9;i++){
str+="
for(varj=1;j<=9;j++){
if(i<=j){
else{
str+="none>"+"";}}str+="
none>"+"";
str+="";
document.write(str);
document.write("");
界面如下;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1