Creating A Bullet Sprite At Players Sprite Location In Phaser But The Sprite Wont Be Created / Added To The Game

Viewed 72

This is a game where the monkey moves around the platforms collecting coins. I want to have the monkey shoot a banana when the down arrow and left arrow are pressed.

How would I create the bullet?

I have the keypress for the shooting and it calls shootR or shootL depending on which arrow is pressed. What I need is to create the projectile and have it move to the right or left(not affected by gravity). Can I get some help creating this projectile as var proj = projs.create(x, y, 'proj'); is not working. I am good at coding with js and phaser is new to me so help would be greatly appreciated.

var config = {
  type: Phaser.AUTO,
  width: 1900,
  height: 1000,
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 300 },
      debug: false
    }
  },
  scene: {
    preload: preload,
    create: create,
    update: update
  }
};
var main = document.getElementById("startBtn")
var heading = document.getElementById("header")
var gameOver
var platforms;
var score = 0;
var scoreText;
var leafAm = 0
var leafText
var gunAm = 0
var ammoAm = 0
var ammoText
var monkeyType = "monkey"
var delay = 0


function start() {
  game = new Phaser.Game(config);
  main.innerHTML = ''
  heading.innerHTML += '<h1 class="header2" onclick="shop()"><u>Click To Access Shop</u></h1>'
}

function preload() {
  this.load.image('Background', 'assets/Background.jpg');
  this.load.image('ground', 'assets/platform.png');
  this.load.image('coin', 'assets/coin.png');
  this.load.image('redCoin', 'assets/redCoin.png');
  this.load.spritesheet('monkey', 'assets/monkey.png', { frameWidth: 600, frameHeight: 720 });
  this.load.spritesheet('proj', 'assets/bullet.png', { frameWidth: 200, frameHeight: 200 });
}

