为Phaser.js开发的Bug Dodger游戏添加移动端触摸控制功能
Hey there! Let's get that mobile touch control sorted for your Bug Dodger game. Here's a straightforward, step-by-step guide to implement the feature where tapping/holding the left half of the screen moves the player left, and tapping/holding the right half moves them right (we'll also cover an alternative player-relative control if that's what you're after):
Step 1: Understand the Current Touch Logic
Your existing code has a basic touch implementation tied to the player's current position. We'll replace that with a more intuitive mobile-friendly control scheme that works consistently across devices.
Step 2: Define Screen Control Boundaries
For your game's 450px width, we'll split the screen into two equal halves at the 225px midpoint. Any input left of this line triggers left movement; input right of it triggers right movement. This is easier for mobile users to intuitively use.
Step 3: Update the update() Function
Replace your existing update() function with this modified version. It retains keyboard controls for desktop users while adding robust mobile touch support:
function update() { // Keep existing keyboard control logic if (gameState.cursors.left.isDown) { gameState.player.setVelocityX(-160); } else if (gameState.cursors.right.isDown) { gameState.player.setVelocityX(160); } // New mobile touch controls (handles tap/hold) else if (this.input.activePointer.isDown) { const screenMidpoint = this.scale.width / 2; // Touch left half = move left if (this.input.activePointer.worldX < screenMidpoint) { gameState.player.setVelocityX(-160); } // Touch right half = move right else { gameState.player.setVelocityX(160); } } // Stop movement when no input is detected else { gameState.player.setVelocityX(0); } }
Step 4: Optional: Player-Relative Touch Control
If you specifically want touch input to react relative to the player's current position (instead of fixed screen halves), use this variant of the touch logic in the update() function:
// Inside the update() function's touch block else if (this.input.activePointer.isDown) { const playerCenterX = gameState.player.getCenter().x; // Touch left of the player's center = move left if (this.input.activePointer.worldX < playerCenterX) { gameState.player.setVelocityX(-160); } // Touch right of the player's center = move right else { gameState.player.setVelocityX(160); } }
Step 5: Test the Implementation
To verify everything works:
- Save your modified
game.jsfile - Load the HTML file on a mobile device (or use your browser's dev tools mobile emulator)
- Tap/hold the left or right screen regions to confirm smooth player movement
Full Modified Game Code
Here's the complete updated game code with fixed screen-region touch controls:
function preload() { this.load.image('bug1', 'https://s3.amazonaws.com/codecademy-content/courses/learn-phaser/physics/bug_1.png'); this.load.image('bug2', 'https://s3.amazonaws.com/codecademy-content/courses/learn-phaser/physics/bug_2.png'); this.load.image('bug3', 'https://s3.amazonaws.com/codecademy-content/courses/learn-phaser/physics/bug_3.png'); this.load.image('platform', 'https://s3.amazonaws.com/codecademy-content/courses/learn-phaser/physics/platform.png'); this.load.image('codey', 'https://s3.amazonaws.com/codecademy-content/courses/learn-phaser/physics/codey.png'); } const gameState = { score: 0 }; function create() { gameState.player = this.physics.add.sprite(225, 450, 'codey').setScale(.5); const platforms = this.physics.add.staticGroup(); platforms.create(225, 490, 'platform').setScale(1, .3).refreshBody(); gameState.scoreText = this.add.text(195, 485, 'Score: 0', { fontSize: '15px', fill: '#000000' }); gameState.player.setCollideWorldBounds(true); this.physics.add.collider(gameState.player, platforms); gameState.cursors = this.input.keyboard.createCursorKeys(); const bugs = this.physics.add.group(); function bugGen () { const xCoord1 = Math.random() * 450; const xCoord2 = Math.random() * 450; const xCoord3 = Math.random() * 450; bugs.create(xCoord1, 10, 'bug1'); bugs.create(xCoord2, 10, 'bug2'); bugs.create(xCoord3, 10, 'bug3'); } const bugGenLoop = this.time.addEvent({ delay: 500, callback: bugGen, callbackScope: this, loop: true, }); this.physics.add.collider(bugs, platforms, function (bug) { bug.destroy(); gameState.score += 10; gameState.scoreText.setText(`Score: ${gameState.score}`); }) this.physics.add.collider(gameState.player, bugs, () => { bugGenLoop.destroy(); this.physics.pause(); this.add.text(180, 250, 'Game Over', { fontSize: '15px', fill: '#000000' }); this.add.text(152, 270, 'Click to Restart', { fontSize: '15px', fill: '#000000' }); this.input.on('pointerup', () =>{ gameState.score = 0; this.scene.restart(); }); }); } function update() { if (gameState.cursors.left.isDown) { gameState.player.setVelocityX(-160); } else if (gameState.cursors.right.isDown) { gameState.player.setVelocityX(160); } else if (this.input.activePointer.isDown) { const screenMidpoint = this.scale.width / 2; if (this.input.activePointer.worldX < screenMidpoint) { gameState.player.setVelocityX(-160); } else { gameState.player.setVelocityX(160); } } else { gameState.player.setVelocityX(0); } } const config = { type: Phaser.AUTO, width: 450, height: 500, backgroundColor: "b9eaff", physics: { default: 'arcade', arcade: { gravity: { y: 50 }, enableBody: true, } }, scene: { preload, create, update } }; const game = new Phaser.Game(config);
Your HTML code remains unchanged:
<html lang="en"> <head> <meta charset="UTF-8" /> <title>Bug Dodger</title> <style> canvas { width: 100%; } </style> </head> <body> <script src="https://cdn.jsdelivr.net/npm/phaser@3.16.2/dist/phaser.min.js"></script> <script defer src="game.js"></script> </body> </html>
Key Improvements
- Intuitive mobile touch controls that work with both taps and holds
- Retains full keyboard support for desktop players
- Uses dynamic screen midpoint calculation (works even if you adjust game width later)
内容的提问来源于stack exchange,提问作者Ankur Gupta

