Why did I have to reverse the fields in physics.add.overlap?

1 week ago 12
ARTICLE AD BOX

I'm using Phaser to write a simple game, but for some reason Phaser.physics.add.overlap was bugged out, and switching the fields corrected it. Here is the full code. The issue occurs at line 173. Earlier, at line 160, the physics worked correctly.

// Global hi-score tracker let hiScore = 0; // Enemy definitions const enemyTypes = [ { key: "enemy_simple", name: "Simple", difficulty: 1, hp: 100, damage: 80, speed: 2.5, score: 100, fires: false }, { key: "enemy_fast", name: "Fast", difficulty: 2, hp: 70, damage: 40, speed: 5, score: 400, fires: false }, { key: "enemy_heavy", name: "Heavy", difficulty: 3, hp: 150, damage: 100, speed: 1, score: 200, fires: false }, { key: "enemy_seeking", name: "Seeking1", difficulty: 4, hp: 100, damage: 50, speed: 3, score: 200, fires: false }, { key: "enemy_damage", name: "Big_Damage", difficulty: 5, hp: 300, damage: 250, speed: 2.5, score: 150, fires: false }, { key: "enemy_shooty", name: "Shooty_Mc_Pew_Pew", difficulty: 6, hp: 100, damage: 50, speed: 1.5, score: 250, fires: true, bulletDamage: 50, reloadTime: 60 } ]; const difficultyCap = enemyTypes.length; // Menu Scene class MenuScene extends Phaser.Scene { constructor() { super("MenuScene"); } preload() { // Load assets here so they're ready before GameScene this.load.image("player", "/static/assets/Player_1.png"); this.load.image("enemy_simple", "/static/assets/Simple.png"); this.load.image("enemy_fast", "/static/assets/Fast.png"); this.load.image("enemy_heavy", "/static/assets/Heavy.png"); this.load.image("enemy_seeking", "/static/assets/Seeking1.png"); this.load.image("enemy_damage", "/static/assets/Heavy Damage.png"); this.load.image("enemy_shooty", "/static/assets/Shooty_Mc_Pew_Pew.png"); this.load.image("bullet", "/static/assets/pBullet.png"); this.load.image("star", "/static/assets/Star.png"); this.load.image("pause", "/static/assets/pause.png"); console.log("Images loaded correctly") } create() { this.titleText = this.add.text(this.scale.width / 2, this.scale.height / 3, "Up We Go!", { fontSize: "48px", fill: "#fff" }).setOrigin(0.5); // origin (0.5,0.5) centers the text let startText = this.add.text(this.scale.width / 2, this.scale.height / 2, "START", { fontSize: "32px", fill: "#0f0" }).setOrigin(0.5); startText.setInteractive(); startText.on("pointerdown", () => { this.scene.start("GameScene"); this.scene.stop("MenuScene"); console.log("Game started") }); } } // Game Scene class GameScene extends Phaser.Scene { constructor() { super("GameScene"); } preload() { // Assets already loaded in MenuScene, but preload is required } shootBullet() { let bullet = this.bullets.create(this.player.x, this.player.y - 20, "bullet"); bullet.setVelocityY(-300); } create() { this.score = 0; this.kills=0; this.difficulty = 2; this.isMobile = this.sys.game.device.os.android || this.sys.game.device.os.iOS; // Player setup this.player = this.physics.add.sprite(this.scale.width/2, this.scale.height/2, "player"); this.player.name="Player" this.player.setCollideWorldBounds(true); this.player.hp = 200; this.player.damage = 100; console.log("Player spawned with HP:", this.player.hp); this.fireCooldown = 300; // milliseconds between shots this.lastFired = 0; // timestamp of last shot // Controls this.cursors = this.input.keyboard.createCursorKeys(); this.input.keyboard.addKeys("W,A,S,D,SPACE"); // Make a group of stars this.stars = this.add.group({ key: "star", repeat: 150, // number of stars setXY: { x: 12, y: 12, stepX: 8, stepY: 6 } }); if (this.isMobile) { const buttonSize = 60; const padding = 40; // Create buttons this.leftBtn = this.add.rectangle(padding, this.scale.height - buttonSize - padding * 2, buttonSize, buttonSize, 0x6666ff).setInteractive(); this.rightBtn = this.add.rectangle(padding + buttonSize * 2, this.scale.height - buttonSize - padding * 2, buttonSize, buttonSize, 0x6666ff).setInteractive(); this.upBtn = this.add.rectangle(padding + buttonSize, this.scale.height - buttonSize * 2 - padding * 2, buttonSize, buttonSize, 0x6666ff).setInteractive(); this.downBtn = this.add.rectangle(padding + buttonSize, this.scale.height - padding * 2, buttonSize, buttonSize, 0x6666ff).setInteractive(); this.fireBtn = this.add.rectangle(this.scale.width - buttonSize - padding, this.scale.height - buttonSize - padding, buttonSize, buttonSize, 0xff6666).setInteractive(); // Button labels this.add.text(this.leftBtn.x, this.leftBtn.y, "←", { fontSize: "24px", fill: "#fff" }).setOrigin(0.5); this.add.text(this.rightBtn.x, this.rightBtn.y, "→", { fontSize: "24px", fill: "#fff" }).setOrigin(0.5); this.add.text(this.upBtn.x, this.upBtn.y, "↑", { fontSize: "24px", fill: "#fff" }).setOrigin(0.5); this.add.text(this.downBtn.x, this.downBtn.y, "↓", { fontSize: "24px", fill: "#fff" }).setOrigin(0.5); this.add.text(this.fireBtn.x, this.fireBtn.y, "FIRE", { fontSize: "18px", fill: "#fff" }).setOrigin(0.5); // Button states this.touchControls = { left: false, right: false, up: false, down: false, fire: false }; // Input handlers this.leftBtn.on("pointerdown", () => this.touchControls.left = true); this.rightBtn.on("pointerdown", () => this.touchControls.right = true); this.upBtn.on("pointerdown", () => this.touchControls.up = true); this.downBtn.on("pointerdown", () => this.touchControls.down = true); this.fireBtn.on("pointerdown", () => this.touchControls.fire = true); this.input.on("pointerup", () => { this.touchControls.left = false; this.touchControls.right = false; this.touchControls.up = false; this.touchControls.down = false; this.touchControls.fire = false; }); } // Randomize positions Phaser.Actions.RandomRectangle(this.stars.getChildren(), this.physics.world.bounds); // Scale each star down this.stars.children.iterate(star => { star.setScale(Phaser.Math.FloatBetween(0.15, 0.25)); star.setDepth(-1); // push stars behind everything }); // Groups this.bullets = this.physics.add.group(); this.enemies = this.physics.add.group(); // Enemy spawn timer this.time.addEvent({ delay: 2000, callback: () => this.spawnEnemy(), loop: true }); this.scoreText = this.add.text(this.scale.width - 20, 20, "Score: 0", { fontSize: "24px", fill: "#fff" }).setOrigin(1, 0); // anchor top-right this.killsText = this.add.text(this.scale.width - 20, 50, "Kills: 0", { fontSize: "24px", fill: "#fff" }).setOrigin(1, 0); // anchor top-right // Collision: bullets vs enemies this.physics.add.overlap(this.bullets, this.enemies, (bullet, enemy) => { bullet.destroy(); enemy.hp -= this.player.damage; if (enemy.hp <= 0) { this.score += enemy.scoreValue; this.kills+=1 this.killsText.setText("Kills: " + this.kills) this.scoreText.setText("Score: " + this.score); enemy.destroy(); } }); // Collision: enemies vs player this.physics.add.overlap(this.enemies, this.player, (playerObj, enemyObj) => { console.log("Player collided with "+enemyObj.name); console.log( "Reducing player hp by", enemyObj.damage, "from", playerObj.hp, "to", playerObj.hp - enemyObj.damage ); playerObj.hp -= enemyObj.damage; console.log("Destroying enemy-"+enemyObj.name+"."); enemyObj.destroy(); this.score += enemyObj.scoreValue; this.kills+=1 this.killsText.setText("Kills: "+this.kills) this.scoreText.setText("Score: " + this.score); if (playerObj.hp <= 0) { console.log("Player dead"); this.endGame(); } }); console.log("Creation complete") } update() { this.stars.children.iterate(star => { star.y += 1; // move down if (star.y > this.scale.height) { star.y = 0; // wrap to top star.x = Phaser.Math.Between(0, this.scale.width); } }); if (this.kills/100==0){ this.difficulty+=1 this.kills+=1 } if (this.isMobile) { if (this.touchControls.left) this.player.setVelocityX(-200); else if (this.touchControls.right) this.player.setVelocityX(200); else this.player.setVelocityX(0); if (this.touchControls.up) this.player.setVelocityY(-200); else if (this.touchControls.down) this.player.setVelocityY(200); else this.player.setVelocityY(0); } else { if (this.cursors.left.isDown || this.input.keyboard.keys[65].isDown) this.player.setVelocityX(-200); else if (this.cursors.right.isDown || this.input.keyboard.keys[68].isDown) this.player.setVelocityX(200); else this.player.setVelocityX(0); if (this.cursors.up.isDown || this.input.keyboard.keys[87].isDown) this.player.setVelocityY(-200); else if (this.cursors.down.isDown || this.input.keyboard.keys[83].isDown) this.player.setVelocityY(200); else this.player.setVelocityY(0); } let now = this.time.now; // Phaser's built-in clock if (this.isMobile) { if (this.touchControls.fire && now > this.lastFired + this.fireCooldown) { this.shootBullet(); this.lastFired = now; } } else { if (this.input.keyboard.keys[32].isDown && now > this.lastFired + this.fireCooldown) { this.shootBullet(); this.lastFired = now; } } } spawnEnemy() { let roll = Phaser.Math.Between(1, 3); let chosenDifficulty = this.difficulty + (roll === 1 ? -1 : roll === 3 ? +1 : 0); chosenDifficulty = Phaser.Math.Clamp(chosenDifficulty, 1, difficultyCap); let eligible = enemyTypes.filter(e => e.difficulty === chosenDifficulty); if (eligible.length > 0) { let chosen = Phaser.Utils.Array.GetRandom(eligible); let x = Phaser.Math.Between(50, this.sys.game.config.width - 50); let enemy = this.enemies.create(x, 0, chosen.key); enemy.setVelocityY(chosen.speed * 40); // Attach stats enemy.name = chosen.name; enemy.hp = chosen.hp; enemy.damage = chosen.damage; enemy.scoreValue = chosen.score; console.log("Enemy ",enemy.name,"created") } } endGame() { hiScore = Math.max(hiScore, this.score); this.scene.start("GameOverScene", { score: this.score, hiScore: hiScore }); } } // Game Over Scene class GameOverScene extends Phaser.Scene { constructor() { super("GameOverScene"); } preload() {} create(data) { this.add.text(this.scale.width / 2, this.scale.height / 3, `Score: ${data.score}`, { fontSize: "32px", fill: "#fff" }).setOrigin(0.5); this.add.text(this.scale.width / 2, this.scale.height / 2, `Hi-Score: ${data.hiScore}`, { fontSize: "32px", fill: "#ff0" }).setOrigin(0.5); this.time.delayedCall(3000, () => { this.scene.stop("GameScene"); this.scene.start("MenuScene"); }); } } // Game config const config = { type: Phaser.AUTO, width: window.innerWidth, height: window.innerHeight, backgroundColor: "#000000", parent: "game", physics: { default: "arcade", arcade: { debug: false } }, scene: [MenuScene, GameScene, GameOverScene], scale: { mode: Phaser.Scale.RESIZE, // auto-resize with window autoCenter: Phaser.Scale.CENTER_BOTH } }; new Phaser.Game(config);

By the way, yes, I did use a neural network to assist my in writing this code, because I am inexperienced at JavaScript.

Read Entire Article