javascriptphaser-frameworkphaserjs

Generate Items with delay in phaser3


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.

SOLUTION

I finally decided to generate the projectiles with the pointerdown event. Being an event it was only called once, and I quickly resolved the problem. But the solutions proposed by @winner_joiner work very well. I think the first solution is better than the second because it is an event. It is definitely only called once.


Solution

  • 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>