js游戏键盘延时问题完美解决方案

本文探讨了解决H5游戏中键盘操作延时的问题,通过使用定时器和状态对象优化了键盘事件处理,实现了流畅的游戏体验。

最近出于兴趣,想做个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>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值