最近出于兴趣,想做个h5小游戏,但一开始就发现键盘连续点击会出现很明显的延时,这个我之前看过一个文案是说防止输入的时候按键keyup相对慢一点就输一大堆文字,导致输入有问题。其实这个很合理,但置于js游戏里面会很不合理。
先看一下没有解决之前的代码
<div id="a"></div>
<style>
#a{
position: relative;
height: 100px;
width: 100px;
background-color: #111;
}
</style>
<script>
var a = document.getElementById('a'),//获取a
translateX = 0,//translateX初始值,并作为动作的关键
translateY = 0,//translateY初始值,并作为动作的关键
step = 1 //keydown时候的步伐(可以理解为速度)
window.onkeydown=function(e){
//筛选不同的按键事件
switch(e.keyCode){
case 38:
translateY -=step //up
break
case 40:
translateY +=step //down
break
case 37:
translateX -=step //left
break
case 39:
translateX +=step //right
break
default:
break
}
//a执行动作
a.style.transform = `translate(${translateX}px,${translateY}px)`
}
</script>
明显当你换个按钮或者直接按下去的时候会有500ms延时(这个我自己通过new Date().getTime()测过)
后来我参考了墙外的一些小哥的回答,通过设定参考值,通过定时器来执行a的动作。我瞬间豁然开朗。。。确实当你一筹莫展的时候问一下其他人的意见还是焕然一新,在代码海洋中沉溺太久,有时候是“众人皆醒你独醉”。下面是完善后的代码。。。
<div id="a"></div>
<style>
#a{
position: relative;
height: 100px;
width: 100px;
background-color: #111;
}
</style>
<script>
//设定一个对象做参考值,这个不一定是对象obj,可以直接设定status=[0,0,0,0],当然这时后面的代码全部要改
var obj = {
status:[0,0,0,0]//[up+1,down-1,left-1,right+1]
}
var translateX = 0,
translateY = 0,
step = 1
window.onkeydown = function (e) {
switch(e.keyCode){
case 38:
obj.status[0] = step //up
break
case 40:
obj.status[1] = step //down
break
case 37:
obj.status[2] = step //left
break
case 39:
obj.status[3] = step //right
break
default:
break
}
}
window.onkeyup = function (e) {
switch(e.keyCode){
case 38:
obj.status[0] = 0 //up
break
case 40:
obj.status[1] = 0 //down
break
case 37:
obj.status[2] = 0 //left
break
case 39:
obj.status[3] = 0 //right
break
default:
break
}
}
function handleStatus() {
//X轴的值
translateY += obj.status[1] - obj.status[0]
//Y轴的值
translateX += obj.status[3] - obj.status[2]
//a动作
a.style.transform = `translate(${translateX}px,${translateY}px)`
}
//定时器一直读取参考值
setInterval(handleStatus,10)
</script>
这时候已经搞定了,但说实话我不喜欢switch代码虽然好,但我不喜欢它的累赘,所以我简化了代码,而且存在定时器又不去关闭的时候会影响到内存,所以添加了keyup的时候关闭定时器
<div id="a"></div>
<style>
#a{
position: relative;
height: 100px;
width: 100px;
background-color: #111;
}
</style>
<script>
var obj = {
status:[0,0,0,0]//[up+1|down-1,left-1|right+1]
}
var keyCode_data = {
38: 0,
40: 1,
37: 2,
39: 3,
}
var translateX = 0,
translateY = 0,
step = 1,
timer = false
window.onkeydown = function (e) {
obj.status[keyCode_data[e.keyCode]] = step
!timer ? setTimer() : false
}
window.onkeyup = function (e) {
obj.status[keyCode_data[e.keyCode]] = 0
obj.status.indexOf(step) == -1 ? clearTimer() : false
}
function handleStatus() {
translateY += obj.status[1] - obj.status[0]
translateX += obj.status[3] - obj.status[2]
a.style.transform = `translate(${translateX}px,${translateY}px)`
// console.log(123) //测试定时器是否关闭
}
function setTimer() {
timer = setInterval(handleStatus,10)
}
function clearTimer() {
clearInterval(timer)
timer = false
}
</script>