How to make two buttons work on mobile - phaser 3

46 Views Asked by At

It's a very classic spaceship game where you kill enemies.

On mobile, I made a joystick to move the player and a button to shoot.

The problem is that when you move the player, you can't shoot. You can't do both things at the same time. I've already tried a few ways to resolve this and I haven't been able to. Could you analyze my code and help me, please?

For anyone who wants to play, this is the link, so you can see the real problem. Remembering that it is on mobile. to play

I included the entire code, but I will explain the functions of player movement and shooting below.

createPlayer createJoystick createButtons movePlayerManager

class Play extends Phaser.Scene {

  constructor() {
    super({
      key: 'play',
      active: false
    });
  }



  loaded = false;

  config = {
    gameTime: 0,

    spaceField: {
      velocityY: 4,
    },

    player: {
      velocityX: 600,
      velocityY: 200,
    },

    life: {
      value: 3,
      created: 0,
      maximum: 1,
    },

    bullet: {
      velocity: 25,
      shot: false,
      timeCreateAnotherShot: 0,
    },

    enemy: {
      velocityY: 4.5,
      velocityXMax: 1,
      velocityXMin: 0,
      created: 0,
      maximum: 3,
      timeValue: 50,
      timeForCreation: 0,
      whichSide: 'right'
    },
  };

  score = 0;



  init() {
  }

  preload() {
  }



  configForMobile(){
    this.config.player.velocityX = 300
  }



  // Create
  createBackground(){
    let widthValue = 800
    let heightValue = 600;
    
    if(!this.sys.game.device.desktop){
      widthValue = window.innerWidth
      heightValue = this.sys.game.device.os.iOS || this.sys.game.device.os.iPhone ? window.innerHeight - 100 : window.innerHeight
    }

    this.spaceField = this.add.tileSprite(
      this.sys.game.device.os.desktop ? 400 : widthValue / 2, 
      this.sys.game.device.os.desktop ? 300 : heightValue / 2, 
      widthValue, 
      heightValue, 
      'background'
    )
  }

  createPlayer() {
    this.player = this.physics.add.sprite(0, 0, 'player');

    // Configs
    this.player.setOrigin(0.5)
    this.player.setScale(.1);
    this.player.setCollideWorldBounds(true);
    this.player.setPosition(this.cameras.main.centerX, this.cameras.main.displayHeight - 20);
    this.player.depth = 2
  }

  configBullets(){
    this.bullets = this.physics.add.group();

    if(this.sys.game.device.os.desktop)
      this.fireButton = this.input.keyboard.addKey('SPACE');
  }

  configEnemies(){
    this.enemies = this.physics.add.group();
    this.enemies.enableBody = true;
  }

  configLifePack(){
    this.lifes = this.physics.add.group();
    this.lifes.enableBody = true;
  }

  collisions(){
    this.physics.add.collider(this.bullets, this.enemies, this.bulletCollidesWithEnemy, null, this)
    this.playerEnemyCollision = this.physics.add.collider(this.player, this.enemies, this.playerCollidesWithEnemy, null, this)
    this.physics.add.collider(this.player, this.lifes, this.playerCollidesWithLife, null, this)
    this.physics.add.collider(this.enemies, this.enemies, null, null, this)
  }

  createScore() {
    this.score = 0;

    this.scoreText = this.add.text(this.cameras.main.centerX, 30,
      `SCORE`, {
        font: "14px Arial",
        fill: "#ffffff"
      }
    ).setOrigin(0.5);

    this.scoreValue = this.add.text(this.cameras.main.centerX, 50,
      `0`, {
        font: "20px Arial",
        fill: "#ffffff"
      }
    ).setOrigin(0.5);

    // Z-index
    this.scoreValue.depth = 9;
    this.scoreText.depth = 9;
  }

  createScoreLife(){
    this.lifeText = this.add.text(30, 30,
      `Vida`, {
        font: "14px Arial",
        fill: "#ffffff"
      }
    ).setOrigin(0.5);

    this.lifeValue = this.add.text(30, 50,
      this.config.life.value, {
        font: "20px Arial",
        fill: "#ffffff"
      }
    ).setOrigin(0.5);
  }

  createJoystick(){
    this.joystick = this.game.plugins.get('rexVirtualJoystick').add(this, {
      x: 70,
      y: this.game.config.height - 100,
      radius: 50,
      base: this.add.circle(0, 0, 50, 0x888888),
      thumb: this.add.circle(0, 0, 30, 0xcccccc),
    });
    this.joystick.depth = 9

    this.joystickCursorKeys = this.joystick.createCursorKeys();
  }

  createButtons(){
    this.fireButton = this.add.sprite(this.game.config.width - 70, this.game.config.height - 90, 'buttons', 'rightButton')
                      .setScale(0.3).setInteractive();
    
    this.fireButton.depth = 2;

    this.fireButton.on('pointerdown', () => {
      console.log('fire button')
      this.createBullet()
    })
  }

