俄罗斯方块就是通过键盘来控制各种小方块的旋转和下落,根据小方块的堆积来进行有戏。方块在一行堆满后就可以消掉,方块堆积至窗口顶端有戏就结束了。
“那么假如我们要做一个俄罗斯方块有戏,我们该从那里入手?”
“需求”女友没有摆脱学院派的影子。
“因为大家对这个游戏都很了解,那么需求我们就先绕过去,毕竟我们不是正规军。我们直接从开发着手分析问题。从开发的角度来看,我们需要先解决什么问题?”
“嗯,开发角度?那包含什么内容?”不按照常理出牌,她立马理不清头绪。
“如果从开发的角度来说,需要将问题按照技术处理的关键来分,比如说图形该怎么处理,运动该怎么控制,程序中的每个逻辑层该如何划分等等。”
“那就是说先要将问题细分,将每个处理的关键技术解决了,再根据系统总的要求进行具体开发,那么系统也就做出来了。”看来她还有点小聪明,一点就通。
“如果是按照这么说的话,俄罗斯放宽涉及到的问题就有:键盘控制,图形呈现,有戏算法这三个部分。”看来来她有点得意了,一口气把知道的全给说出来了。
“作为游戏开发,这里面时钟也是个需要处理的关键问题,否则方块就不会动了。那么我们今天首先要解决的问题就是关于在web上响应键盘,做一个可以根据键盘上下左右翼懂得小方块。首先我们先看看代码。”
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
</head>
<body>
<div id="dSquare" style="background:#0000FF;POSITION: absolute; width:20px; height:20px; top:50px; left:200px;"></div>
</body>
</html>
<script language=javascript>
if(typeof GetControl=="#ff0000") GetControl=function (id)
{
return document.getElementById(id);
};
var control=GetControl("dSquare");
function KeyDown(e) {
var key;
try{
key=event.keyCode; //取得键盘Code编号
}
catch(a){ //对于Firefox来说,不支持event.keyCode
key=KeyDown.arguments[0].keyCode;
}
switch(key)
{
case 40://40 == down
control.style.top=(parseInt(control.style.top)+1)+ "px";
break;
case 39://39 == right
control.style.left=(parseInt(control.style.left)+1)+ "px";
break;
case 38://38 == up
control.style.top=(parseInt(control.style.top)-1)+ "px";
break;
case 37://37 == left
control.style.left=(parseInt(control.style.left)-1)+ "px";
break;
}
}
document.onkeydown=KeyDown; //附加事件
document.onkeypress=KeyDown; //附加事件
</script>
在这个代码中,我们需要关注代码中的5点:
1:document;
2:id="dSquare";
3:getElementById
4:document.onkeydown=KeyDown;
5:event.keyCode,
1.document 是浏览器提供的客户端对象模型,而且document对象是一个顶层对象,不需要预先实例化就可直接使用。所以这个对象和Div存在区别,浏览器所提供的客户端模型中也存在Div模型,但是这个模型需要根据指定的ID来进行访问。在Javascript中,可以对浏览器提供的各种对象模型进行操作,可以修改对象模型的属性,和调用对象模型的函数和给对象模型附加事件。但是使用过程中需要注意的问题是:由于不同浏览器提供的对象模型并不完全一致,而是彼此存在差异,所以提供的属性或函数中就存在不同,这些不同也就造成了Javascript多浏览器的问题。
2.id="dSquare",这里我们实际上关注的是DOM对象问题,再HTML中所有的元素都存在对应的DOM模型,如果我们需要访问这些模型,通过ID是比较快捷的一种方法,而且这个ID尽量避免一样,就下我们每个人使用的身份证一样。
3.getElementById,是内置对象提供的一个方法,用于访问指定ID的对象,如果对象不存在的话,就会返回一个null值。
4.document.onkeydown=KeyDown;这是比较典型的Javascript时间附加的方式,对于Javascript中,对于事件附加的处理之需要定义之需要函数明就可以了,具体函数的操作可以参考Javascript中各种函数的定义,如对象内函数,一般函数等。
5.event.keyCode ,这部分代码主要是针对多浏览器处理的,可以看到代码中存在有一个try catch的处理,这个是由于firefox中没有提供event.keyCode,所以需要通过KeyDown.arguments[0].keyCode的方式来访问参数,这里面需要注意的是在Javascript中函数参数的访问方式,如固定参数,和动态参数的访问。
“我听完这些头都有点大了。”等我将代码注意部分简单讲完,她已经开始有点晕头转向。“document对象模式我可以理解,不就是浏览器客户端中提供的各种对象,这个其实和DOM模式应该是描述的一件事情,Javascript根据DOM的模型进行对应的各种处理。”
“是的,所以如果你在浏览器上使用其他的对象模型,比如表格的话,可以根据浏览器提供的DOM信息,去确认对象的属性和函数是否存在,在具体开发中根据需要去查资料。”
“if(typeof GetControl=="#ff0000") GetControl=function (id)这部分代码就比较奇怪,我们又看明白?你为什么不写成这个样子,我看代码也能运行。“
function GetControl(id)
{
return document.getElementById(id);
};
“其实这段代码有两个概念需要说明,1:关于变量的定义,由于在Javascript中对于变量的定义比较灵活,可以使用Var固定作用域,也可以不使用Var,如果没有使用var 的变量,就会被当成全局变量,所以这里GetControl是全局变量。2:关于函数的定义方式的灵活性也在这里面体现出来,说明函数的声明不是只有function GetControl(id)一种形式。”
“key=KeyDown.arguments[0].keyCode; 为什么不使用KeyDown(e)中的e呢?“
“对于key=e.keyCode的处理也是可以的,对于Javascript中,对于函数参数的处理和其他高级语言存在比较大的区别,这里需要注意。“
“通过try catch取得KeyCode的方式我总觉得不好,有没有别的办法?”
“嗯,通过异常的方式去取值确实是一种不好的开发习惯,在这里可以有多种方式去取的KeyCode,而且不会引起异常。比如说判断浏览器类型,然后根据不同的浏览器去取的不同的方式。还有以下的这种方式也能取得KeyCode。主要是利用判断的方式去调用不同的方法取值。“
var key = window.event ? window.event.keyCode : e.which;
“好了,代码就这些,这个小方块能够移动的原因就在于在Key按下后,触发了我们附加的事件函数,在函数中我们通过key的值来修改Div的style 的位置值,这样就达到了运动的效果。Key事件的触发也为我们开发俄罗斯方块解决了第一个关键问题。“
“还有,这个课还有一个课后作业,就是修改代码,判断如果方块移动到浏览器的边界后,就不能再往外移动,不能让浏览器出现滚动边框。”
“还要有作业,我才不做呢。”