function create() {
  this.add.image(500, 275, 'Background').setScale(3);
  platforms = this.physics.add.staticGroup();
  platforms.create(200, 650, 'ground').setScale(0.15).refreshBody();
  platforms.create(600, 400, 'ground').setScale(0.15).refreshBody();
  platforms.create(1600, 650, 'ground').setScale(0.15).refreshBody();
  platforms.create(750, 100, 'ground').setScale(0.15).refreshBody();
  platforms.create(850, 750, 'ground').setScale(0.15).refreshBody();
  platforms.create(100, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(400, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(700, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(1000, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(1300, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(1600, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(1900, 950, 'ground').setScale(0.15).refreshBody();
  platforms.create(1800, 800, 'ground').setScale(0.15).refreshBody();
  platforms.create(250, 250, 'ground').setScale(0.15).refreshBody();
  platforms.create(1000, 500, 'ground').setScale(0.15).refreshBody();
  platforms.create(1150, 220, 'ground').setScale(0.15).refreshBody();
  player = this.physics.add.sprite(100, 450, 'monkey').setScale(0.075);
  this.physics.add.collider(player, platforms);
  player.setBounce(0.2);
  player.setCollideWorldBounds(true);
  this.anims.create({
    key: 'left',
    frames: this.anims.generateFrameNumbers('monkey', { start: 0, end: 3 }),
    frameRate: 10,
    repeat: -1
  });
  this.anims.create({
    key: 'turn',
    frames: [{ key: 'monkey', frame: 4 }],
    frameRate: 20
  });
  this.anims.create({
    key: 'right',
    frames: this.anims.generateFrameNumbers('monkey', { start: 5, end: 8 }),
    frameRate: 10,
    repeat: -1
  });
  this.anims.create({
    key: 'shoot',
    frames: this.anims.generateFrameNumbers('proj', { start: 0, end: 3 }),
    framerate: 15,
    repeat: -1
  })
  coins = this.physics.add.group({
    key: 'coin',
    repeat: 10,
    setXY: { x: 12, y: 0, stepX: 150 }
  });
  coins.children.iterate(function (child) {
    child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));
    child.setScale(0.05)
  });
  this.physics.add.collider(coins, platforms);
  this.physics.add.overlap(player, coins, collectCoin, null, this);
  redCoins = this.physics.add.group();
  this.physics.add.collider(redCoins, platforms);
  this.physics.add.collider(player, redCoins, hitredCoin, null, this);
  projs = this.physics.add.group()
  this.physics.add.collider(projs, platforms)
  this.physics.add.collider(projs, redCoins, shootredCoin, null, this)
  scoreText = this.add.text(16, 16, 'Score: 0₴', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
  ammoText = this.add.text(16, 66, 'Ammo: 0', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
  leafText = this.add.text(16, 116, 'Shields: 0', { fontSize: '40px', fill: 'rgb(85, 1, 1)' });
}

function update() {
  cursors = this.input.keyboard.createCursorKeys();
  if (cursors.down.isDown && cursors.left.isDown && delay == 0) {
    shootL()
  } else if (cursors.down.isDown && cursors.right.isDown && delay == 0) {
    shootR()
  }
  if (cursors.left.isDown) {
    player.setVelocityX(-240);
    player.anims.play('left', true);
  }
  else if (cursors.right.isDown) {
    player.setVelocityX(240);
    player.anims.play('right', true);
  }
  else {
    player.setVelocityX(0);
    player.anims.play('turn');
  }
  if (cursors.up.isDown && player.body.touching.down) {
    player.setVelocityY(-330);
  }
}

function collectCoin(player, coin) {
  coin.disableBody(true, true);
  score += 1;
  scoreText.setText('Score: ' + score + '₴');
  if (coins.countActive(true) === 0) {
    coins.children.iterate(function (child) {
      child.enableBody(true, child.x, 0, true, true);
    });
    var x = Phaser.Math.Between(0, 800);
    var redCoin = redCoins.create(x, 16, 'redCoin').setScale(0.05);
    redCoin.setBounce(1);
    redCoin.setCollideWorldBounds(true);
    redCoin.setVelocity(Phaser.Math.Between(-300, 300), 20);
  }
}

function shootR(player, redCoin, proj) {
  var x = player.x
  var y = player.y
  
  var proj = projs.create(x, y, 'proj');

  // proj.setVelocityX(-240);
  // player.anims.play('shoot', true);
  ammoAm -= 1
  ammoText.setText('Ammo: ' + ammoAm + '');
  delay = 1
  this.time.delayedCall(3000, delayer, null, this);
}

function shootL(player, redCoin, proj) {
  var x = player.x
  var y = player.y

  var proj = projs.create(x, y, 'proj');

  ammoAm -= 1
  ammoText.setText('Ammo: ' + ammoAm + '');
  delay = 1
  this.time.delayedCall(3000, delayer, null, this);
}

function hitredCoin(player, redCoin) {
  if (leafAm > 0) {
    leafAm -= 1
    leafText.setText('Shields: ' + leafAm + '');
    redCoin.disableBody(true, true);
    var x = Phaser.Math.Between(0, 800);
    var redCoin = redCoins.create(x, 16, 'redCoin').setScale(0.05);
    redCoin.setBounce(1);
    redCoin.setCollideWorldBounds(true);
    redCoin.setVelocity(Phaser.Math.Between(-300, 300), 20);
  } else {
    this.physics.pause();
    player.setTint(0xff0000);
    player.anims.play('turn');
    gameOver = true;
    this.time.delayedCall(3000, restart, null, this);
  }
}

function shootredCoin(projs, redCoin) {
  redCoin.disableBody(true, true);
  projs.disableBody(true, true);
}

function restart() {
  score = 0
  var leafAm = 0
  var gunAm = 0
  var ammoAm = 0
  this.scene.stop();
  this.scene.start();
}

function shop() {
  main.innerHTML = `<button class="shopBackground"></button>`
  main.innerHTML += `<button class="shop1">Shop</button>`
  main.innerHTML += `<button class="shop2">Warning: Shop Fast, you can still die</button>`
  main.innerHTML += `<button class="shop3" onclick = "buy1()">Banana Gun...₴100.00<br>(Ability to shoot bananas)<br>click here to buy</button>`
  main.innerHTML += `<button class="shop4" onclick = "buy2()">Leaf Shield...₴30.00<br>(Protection from 1 hit)<br>click here to buy</button>`
  main.innerHTML += `<button class="shop5" onclick = "buy3()">Bananas...₴10.00<br>(Extra ammo, gun comes with 1)<br>click here to buy</button>`
  main.innerHTML += `<button class="shop6">₴ is score</button>`
  main.innerHTML += `<button class="shop7" onclick="main.innerHTML = ''">Back To Game</button>`
  main.innerHTML += `<img src="/assets/banana1.png" class="banana1">`
  main.innerHTML += `<img src="/assets/banana2.png" class="banana2">`
  main.innerHTML += `<img src="/assets/leaf.png" class="leaf">`
}

function buy1() {
  if (score > 99 && gunAm < 1) {
    gunAm += 1
    ammoAm += 1
    score -= 100
    scoreText.setText('Score: ' + score + '₴');
    alert("You have bought a gun \nClick the down arrow and either left or right to shoot\nShooting costs ammo but bullets detroy the red orbs\nEnjoy and good luck")
  } else if (gunAm > 0) {
    alert("You already have one")
  } else {
    alert("Not enough score")
  }
}

function buy2() {
  if (score > 29) {
    leafAm += 1
    score -= 30
    scoreText.setText('Score: ' + score + '₴');
    leafText.setText('Shields: ' + leafAm + '');
  } else {
    alert("Not enough score")
  }
}

function buy3() {
  if (score > 9) {
    ammoAm += 1
    score -= 10
    scoreText.setText('Score: ' + score + '₴');
    ammoText.setText('Ammo: ' + ammoAm + '');
    ;
  } else {
    alert("Not enough score")
  }
}

function delayer() {
  delay = 0
}

Any Help Or Ideas On This Would Be Appreciated.

There is also some HTML and CSS but those parts aren't affecting it or at least they shouldn't be

1 Answers

There are somethings to unpack here,

Btw.: usually on stackoverflow you should only post the essential code: https://stackoverflow.com/help/minimal-reproducible-example this makes helping easy

But back to your question:

  • First of all, the functions shootR and shootL don't work because, they are defined with parameters, but they are not passed. So the player parameter is overloading the global player variable (btw. the global player variable is never declared with var, let or const)

function definitions:

    function shootR(player, redCoin, proj) 
    ...

functions being called:

    ...
    if (cursors.down.isDown && cursors.left.isDown && delay == 0) {
        shootL()
    } else if (cursors.down.isDown && cursors.right.isDown && delay == 0) {
        shootR()
    }
    ...

Quick fix: pass the player parameter, example: shootR(player)

  • Second the this in the shootR and shootL functions, are not pointing to the right object.

Quick fix: Pass the scene to the function, example: shootR(this, player) and alter the functions to:

function shootL(scene, player,  redCoin, proj) {
    var x = player.x
    var y = player.y

    var proj = projs.create(x, y, 'proj');

    ammoAm -= 1
    ammoText.setText('Ammo: ' + ammoAm + '');
    delay = 1
    scene.time.delayedCall(3000, delayer, null, scene);
}
  • third to "remove the gravity", just use
    Quick fix: proj.body.setAllowGravity(false); in the shootR and shootL (here is the link to the documentation ) functions,

  • And Last just add the velocity for the bullet proj.setVelocityX()

btw.: the code could be improved using classes and their properties, I would suggest looking at the phaser examples https://phaser.io/examples/v3/view/scenes/scene-from-class and/or https://phaser.io/examples/v3/view/scenes/scene-from-es6-class on how to use classes for scene, this could remove many problems. And you would not need to use global varibales or pass so many parameters.

Related