js解决按键事件监听被覆盖问题

问题描述

今天晚上,和小伙伴一块用js canvas完成童年回忆坦克大战,做到一半时,发现这样一个问题。当我按住上移动按钮之后同时按住右移动按钮,再松开右按钮,坦克没有向上移动,而是停止了移动,这极其不符合预期效果。

思考

首先,这个问题是由于js是单线程,按键事件监听现有的会覆盖掉之前的,因此不会再触发原有按键事件。

解决方法

我这里提出一个方案:
引入一个全局数组,用于记录已按按键,此数组只允许存储标识按键的值,并且不允许重复值,再到定时器中循环执行数组内对应按键所执行的操作移动操作,定时器循环执行时间间隔为游戏的帧数。
OK,可以开干了

解决demo代码

<!DOCTYPE html>
<html>
	<head>
			<meta charset="utf-8">		
			<title></title>	
			</head>	
			<body style="width: 100%;height: 689px;">	
				<div id="tank" style="position: relative;width: 50px;height: 50px;background-color: aqua;left:100px;top: 100px;">					</div>	
					<script>	
							const tank=document.getElementById("tank")		
								const contrlArr = []	
									addEventListener("keydown", (e) => {	
												if ([37, 38, 39, 40].includes(e.keyCode))
												 {					if (e.keyCode == 37) {	
												 					console.log("左");					}					
												 					if (e.keyCode == 38) {			
												 								console.log("上");		
												 											}			
												 					if (e.keyCode == 39) {		
												 									console.log("右");		}					
							if (e.keyCode == 40) {						console.log("下");					}					if (!contrlArr.includes(e.keyCode)) {						contrlArr.push(e.keyCode)					}				}							})			addEventListener("keyup", (e) => {				if ([37, 38, 39, 40].includes(e.keyCode)) {					if (e.keyCode == 37) {						console.log("左");					}					if (e.keyCode == 38) {						console.log("上");					}					if (e.keyCode == 39) {						console.log("右");					}					if (e.keyCode == 40) {						console.log("下");					}					contrlArr.map((v, i) => {						if (v == e.keyCode) {							contrlArr.splice(i, 1)						}					})				}			})			// 控制移动帧数			setInterval(()=>{				contrlArr.map((v,i)=>{					if(contrlArr.length&&contrlArr.length==(i+1)){						if (v == 37) {						tank.style.left=parseInt(tank.style.left.replace("px",""))-2+"px"						console.log("左");					}					if (v == 38) {						tank.style.top=parseInt(tank.style.top.replace("px",""))-2+"px"						console.log("上");					}					if (v == 39) {						tank.style.left=parseInt(tank.style.left.replace("px",""))+2+"px"						console.log("右");					}					if (v == 40) {						console.log("xia",tank.style.top);						tank.style.top=parseInt(tank.style.top.replace("px",""))+2+"px"						console.log("下");					}					}				})			},100)		</script>
	</body>
</html>

备注

手机上敲的,请谅解这个代码样式,若感兴趣请移步到坦克大战移动小demo
该项目由上下左右方向键控制蓝色块移动

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值