  countdown(){
    let index = 3;
    let text = "";

    // Background
    this.background = this.add.graphics();
    this.background.fillStyle(0x000, .5);
    this.background.fillRect(0, 0, this.game.config.width, this.game.config.height);
    this.background.depth = 9;

    // Init
    text = this.add.text(
      this.cameras.main.centerX,
      this.cameras.main.centerY,
      index,
      { font: "100px Arial",  fill: "#ffffff" }
    );
    text.setOrigin(0.5);
    text.depth = 9;

    // Interval
    const interval = setInterval(() => {
      // Clear
      if(index === "GO!"){
        text.destroy();
        this.background.destroy();
        clearInterval(interval);
        this.loaded = true;
        return;
      }

      // Destroy text
      text.destroy();

      // Change value to 'Go' || decrease time
      if(index === 1) index = "GO!";
      else index--;

      // Create text
      text = this.add.text(
        this.cameras.main.centerX,
        this.cameras.main.centerY,
        index,
        { font: "100px Arial",  fill: "#ffffff" }
      );

      // Configs
      text.setOrigin(0.5);
      text.depth = 9;
    }, 1000)
  }

  create() {
    // Camera
    this.cameras.main.setBackgroundColor("#24252A");

    // Functions
    this.createBackground();
    this.createPlayer();
    this.configBullets()
    this.configEnemies()
    this.configLifePack()
    this.collisions()
    this.createScore()
    this.createScoreLife()

    // Cursor
    if(this.sys.game.device.os.desktop){
      this.cursors = this.input.keyboard.createCursorKeys();
    }
    else{
      this.createJoystick();
      this.createButtons();
    }

    // Countdown
    this.countdown()
  }



  // Update
  gameTime(){
    this.config.gameTime++;

    // Life
    if(this.config.gameTime % 1000 === 0 && this.score < 80 || this.config.gameTime % 2000 === 0 && this.score > 80){
      this.createLife()
    }

    if(this.config.gameTime % 100 === 0){
      this.config.spaceField.velocityY += .2

      this.config.enemy.velocityY += .2
    }
    if(this.config.gameTime % 1000 === 0){

      this.config.enemy.timeValue = this.config.enemy.timeValue > 15 ? this.config.enemy.timeValue - 5 : 15
      this.config.enemy.maximum = this.config.enemy.maximum < 8 ? this.config.enemy.maximum + 1 : 8;
    }
    if(this.config.gameTime % 2000 === 0){
      this.config.player.velocityX += 100

      if(this.config.enemy.velocityXMin === 0)
        this.config.enemy.velocityXMin = 1
    }
    if(this.config.gameTime % 5000 === 0){
      this.config.enemy.velocityXMin++;
      this.config.enemy.velocityXMax++;
    }
  }

  moveBackground(){
    this.spaceField.tilePositionY -= this.config.spaceField.velocityY;
  }

  movePlayerManager() {
    if (
      this.cursors && this.cursors.left.isDown || 
      this.joystickCursorKeys && this.joystickCursorKeys.left.isDown
    ){
      this.player.setVelocityX(-this.config.player.velocityX);
    }
    else if (
      this.cursors && this.cursors.right.isDown ||
      this.joystickCursorKeys && this.joystickCursorKeys.right.isDown
    ){
      this.player.setVelocityX(this.config.player.velocityX);
    }
    else if(
      this.cursors && this.cursors.up.isDown ||
      this.joystickCursorKeys && this.joystickCursorKeys.up.isDown
    ){
      this.player.setVelocityY(-this.config.player.velocityY);
    }
    else if(
      this.cursors && this.cursors.down.isDown ||
      this.joystickCursorKeys && this.joystickCursorKeys.down.isDown
    ){
      this.player.setVelocityY(this.config.player.velocityY);
    }
    else
    {
      this.player.setVelocityX(0);
      this.player.setVelocityY(0);
    }
  }

  moveEnemies(){
    this.enemies.children.each((enemy) => {
      enemy.y += this.config.enemy.velocityY

      // X
      if(enemy.x >= (this.game.config.width - 40)){
        enemy.whichSide = 'left'
      }
      else if(enemy.x <= 40){
        enemy.whichSide = 'right'
      }

      if(enemy.whichSide === 'right' && enemy.y > -40){
        enemy.x += enemy.velocityX;
      }
      else if(enemy.whichSide === 'left' && enemy.y > -40){
        enemy.x -= enemy.velocityX
      }

      // Y
      if(enemy.y > this.game.config.height){
        enemy.destroy()

        this.config.enemy.created--;
        // this.config.life.value--;

        // this.updateScoreLife()
      }
    })
  }

