Fast Foodie - Food is placed three times instead of one

I’m stuck around step 34 on the Fast Foodies Phaser project - Project Link

Here is the relevant code for this question

  create() {
    // Stop, reassign, and play the new music
    gameState.currentMusic.stop();
    gameState.currentMusic = this.sound.add('gameplayTheme');
    gameState.currentMusic.play({ loop: true });

    // Assign SFX
    gameState.sfx = {};
    gameState.sfx.placeFood = this.sound.add('placeFoodSFX');
    gameState.sfx.servingCorrect = this.sound.add('servingCorrectSFX');
    gameState.sfx.servingIncorrect = this.sound.add('servingIncorrectSFX');
    gameState.sfx.servingEmpty = this.sound.add('servingEmptySFX');
    gameState.sfx.fiveStars = this.sound.add('fiveStarsSFX');
    gameState.sfx.nextWave = this.sound.add('nextWaveSFX');

    // Create environment sprites
    gameState.floorServer = this.add.sprite(gameState.cam.midPoint.x, 0, 'Floor-Server').setScale(0.5).setOrigin(0.5, 0);
    gameState.floorCustomer = this.add.sprite(gameState.cam.midPoint.x, gameState.cam.worldView.bottom, 'Floor-Customer').setScale(0.5).setOrigin(0.5, 1);
    gameState.table = this.add.sprite(gameState.cam.midPoint.x, gameState.cam.midPoint.y, 'Barrier').setScale(0.5);

    // Create player and tray sprites
    gameState.tray = this.add.sprite(gameState.cam.midPoint.x, gameState.cam.midPoint.y, 'Tray').setScale(0.5);
    gameState.player = this.add.sprite(gameState.cam.midPoint.x, 200, 'Chef').setScale(0.5);

    // Display the score
    gameState.scoreTitleText = this.add.text(gameState.cam.midPoint.x, 30, 'Score', { fontSize: '15px', fill: '#666666' }).setOrigin(0.5);
    gameState.scoreText = this.add.text(gameState.cam.midPoint.x, gameState.scoreTitleText.y + gameState.scoreTitleText.height + 20, gameState.score, { fontSize: '30px', fill: '#000000' }).setOrigin(0.5);

    // Display the wave count
    gameState.waveTitleText = this.add.text(gameState.cam.worldView.right - 20, 30, 'Wave', { fontSize: '64px', fill: '#666666' }).setOrigin(1, 1).setScale(0.25);
    gameState.waveCountText = this.add.text(gameState.cam.worldView.right - 20, 30, gameState.currentWaveCount + '/' + gameState.totalWaveCount, { fontSize: '120px', fill: '#000000' }).setOrigin(1, 0).setScale(0.25);

    // Display number of customers left
    gameState.customerCountText = this.add.text(gameState.cam.worldView.right - 20, 80, `Customers left: ${gameState.customersLeftCount}`, { fontSize: '15px', fill: '#000000' }).setOrigin(1);
    
    // Generate wave group
    gameState.customers = this.add.group();
    this.generateWave();
    //Keep track of meals
    gameState.currentMeal = this.add.group();
    gameState.currentMeal.fullnessValue = 0;
    //key inputs
    gameState.keys.Enter = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ENTER);
    gameState.keys.A = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);
    gameState.keys.S = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S);
    gameState.keys.D = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);
  }

  update() {
    if(gameState.readyForNextOrder) {
      gameState.readyForNextOrder = false;

      gameState.customerIsReady = false;

      let thisIndex = gameState.customersServedCount;
      gameState.currentCustomer = gameState.customers.children.entries[thisIndex]

      const tween = this.tweens.add({
        targets: gameState.currentCustomer,
        delay: 100,
        x:gameState.player.x,
        angle:90,
        ease:'Power2',
        onComplete: () => {
          gameState.customerIsReady = true;
          gameState.currentCustomer.meterContainer.visible = true;
        }
      })
    }

    if(gameState.keys.A.isDown) {
      this.placeFood('Burger', 5);
    } else if(gameState.keys.S.isDown) {
      this.placeFood('Fries', 3);
    } else if(gameState.keys.D.isDown) {
      this.placeFood('Shake', 1);
    } else if(gameState.keys.Enter.isDown) {

    }
  }

  /* WAVES */
  // Generate wave
  generateWave() {
    
    // Add the total number of customers per wave here:
    gameState.totalCustomerCount = Math.ceil((Math.random() * 10) * gameState.currentWaveCount);
    this.updateCustomerCountText();
    for (let i = 0; i < gameState.totalCustomerCount; i++) {
      // Create your container below and add your customers to it below:
      const customerContainer = this.add.container(gameState.cam.worldView.right + (200 * i), gameState.cam.worldView.bottom - 140);

      gameState.customers.add(customerContainer)

      // Customer sprite randomizer
      let customerImageKey = Math.ceil(Math.random() * 5);

      // Draw customers here!
      const customer = this.add.sprite(0,0, `Customer-${customerImageKey}`).setScale(0.5)
      customerContainer.add(customer)
      // Fullness meter container
      customerContainer.fullnessMeter = this.add.group();

      // Define capacity
      customerContainer.fullnessCapacity = Math.ceil(Math.random() * 5 * gameState.totalWaveCount);

      // If capacity is an impossible number, reshuffle it until it isn't
      while (customerContainer.fullnessCapacity === 12 || customerContainer.fullnessCapacity === 14) {
        customerContainer.fullnessCapacity = Math.ceil(Math.random() * 5) * gameState.totalWaveCount;
      }

      // Edit the meterWidth
      let meterWidth = customerContainer.fullnessCapacity * 10;
      customerContainer.meterContainer = this.add.container(0, customer.y + (meterWidth / 2));
      
      // Add the customerContainer.meterContainer to customerContainer
      customerContainer.add(customerContainer.meterContainer)

      // Add meter base
      customerContainer.meterBase = this.add.rectangle(-130, customer.y, meterWidth, 33, 0x707070).setOrigin(0);
      customerContainer.meterBase.setStrokeStyle(6, 0x707070);
      customerContainer.meterBase.angle = -90;
      customerContainer.meterContainer.add(customerContainer.meterBase);

      // Add timer countdown meter body
      customerContainer.timerMeterBody = this.add.rectangle(customerContainer.meterBase.x + 22, customer.y + 1, meterWidth + 4, 12, 0x3ADB40).setOrigin(0);
      customerContainer.timerMeterBody.angle = -90;
      customerContainer.meterContainer.add(customerContainer.timerMeterBody);

      // Create container for individual fullness blocks
      customerContainer.fullnessMeterBlocks = [];

      // Create fullness meter blocks
      for (let j = 0; j < customerContainer.fullnessCapacity; j++) {
        customerContainer.fullnessMeterBlocks[j] = this.add.rectangle(customerContainer.meterBase.x, customer.y - (10 * j), 10, 20, 0xDBD53A).setOrigin(0);
        customerContainer.fullnessMeterBlocks[j].setStrokeStyle(2, 0xB9B42E);
        customerContainer.fullnessMeterBlocks[j].angle = -90;
        customerContainer.fullnessMeter.add(customerContainer.fullnessMeterBlocks[j]);
        customerContainer.meterContainer.add(customerContainer.fullnessMeterBlocks[j]);
      }

      // Hide meters
      customerContainer.meterContainer.visible = false;
    }
  }

   updateCustomerCountText() {
    gameState.customersLeftCount = gameState.totalCustomerCount - gameState.customersServedCount;

    gameState.customerCountText.setText(`Customers Left: ${gameState.customersLeftCount}`);
  };
  
  placeFood(food, fullnessValue) {
    if(gameState.currentMeal.children.entries.length < 3 && gameState.customerIsReady === true) {
      let Xposition = gameState.tray.x;

      switch(gameState.currentMeal.children.entries.length) {
        case 0:
          Xposition -= 90;
          break;
        case 2:
          Xposition += 100;
          break;
      }
      gameState.currentMeal.create(Xposition, gameState.tray.y, food)
      gameState.currentMeal.fullnessValue += fullnessValue;

      for(let i = 0; i < gameState.currentMeal.fullnessValue; i++) {
        if(i < gameState.currentCustomer.fullnessCapacity) {
          gameState.currentCustomer.fullnessMeterBlocks[i].setFillStyle(0xFFFA81);
        } else if(i === gameState.currentCustomer.fullnessMeterBlocks) {
          gameState.currentCustomer.fullnessMeterBlocks[i].setFillStyle(0x3ADB40);
          gameState.currentCustomer.fullnessMeterBlocks[i].setStrokeStyle(2, 0x2EB94E);
        } else if(i > gameState.currentMeal.fullnessCapacity) {
          gameState.currentCustomer.fullnessMeterBlocks[i].setFillStyle(0xDB533A);
          gameState.currentCustomer.fullnessMeterBlocks[i].setStrokeStyle(2, 0xB92E2E);
        }
      }
    }
  };  
}

Its supposed to work so that when you click either A, S or D one food item is placed on the tray however when on of the keys is pressed three of the same item is served. I’ve no idea how this happens, been looking at it for awhile.

Any help would be great.

Hi there, welcome to the forums.

Going to preface this with the caveats of

A. I am not familiar with Phaser, and
B. I’ve not done the Phaser.js course, but…

I think your error is with your checks for keypresses:

 if(gameState.keys.A.isDown) {
      this.placeFood('Burger', 5);
    } else if(gameState.keys.S.isDown) {
      this.placeFood('Fries', 3);
    } else if(gameState.keys.D.isDown) {
      this.placeFood('Shake', 1);
    } else if(gameState.keys.Enter.isDown) {

    }

According to the docs, isDown will return true for as long as the key is pressed.

So unless you’re incredibly deft with the keyboard and only keep the key pressed for a single update() cycle in your Phaser app, the key will register as pressed across multiple updates which would explain your multiple food additions.

I think you’ll need to change your test for key presses to resolve the issue. :slight_smile:

2 Likes

Yeh changed the tests for keypress and now its working as expected.
Thanks for the help :smiley:

1 Like

No problem, glad it’s fixed. :slight_smile: