如何为P5.js中的keyPressed()函数进行时间缓冲?

时间:2018-08-14 04:31:07

标签: javascript p5.js

我在P5.js环境中制作了一个简单的Snake游戏, 而且我有一件事要修复。

所以,我有用于keyPressed()函数的代码

function keyPressed(){
    if(keyCode === LEFT_ARROW) {
        if(snake.yspeed == 1 || snake.yspeed == -1) {
            snake.yspeed = 0;
            snake.xspeed = -1;
        }
    }else if(keyCode === RIGHT_ARROW) {
        if(snake.yspeed == 1 || snake.yspeed == -1) {
            snake.yspeed = 0;
            snake.xspeed = 1;
        }
    }else if(keyCode === UP_ARROW) {
        if(snake.xspeed == 1 || snake.xspeed == -1) {
            snake.xspeed = 0;
            snake.yspeed = -1;
        }
    }else if(keyCode === DOWN_ARROW) {
        if(snake.xspeed == 1 || snake.xspeed == -1) {
            snake.xspeed = 0;
            snake.yspeed = 1;
        }
    }
}

yspeed是垂直运动,xspeed是水平运动。

因此,如果蛇向右移动,即使我按了LEFT_ARROW,蛇也不会向左转。但是,如果我按UP_ARROWDOWN_ARROW并快速按LEFT_ARROW,则蛇会立即向左转并撞向自己。

因此,我想在按下箭头键之一后为keyPressed()函数添加缓冲时间。

如何在P5.js中做到这一点?

2 个答案:

答案 0 :(得分:1)

我也做了snake game,遇到了这个确切的问题。 我用香草javascript编写了它,并将fps设置为12,这使玩家有足够的时间在两个周期之间两次改变方向。


解决方案

我的解决方案是使用一个缓冲区变量来存储上次按下的方向。在您的情况下,可能看起来像这样

onChange={e => {
    const val = e.target.value;
    this.props.change('FieldNameAlt', val)
}};

实际上只有在我在let dir = ''; function keyPressed(){ if(keyCode === LEFT_ARROW) dir = 'LEFT'; if(keyCode === RIGHT_ARROW) dir = 'RIGHT'; if(keyCode === UP_ARROW) dir = 'UP'; if(keyCode === DOWN_ARROW) dir = 'DOWN'; } 中调用蛇的update()方法之前更改其方向:

draw()

您只需要在function draw() { ... snake.direction(dir); snake.update(); snake.draw(); ... } 方法中检查移动是否有效。

direction()

(我从我的代码中复制了此代码,但您明白了)


工作原理

让我们举个例子。

在您的游戏中,正在发生的事情是,它首先将蛇的速度更改为指向this.direction = function(d) { switch(d) { case 'LEFT': if (this.xv != 1) {this.xv = -1; this.yv = 0;} break; case 'RIGHT': if (this.xv != -1) {this.xv = 1; this.yv = 0;} break; case 'UP': if (this.yv != 1) {this.xv = 0; this.yv = -1;} break; case 'DOWN': if (this.yv != -1) {this.xv = 0; this.yv = 1;} break; default: this.xv = this.yv = 0; } } ,然后更改为UP,直到调用下一个LEFT为止。 / p>

现在所做的就是将snake.update()变量更改为dir,然后在调用下一个UP之前将LEFT更改。因此,下一个snake.update()得到一个包含snake.direction()的{​​{1}}参数,该参数将被忽略(因为蛇指向dir),并且蛇不会向后退缩。 / p>


我希望这是有道理的,如果有帮助,您可以检查我的代码here

答案 1 :(得分:1)

您可以尝试通过在两次按键之间检查catch (SQLIntegrityConstraintViolationException ex) { //Assuming deleteFilm() has the correct throws clause throw ex; //you are not doing this. } 至少被调用一次来增加按键的时间限制。像这样:

draw()

但是我的猜测是,这会使您的游戏显得笨拙且反应迟钝。

有两种通用的解决方案,而不是根据时间限制用户输入:

选项1::当用户按下相应的键时,立即移动蛇。为此,您可以在每一帧的开头以及在按某个键时调用var canPress = true; function keyPressed(){ if(canPress){ // respond to key press } canPress = false; } function draw(){ // draw the frame canPress = true; } 之类的函数。

选项2:防止蛇沿着会立即杀死自己的方向移动。为此,您可以检查要进入的正方形是否已被占用,如果是,则忽略按键。

您采用哪种方法取决于您希望游戏的工作方式。您甚至可以采用混合方法,并且两者都可以。