  shootingEvent(){
    if(this.config.bullet.timeCreateAnotherShot != 0)
      this.config.bullet.timeCreateAnotherShot--;

    if(
      this.sys.game.device.os.desktop && this.fireButton && this.fireButton.isDown
      )
    {
      this.createBullet()
    } 


    this.bullets.children.each(function (bullet) {
      bullet.y -= this.config.bullet.velocity

      if(bullet.y < 0){
        bullet.destroy()
      }
    }, this)
  }

  updateScore(){
    this.score++;
    this.scoreValue.setText(this.score);
  }

  updateScoreLife(){
    this.lifeValue.setText(this.config.life.value);
  }

  lifeHitAtTheEndScreen(){
    this.lifes.children.entries.forEach(life => {
      if(life.y >= this.game.config.height){
        life.destroy()
        this.config.life.created--;
      }
    });
  }

  update(time) {
    if(this.loaded){
      this.gameTime()

      this.createEnemy()

      this.moveBackground()
      this.movePlayerManager();
      this.moveEnemies()

      this.shootingEvent();
      this.lifeHitAtTheEndScreen()
    }
  }



  //
  createBullet(){
    if(this.config.bullet.timeCreateAnotherShot != 0) return

    const bullet = this.physics.add.sprite(this.player.x, this.player.y, 'bullet')
    bullet.setScale(.1)

    this.bullets.add(bullet)

    this.config.bullet.shot = true;
    this.config.bullet.timeCreateAnotherShot = 15
  }

  createEnemy(){
    if(this.config.enemy.timeForCreation > 0)
      this.config.enemy.timeForCreation--;

    if(this.config.enemy.created >= this.config.enemy.maximum || this.config.enemy.timeForCreation != 0) return;

    this.config.enemy.timeForCreation = this.config.enemy.timeValue;
    this.config.enemy.created++

    // Location
    const enemyYLocation = Math.floor(Math.random() * (200 - 50 + 1) + 50)
    const enemyXLocation = Math.floor(Math.random() * ((this.game.config.width - 100) - 100 + 1) + 50)

    // X velocity
    let enemyXVelocity = Math.floor(Math.random() * (this.config.enemy.velocityXMax - this.config.enemy.velocityXMin + 1) + this.config.enemy.velocityXMin)

    // Create enemy
    const enemy = this.enemies.create(enemyXLocation, -enemyYLocation, 'enemy')
    enemy.setScale(.1)
    enemy.setOrigin(.5)

    //
    enemy.whichSide = enemyXLocation > (this.game.config.width + 100) / 2 ? 'right' : 'left'
    enemy.velocityX = enemyXVelocity
  }

  createLife(){
    if(this.config.life.created >= this.config.life.maximum) return;

    this.config.life.created++;

    // Location
    const yLocation = Math.floor(Math.random() * (200 - 50 + 1) + 50)
    const xLocation = Math.floor(Math.random() * ((this.game.config.width - 100) - 50 + 1) + 50)

    // Create enemy
    const life = this.lifes.create(xLocation, -yLocation, 'life')
    life.setScale(.035)
    life.setOrigin(.5)

    life.body.velocity.y = 500
  }

  bulletCollidesWithEnemy(bullet, enemy){
    bullet.destroy()
    enemy.destroy()

    this.config.enemy.created--;

    // Score
    this.updateScore()
  }

  playerCollidesWithEnemy(player, enemy){
    if(this.config.life.value <= 1) 
      this.gameOver() 

    enemy.destroy()

    this.playerEnemyCollision.active = false

    this.config.life.value--;

    this.actionAfterPlayerCollidesWithEnemy()
    this.updateScoreLife()
  }

  playerCollidesWithLife(player, life){
    life.destroy()

    this.config.life.created--;
    this.config.life.value++;
   
    this.updateScoreLife()
  }

  actionAfterPlayerCollidesWithEnemy(){
    let index = 1;
    let alphaValue = 1

    this.player.alpha = .3

    const interval = setInterval(() => {
      if(index === 10){
        clearInterval(interval)
        this.playerEnemyCollision.active = true
        return;
      }

      this.player.alpha = alphaValue

      alphaValue = alphaValue === 1 ? .3 : 1
      index++;
    }, 200);
  }



  //
  gameOver(){
    this.loaded = false;
    
    setTimeout(() => {
      this.scene.restart()

      this.score = 0;
      this.config = {
        gameTime: 0,
    
        spaceField: {
          velocityY: 4,
        },
    
        player: {
          velocityX: 600,
          velocityY: 200,
        },
    
        life: {
          value: 3,
          created: 0,
          maximum: 1,
        },
    
        bullet: {
          velocity: 25,
          shot: false,
          timeCreateAnotherShot: 0,
        },
    
        enemy: {
          velocityY: 4.5,
          velocityXMax: 1,
          velocityXMin: 0,
          created: 0,
          maximum: 3,
          timeValue: 50,
          timeForCreation: 0,
          whichSide: 'right'
        },
      };
    }, 200)
  }
}

export default Play;

0

There are 0 best solutions below