javascript 长按键盘问题?

<html><head><title>贪吃蛇</title></head><bodyonkeydown="hero.move(event)"><divid="filed"... <html>
<head>
<title>贪吃蛇</title>
</head>

<body onkeydown="hero.move(event)">
<div id="filed" style="background-color:pink;width:500px;height:400px;position:absolute">
<div id="mytank" style="background-position-y:-40px;background-image:url('tank.png');position:absolute;width:40px;height:40px;">
</div>
</div>
<script lanugage="javascript" type="text/javascript">
//用面向对象的方法开发,web版本的坦克大战1.0(可以通过asdf键来控制坦克的走向)
function MyTank(x,y,direct){
this.x=x;//坦克的横坐标
this.y=y;//坦克的纵坐标
this.direct=direct;//方向
this.speed=1;//速度
flag=false;
mytank.style.left=this.x+"px";
mytank.style.top=this.y+"px";
//移动方向
function directF(val,that){
switch(val){
case 3:
that.x=that.x-5;
mytank.style.left=that.x+"px";
flag=true;
break;
}
}
//初始化
this.move=function(event){
that=this;
if(flag==true){
window.clearInterval(value);
flag=false;
}

switch(event.keyCode){
case 65:
//a表示左
//this.x-=this.speed;
this.direct=3;
mytank.style.backgroundPositionY="80px";
value=window.setInterval(function(){
directF.call(this,3,that);
},100);
break;
}
}
}
var hero=new MyTank(200,300,0);
</script>
</body>
</html>
长按A的话会加速移动,但是一下一下按可以正常运行,这是为什么?
展开
 我来答
hutia
2014-11-10 · TA获得超过580个赞
知道小有建树答主
回答量:97
采纳率:100%
帮助的人:158万
展开全部

代码写的太烂。。。。

一些问题点:

1、 flag 请用 var 声明(否则会变成全局变量,污染别的代码)

2、 flag 设置的位置有问题

3、 flag 的使用逻辑有问题



下面是完整代码(注意看用 /** */ 注释的地方):

function MyTank(x,y,direct){
this.x=x;//坦克的横坐标
this.y=y;//坦克的纵坐标
this.direct=direct;//方向
this.speed=1;//速度
var flag=false; /** 记得用 var */
mytank.style.left=this.x+"px";
mytank.style.top=this.y+"px";
//移动方向
function directF(val,that){
switch(val){
case 3:
that.x=that.x-5;
mytank.style.left=that.x+"px";
/** flag=true; 这句不要放在这里 */
break;
}
}
//初始化
this.move=function(event){
that=this;
if (flag == event.keyCode) return false; /** 如果已经沿目标方向运行,则不用处理 */
if (flag) {
window.clearInterval(value);
flag=false;
}

switch(event.keyCode){
case 65:
//a表示左
//this.x-=this.speed;
this.direct=3;
mytank.style.backgroundPositionY="80px";
flag = event.keyCode; /** 设置 flag */
value=window.setInterval(function(){
directF.call(this,3,that);
},100);
break;
}
}
}
var hero=new MyTank(200,300,0);
追问
学东西了,我写得的确难,但是我还想知道我代码导致它长按会加速的原因?
追答
原因就在我改了以后,标记注释的那几处。最好能通过读代码来学习,对你的提高会有很大好处。

我试着解释一下吧(其实不会有你仔细读代码来的体会深刻):

根本原因在于, flag 的作用是标记你有没有 setInterval。可是你原来的代码里,要等到 directF 被调用后才会设置 flag。这就带来一个问题:如果连续调用 move 函数,那么你 setInterval 延迟调用的 directF 还没有被执行,就又再一次的 setInterval 了。期望的逻辑是 setInterval 只被调用一次,可是在你一直按住按键的时候, setInterval 被调用了很多次。

那么为什么我要设置 flag = keyCode 呢?

是因为,如果我在setInterval 之前就设置 flag 的话,带来一个后果,就是一直按住按键的时候,你会发现 tank 它不动了。为啥会这样?因为你刚 setInterval 结束,就又调用了一次 move,而 move 的开始部分会 clearInterval。。。综合下来的结果就是,按住按键,tank不动,手松开,tank 开始移动。

怎么解决这个问题呢?我记录下来当前的按键,保存在 flag 里。如果下次再调用 move 函数的时候,先检查一下,当前的按键和 flag 里的是否相同。如果相同,那么显然就是一直按住的按键(或者重复按键了),那么不予理会就可以(return)。如果不同,那么就正常的流程逻辑走下去即可。

====我是努力的分割线====
能知道自己水平需要提高,就是非常好的童鞋啦。。。好好努力吧。。。
少问,多写代码练习,多读别人的代码。。。。
少上知道,多上知乎。。。
祝你进步~~
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式