防止按钮在按住时持续触发

问题描述

我试图防止特定按钮持续触发,但我的任何方法都没有成功。我已经尝试了其他 stackoverflow 帖子中的几个建议/答案,但都没有奏效。我目前有一个控制器,对于我的左/右按钮,我不在乎它们是否重复,但是对于我的跳跃按钮,我不希望能够按住按钮并让角色继续跳跃。我最接近完成这项工作的方法是使用地图并将按钮设置为它,但不幸的是,在 keyup 上,角色也会跳跃。这是我当前的代码

class Controller {
    constructor() {
        this.left  = false;
        this.up    = false;
        this.right = false;
        this.down  = false;
        this.pressed = {};

        let keyDown = (e) => {
            if (e.code == 'ArrowLeft')  this.left = true;
            if (e.code == 'ArrowRight') this.right = true;
            if (e.code == 'ArrowDown')  this.down = true;
           
            if (e.code === 'ArrowUp') {
                if (this.pressed[e.code] === false) { return }
                else {
                    this.pressed[e.code] = false;
                    this.up = true;
                }
            } 
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowLeft')  this.left = false;
            if (e.code == 'ArrowRight') this.right = false;
            if (e.code == 'ArrowDown')  this.down = false;
            if (e.code === 'ArrowUp') {
                this.pressed[e.code] = true;
                this.up = false;
            }
        }
    window.addEventListener('keydown',keyDown);
    window.addEventListener('keyup',keyUp);
   }
   
}
let controller = new Controller();

以及我也尝试过的一些替代方案

        this.pressed = false;
        let keyDown = (e) => {
            if (e.code == 'ArrowLeft')  this.left = true;
            if (e.code == 'ArrowRight') this.right = true;
            if (e.code == 'ArrowDown')  this.down = true;
            console.log(controller.pressed)
            if (e.code === 'ArrowUp') {
                if (!this.pressed) { return }
                this.pressed = false;
                this.up = true;
            } 
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowLeft')  this.left = false;
            if (e.code == 'ArrowRight') this.right = false;
            if (e.code == 'ArrowDown')  this.down = false;
            if (e.code === 'ArrowUp') {
                this.pressed = true;
                this.up = false;
            }
        }
       this.pressed = false;
       let keyDown = (e) => {
            if (e.code == 'ArrowLeft')  this.left = true;
            if (e.code == 'ArrowRight') this.right = true;
            if (e.code == 'ArrowDown')  this.down = true;
            if (!this.pressed) { 
                this.pressed = true;    
                if (e.code == 'ArrowUp') { 
                    this.up = true;
                }   
            } 
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowLeft')  this.left = false;
            if (e.code == 'ArrowRight') this.right = false;
            if (e.code == 'ArrowDown')  this.down = false;
            if (e.code == 'ArrowUp') {
               this.pressed = false;
               this.up = false;
            }
        }

从逻辑上讲,我觉得这些应该可行,但实际上行不通。以防万一我的角色基于此跳跃

if (controller.up && !this.jumping) {this.vy -= this.speed * 60; this.jumping = true;}

我可能尝试过至少 10 种不同的方法,最接近的是我的角色在停止之前跳了两次(同时按住箭头)。

编辑:这给出了 2 次跳跃然后停止。谁能解释为什么他在停下之前跳了两次?

this.keySet = new Set();

        let keyDown = (e) => {
            if (e.code == 'ArrowUp') {
                if (this.keySet.has(e.code)) { this.up = false } 
                else { this.keySet.add(e.code); this.up = 'keydown' === e.type }
            }            
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowUp') { this.keySet.delete(e.code); this.up = false }            
        }

解决方法

你可以throttle函数

限制的工作方式是,当您调用一个函数时,它会像往常一样执行该函数,但在随后的调用中,它不会再次运行,直到自上次尝试执行后经过足够长的时间。

Lodash 有一个实现,但你可以在互联网上找到它的版本:https://lodash.com/docs/4.17.15#throttle