[SOLVED] Event keys question

Hello

Just a noob question again

When using event keys for something like controlling player movement (rather than keyboard.isPressed or wasPressed) can you get this to fire only once when you press and hold key down?

For example when jumping it will execute jump continuously if jump = true when the key is held down, is it possible to limit this to 1 per every time you key down and hold it without releasing key up?

Thanks

Hi @nasjarta,

For the pc.EVENT_KEYDOWN event it will fire continuously will being pressed.

You can either use pc.EVENT_KEYUP or add a gate check on your key down handler:

KeyboardHandler.prototype.onKeyDown = function (event) {
   
   if(this.wasPressed === true) return;

   // do what you normally do
};

And reset it on key up:

KeyboardHandler.prototype.onKeyUp = function (event) {
   
   this.wasPressed = true;
};
2 Likes

Sorry but I am confused.

I tried your solution but then the jump become indefinite after jumping once.

So for example I have the following code in a switch statement:

KeyboardHandler.prototype.onKeyDown = function (event) { 

   switch (event.key) {
      case pc.KEY_W:
         this.moveForward = true;
         break;
      case pc.KEY_A:
         this.moveLeft = true;
         break;
      case pc.KEY_D:
         this.moveRight = true;
         break;
      case pc.KEY_S:
         this.moveBack = true;
         break;
      case pc.KEY_SPACE:
         this.jump = true; // jump = true plays jump function
         break;

I want to achieve the same as this.app.keyboard.wasPressed but the jump either does not happen at all, or happens all the time once you hold the key down. I want to just jump once if you press the key and hold it just like wasPressed.

Hey, is that your full code? If that’s the case that’s not what I proposed.

You need to safeguard your actions to execute only once on key down. The basic idea is the onKeyDown will fire per frame as long as the key is pressed. So your code needs to catch that event once, that’s the first time.

If you have trouble doing that try sharing a bit more of how your code works and if possible a sample project too.

2 Likes

Hello it is just part of it. Here is the full project:

https://playcanvas.com/project/904245/overview/event-once

I did some researching on Google to find a solution for this but I still could not get it to work properly.

Maybe if I add a separate function onKeyDownFirst and use repeat https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat for only the jump. I think that might work.

Hi @Leonidas will you be able to help me?

I tried the repeat property - even though the key is fired once the movement is always executed.

Following your method and making some tweaks I managed to get it to work only partially. Here sometimes it works as expected and other times it jumps forever. I do not know why it is doing that, maybe because it is colliding with the update function?

Movement.prototype.onKeyDown = function (event) {

    if (event.event.repeat) return;

    switch (event.key) {
        case pc.KEY_W:
            this.moveForward = true;
            break;
        case pc.KEY_A:
            this.moveLeft = true;
            break;
        case pc.KEY_D:
            this.moveRight = true;
            break;
        case pc.KEY_S:
            this.moveBack = true;
            break;
        case pc.KEY_SPACE:
            this.jump = true;
            if (this.jump) return;
            break;
    }
};

Movement.prototype.onKeyUp = function (event) {

    switch (event.key) {
        case pc.KEY_W:
            this.moveForward = false;
            break;
        case pc.KEY_A:
            this.moveLeft = false;
            break;
        case pc.KEY_D:
            this.moveRight = false;
            break;
        case pc.KEY_S:
            this.moveBack = false;
            break;
        
        this.jump = false;
    }
};

I am finding this very difficult to understand for some reason. Whatever I try it does not work.

Hi @nasjarta,

You need to make sure that this.jump is set to true only for a single frame.

Here is what worked for me in your project, change your onKeyDown code to this:

        case pc.KEY_SPACE:
            if (this.jump){
                this.jump = false;
                return;
            }
            this.jump = true;
            break;

Hello Leonidas

I tried your solution but it is still multiple jumping sometimes and sometimes not. This is really confusing.

I gave your project a try, seems to work. The player jumps one from the ground and can jump again only after he lands back on the ground.

I managed to fix it.

I was calling the jump function on an if statement inside the update function, what I did was take it out from there and add it to the switch statement directly which solved the issue. Now it works exactly like wasPressed. I could not seem to figure out that the update function and the switch statement were interfering.

Thanks for your help as always Leonidas

1 Like