Generate Items with delay in phaser3

44 Views Asked by At

I'm creating a simple game in phaser, where I have a spaceship, which by pressing the space bar, shoots projectiles. This is the code:

var gameScene = new Phaser.Scene('game');
var navicella;
var bullets; 

gameScene.preload = function(){
    this.load.image('navicella', './assets/astronave.png')
    this.load.image('bullet', './assets/bullet.png')
}

gameScene.create = function(){
    navicella = this.physics.add.sprite(450, 500, 'navicella');
    bullets = this.physics.add.group();
    this.keySpace = this.input.keyboard.addKey(Phaser.Input.Keyboard.Key.SPACE, 100);
    
}
gameScene.update = function(){
    navicella.x = this.input.mousePointer.x;
    if(this.keySpace.isDown){
        var bullet = bullets.create(navicella.x, 500, 'bullet');
        bullet.setVelocityY(-100);
        
    }

    
}
var config = {
    type: Phaser.AUTO,
    width: 900, 
    height: 600,
    scene: gameScene,
    physics: {
        default: 'arcade',
        arcade: {
            debug: false,
            gravity:{y: 0}
        }
    },
};
var game = new Phaser.Game(config);

The problem in the code, is that when I press the space bar, too many projectiles are generated, there is no limit. I had thought about adding a delay when projectiles spawn, but I have no idea how to do it.

2

There are 2 best solutions below

0
iamsmruti On BEST ANSWER

The best way to achieve this with minimal effort is to use the keyboard events given by the phaser itself. So here is how you should implement keyboard events, instead of just checking if it is pressed, you should create an event listener and then write the logic inside.

You can create a keypressed event like this

var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);

Following are the keycodes, that you can use to trigger different buttons on the keyboard. KeyCodes

So, using this you can change your update function to something like this:

gameScene.update = function () {
   navicella.x = this.input.mousePointer.x;
   var spaceBar = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
        
   spaceBar.on("down" , () => {
      var bullet = bullets.create(navicella.x, 500, "bullet");
      bullet.setVelocityY(-100);
   })
};

Let me know, if you require any resource for this, will be glad to help you out.

0
winner_joiner On

There are serveral way to do this,

  1. you could listen to the key_UP event, but than the user would have to type for each shot
  2. Or you could you could use a variable the check how much time has passed between shots. For this you can use the parameter time, which is passed to the update function and a helper variable.

This short Demo shows both Methodes:
(but Phaser has several other ways to solve this)

document.body.style = 'margin:0;';


var gameScene = new Phaser.Scene('game');
var navicella;
var bullets; 

gameScene.create = function(){
    let graphics  = this.make.graphics();
    graphics.fillStyle(0xffffff);
    graphics.fillRect(0, 0, 4, 4);
    graphics.generateTexture('bullet', 4, 4);
    
    this.add.text(10,10, 'Shoot with A or SPACE')
        .setScale(1.5)
        .setOrigin(0)
        .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
    let shipPlacehpolder = this.add.rectangle(250, 120, 20,20, 0xffffff).setOrigin(.5);
    navicella = this.physics.add.existing(shipPlacehpolder);
    bullets = this.physics.add.group();
    
    this.keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
    
    this.input.keyboard.on('keyup-SPACE', () => { //<-- keup version
        var bullet = bullets.create(navicella.x, navicella.y, 'bullet');
        bullet.setVelocityY(-150);
    });
    this.lastBulletShot = 0;
}

gameScene.update = function(time, delta){ // <-- default parameter which are passed
    navicella.x = this.input.mousePointer.x;
    if(this.keyA.isDown && time - this.lastBulletShot > 200 ){ // <--Time to wait between shots
        var bullet = bullets.create(navicella.x, navicella.y, 'bullet');
        bullet.setVelocityY(-150);
        this.lastBulletShot = time; // <-- save last time bullet was shot
    }
}

var config = {
    type: Phaser.AUTO,
    width: 500, 
    height: 180,
    scene: gameScene,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 0 }
        } 
    },
};
var game = new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>