|
@@ -631,90 +631,93 @@ class GameScene extends Phaser.Scene {
|
|
|
|
|
|
|
|
|
}
|
|
|
-enterShootingMode() {
|
|
|
- this.gameActive = false;
|
|
|
- this.isShooting = true;
|
|
|
-
|
|
|
- // 关键修复:重置键盘状态,清除所有按键的按下状态
|
|
|
- this.input.keyboard.resetKeys();
|
|
|
- // 额外保险:手动清除方向键状态
|
|
|
- this.cursors.left.isDown = false;
|
|
|
- this.cursors.right.isDown = false;
|
|
|
- this.cursors.up.isDown = false;
|
|
|
- this.cursors.down.isDown = false;
|
|
|
-
|
|
|
- // 停止所有生成事件
|
|
|
- if (this.obstacleEvent) this.obstacleEvent.remove();
|
|
|
- if (this.jerseyEvent) this.jerseyEvent.remove();
|
|
|
- if (this.broomEvent) this.broomEvent.remove();
|
|
|
-
|
|
|
- // 清除现有障碍物和道具
|
|
|
- this.obstacles.forEach(obs => obs.destroy());
|
|
|
- this.obstacles = [];
|
|
|
- this.powerUps.forEach(p => p.destroy());
|
|
|
- this.powerUps = [];
|
|
|
-
|
|
|
- // 创建射门场景背景
|
|
|
- this.background.setTexture('goalBackground');
|
|
|
-
|
|
|
- // 创建球门
|
|
|
- this.goal = this.physics.add.sprite(GAME_WIDTH / 2, 100, 'goal');
|
|
|
- this.goal.setScale(0.8);
|
|
|
- this.goal.setImmovable(true);
|
|
|
- this.goal.setDepth(5);
|
|
|
-
|
|
|
- // 创建守门员
|
|
|
- this.goalkeeper = this.physics.add.sprite(GAME_WIDTH / 2, 150, 'goalkeeperAnim');
|
|
|
- this.goalkeeper.setScale(0.9);
|
|
|
- this.goalkeeper.setImmovable(true);
|
|
|
- this.goalkeeper.anims.play('goalkeeperAnim', true);
|
|
|
- this.goalkeeper.setDepth(7);
|
|
|
-
|
|
|
- // 让守门员左右移动
|
|
|
- this.tweens.add({
|
|
|
- targets: this.goalkeeper,
|
|
|
- x: [GAME_WIDTH / 2 - 50, GAME_WIDTH / 2 + 50],
|
|
|
- duration: 2000,
|
|
|
- ease: 'Sine.inOut',
|
|
|
- repeat: -1,
|
|
|
- yoyo: true
|
|
|
- });
|
|
|
+ enterShootingMode() {
|
|
|
+ this.gameActive = false;
|
|
|
+ this.isShooting = true;
|
|
|
+ // 暂停计分定时器
|
|
|
+ if (this.timer) {
|
|
|
+ this.timer.paused = true;
|
|
|
+ }
|
|
|
+ // 关键修复:重置键盘状态,清除所有按键的按下状态
|
|
|
+ this.input.keyboard.resetKeys();
|
|
|
+ // 额外保险:手动清除方向键状态
|
|
|
+ this.cursors.left.isDown = false;
|
|
|
+ this.cursors.right.isDown = false;
|
|
|
+ this.cursors.up.isDown = false;
|
|
|
+ this.cursors.down.isDown = false;
|
|
|
+
|
|
|
+ // 停止所有生成事件
|
|
|
+ if (this.obstacleEvent) this.obstacleEvent.remove();
|
|
|
+ if (this.jerseyEvent) this.jerseyEvent.remove();
|
|
|
+ if (this.broomEvent) this.broomEvent.remove();
|
|
|
|
|
|
- // 调整球员位置(准备射门)
|
|
|
- this.player.setPosition(GAME_WIDTH / 2, GAME_HEIGHT - 100);
|
|
|
- this.player.setTexture('playerShoot');
|
|
|
- // 关键修复:停止玩家所有移动
|
|
|
- this.player.setVelocity(0);
|
|
|
-
|
|
|
- // 创建足球(修复:让足球跟随玩家位置)
|
|
|
- this.ball = this.physics.add.sprite(this.player.x, this.player.y - 50, 'ballAnim');
|
|
|
- this.ball.setScale(0.8);
|
|
|
- this.ball.anims.play('ballAnim', true);
|
|
|
- this.ball.setDepth(8);
|
|
|
-
|
|
|
- // 显示射门提示
|
|
|
- this.shootHint = this.add.text(GAME_WIDTH / 2, GAME_HEIGHT - 50, '点击或按空格键射门', {
|
|
|
- fontSize: '16px',
|
|
|
- fill: '#ffffff',
|
|
|
- backgroundColor: 'rgba(0,0,0,0.5)',
|
|
|
- padding: { x: 5, y: 2 }
|
|
|
- }).setOrigin(0.5);
|
|
|
- this.shootHint.setDepth(10);
|
|
|
-
|
|
|
- // 射门控制
|
|
|
- this.input.keyboard.on('keydown-SPACE', this.shootBall, this);
|
|
|
- this.input.on('pointerdown', this.shootBall, this);
|
|
|
-}
|
|
|
+ // 清除现有障碍物和道具
|
|
|
+ this.obstacles.forEach(obs => obs.destroy());
|
|
|
+ this.obstacles = [];
|
|
|
+ this.powerUps.forEach(p => p.destroy());
|
|
|
+ this.powerUps = [];
|
|
|
+
|
|
|
+ // 创建射门场景背景
|
|
|
+ this.background.setTexture('goalBackground');
|
|
|
+
|
|
|
+ // 创建球门
|
|
|
+ this.goal = this.physics.add.sprite(GAME_WIDTH / 2, 100, 'goal');
|
|
|
+ this.goal.setScale(0.8);
|
|
|
+ this.goal.setImmovable(true);
|
|
|
+ this.goal.setDepth(5);
|
|
|
+
|
|
|
+ // 创建守门员
|
|
|
+ this.goalkeeper = this.physics.add.sprite(GAME_WIDTH / 2, 150, 'goalkeeperAnim');
|
|
|
+ this.goalkeeper.setScale(0.9);
|
|
|
+ this.goalkeeper.setImmovable(true);
|
|
|
+ this.goalkeeper.anims.play('goalkeeperAnim', true);
|
|
|
+ this.goalkeeper.setDepth(7);
|
|
|
+
|
|
|
+ // 让守门员左右移动
|
|
|
+ this.tweens.add({
|
|
|
+ targets: this.goalkeeper,
|
|
|
+ x: [GAME_WIDTH / 2 - 50, GAME_WIDTH / 2 + 50],
|
|
|
+ duration: 2000,
|
|
|
+ ease: 'Sine.inOut',
|
|
|
+ repeat: -1,
|
|
|
+ yoyo: true
|
|
|
+ });
|
|
|
+
|
|
|
+ // 调整球员位置(准备射门)
|
|
|
+ this.player.setPosition(GAME_WIDTH / 2, GAME_HEIGHT - 100);
|
|
|
+ this.player.setTexture('playerShoot');
|
|
|
+ // 关键修复:停止玩家所有移动
|
|
|
+ this.player.setVelocity(0);
|
|
|
+
|
|
|
+ // 创建足球(修复:让足球跟随玩家位置)
|
|
|
+ this.ball = this.physics.add.sprite(this.player.x, this.player.y - 50, 'ballAnim');
|
|
|
+ this.ball.setScale(0.8);
|
|
|
+ this.ball.anims.play('ballAnim', true);
|
|
|
+ this.ball.setDepth(8);
|
|
|
+
|
|
|
+ // 显示射门提示
|
|
|
+ this.shootHint = this.add.text(GAME_WIDTH / 2, GAME_HEIGHT - 50, '点击或按空格键射门', {
|
|
|
+ fontSize: '16px',
|
|
|
+ fill: '#ffffff',
|
|
|
+ backgroundColor: 'rgba(0,0,0,0.5)',
|
|
|
+ padding: { x: 5, y: 2 }
|
|
|
+ }).setOrigin(0.5);
|
|
|
+ this.shootHint.setDepth(10);
|
|
|
+
|
|
|
+ // 射门控制
|
|
|
+ this.input.keyboard.on('keydown-SPACE', this.shootBall, this);
|
|
|
+ this.input.on('pointerdown', this.shootBall, this);
|
|
|
+ }
|
|
|
|
|
|
shootBall() {
|
|
|
- if (!this.isShooting) return;
|
|
|
+ if (!this.isShooting) return;
|
|
|
|
|
|
- // 禁用输入
|
|
|
- this.input.keyboard.off('keydown-SPACE', this.shootBall, this);
|
|
|
- this.input.off('pointerdown', this.shootBall, this);
|
|
|
- // 移除射门模式下的左右移动监听(如果添加了)
|
|
|
- this.input.keyboard.off('keydown-LEFT');
|
|
|
- this.input.keyboard.off('keydown-RIGHT');
|
|
|
+ // 禁用输入
|
|
|
+ this.input.keyboard.off('keydown-SPACE', this.shootBall, this);
|
|
|
+ this.input.off('pointerdown', this.shootBall, this);
|
|
|
+ // 移除射门模式下的左右移动监听(如果添加了)
|
|
|
+ this.input.keyboard.off('keydown-LEFT');
|
|
|
+ this.input.keyboard.off('keydown-RIGHT');
|
|
|
|
|
|
if (this.shootHint) {
|
|
|
this.shootHint.destroy();
|
|
@@ -772,80 +775,88 @@ enterShootingMode() {
|
|
|
}
|
|
|
this.ball.destroy();
|
|
|
this.resetToRunningScene();
|
|
|
+ // 恢复计分定时器
|
|
|
+ if (this.timer) {
|
|
|
+ this.timer.paused = false;
|
|
|
+ }
|
|
|
},
|
|
|
callbackScope: this
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-// 射门失败处理
|
|
|
-failShoot() {
|
|
|
- this.isShooting = false;
|
|
|
-
|
|
|
- // 关键修复1:解除足球的物理控制
|
|
|
- this.ball.setVelocity(0);
|
|
|
- this.ball.setImmovable(true);
|
|
|
- this.physics.world.disable(this.ball); // 完全禁用物理引擎对足球的控制
|
|
|
-
|
|
|
- // 关键修复2:调整足球位置到守门员前方固定位置,不跟随移动
|
|
|
- this.ball.setPosition(
|
|
|
- this.goalkeeper.x,
|
|
|
- this.goalkeeper.y + 20 // 固定在守门员前方20px处
|
|
|
- );
|
|
|
-
|
|
|
- // 显示失败提示
|
|
|
- const failText = this.add.text(GAME_WIDTH / 2, GAME_HEIGHT / 2, '射门失败!', {
|
|
|
- fontSize: '24px',
|
|
|
- fill: '#f00',
|
|
|
- stroke: '#000000',
|
|
|
- strokeThickness: 2
|
|
|
- }).setOrigin(0.5);
|
|
|
- failText.setDepth(10);
|
|
|
-
|
|
|
- // 2秒后返回奔跑场景
|
|
|
- this.time.addEvent({
|
|
|
- delay: 2000,
|
|
|
- callback: () => {
|
|
|
- if (failText && failText.active) {
|
|
|
- failText.destroy();
|
|
|
- }
|
|
|
- this.ball.destroy(); // 确保足球被销毁
|
|
|
- this.resetToRunningScene();
|
|
|
- },
|
|
|
- callbackScope: this
|
|
|
- });
|
|
|
-}
|
|
|
+ // 射门失败处理
|
|
|
+ failShoot() {
|
|
|
+ this.isShooting = false;
|
|
|
|
|
|
- // 重置为奔跑场景
|
|
|
-resetToRunningScene() {
|
|
|
- this.clearScene();
|
|
|
+ // 关键修复1:解除足球的物理控制
|
|
|
+ this.ball.setVelocity(0);
|
|
|
+ this.ball.setImmovable(true);
|
|
|
+ this.physics.world.disable(this.ball); // 完全禁用物理引擎对足球的控制
|
|
|
|
|
|
- // 重置玩家状态
|
|
|
- if (this.player) {
|
|
|
- this.player.setTexture('playerAnim');
|
|
|
- this.player.setPosition(GAME_WIDTH / 2, GAME_HEIGHT - 100);
|
|
|
- this.player.setVelocity(0);
|
|
|
- }
|
|
|
+ // 关键修复2:调整足球位置到守门员前方固定位置,不跟随移动
|
|
|
+ this.ball.setPosition(
|
|
|
+ this.goalkeeper.x,
|
|
|
+ this.goalkeeper.y + 20 // 固定在守门员前方20px处
|
|
|
+ );
|
|
|
|
|
|
- // 恢复背景和游戏状态
|
|
|
- if (this.background) this.background.setTexture('grass');
|
|
|
- this.gameActive = true;
|
|
|
- this.isShooting = false;
|
|
|
+ // 显示失败提示
|
|
|
+ const failText = this.add.text(GAME_WIDTH / 2, GAME_HEIGHT / 2, '射门失败!', {
|
|
|
+ fontSize: '24px',
|
|
|
+ fill: '#f00',
|
|
|
+ stroke: '#000000',
|
|
|
+ strokeThickness: 2
|
|
|
+ }).setOrigin(0.5);
|
|
|
+ failText.setDepth(10);
|
|
|
|
|
|
- // 关键:确保所有射门场景元素被彻底清理
|
|
|
- if (this.ball) {
|
|
|
- this.ball.destroy();
|
|
|
- this.ball = null; // 显式置空引用
|
|
|
+ // 2秒后返回奔跑场景
|
|
|
+ this.time.addEvent({
|
|
|
+ delay: 2000,
|
|
|
+ callback: () => {
|
|
|
+ if (failText && failText.active) {
|
|
|
+ failText.destroy();
|
|
|
+ }
|
|
|
+ this.ball.destroy(); // 确保足球被销毁
|
|
|
+ this.resetToRunningScene();
|
|
|
+ // 恢复计分定时器
|
|
|
+ if (this.timer) {
|
|
|
+ this.timer.paused = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ callbackScope: this
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- // 重新开始生成障碍物
|
|
|
- this.startSpawning();
|
|
|
-}
|
|
|
+ // 重置为奔跑场景
|
|
|
+ resetToRunningScene() {
|
|
|
+ this.clearScene();
|
|
|
+
|
|
|
+ // 重置玩家状态
|
|
|
+ if (this.player) {
|
|
|
+ this.player.setTexture('playerAnim');
|
|
|
+ this.player.setPosition(GAME_WIDTH / 2, GAME_HEIGHT - 100);
|
|
|
+ this.player.setVelocity(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 恢复背景和游戏状态
|
|
|
+ if (this.background) this.background.setTexture('grass');
|
|
|
+ this.gameActive = true;
|
|
|
+ this.isShooting = false;
|
|
|
+
|
|
|
+ // 关键:确保所有射门场景元素被彻底清理
|
|
|
+ if (this.ball) {
|
|
|
+ this.ball.destroy();
|
|
|
+ this.ball = null; // 显式置空引用
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重新开始生成障碍物
|
|
|
+ this.startSpawning();
|
|
|
+ }
|
|
|
|
|
|
gameOver() {
|
|
|
this.gameActive = false;
|
|
|
|
|
|
// 清理所有定时事件
|
|
|
- if (this.timer) this.timer.remove();
|
|
|
+ if (this.timer) this.timer.remove(); this.timer = null;
|
|
|
if (this.obstacleEvent) this.obstacleEvent.remove();
|
|
|
if (this.jerseyEvent) this.jerseyEvent.remove();
|
|
|
if (this.broomEvent) this.broomEvent.remove();
|
|
@@ -868,69 +879,69 @@ resetToRunningScene() {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-update() {
|
|
|
- if (!this.gameActive) return;
|
|
|
+ update() {
|
|
|
+ if (!this.gameActive) return;
|
|
|
|
|
|
- // 关键修复:射门模式下直接返回,不执行任何移动逻辑
|
|
|
- if (this.isShooting) return;
|
|
|
+ // 关键修复:射门模式下直接返回,不执行任何移动逻辑
|
|
|
+ if (this.isShooting) return;
|
|
|
|
|
|
- // 玩家移动逻辑(原有代码保持不变)
|
|
|
- if (this.player && this.player.active) {
|
|
|
- if (this.cursors.left.isDown) {
|
|
|
- this.player.setVelocityX(-200);
|
|
|
- if (this.player.anims.currentAnim?.key !== 'playerLeft' && !this.player.anims.paused) {
|
|
|
- this.player.anims.play('playerLeft', true);
|
|
|
- }
|
|
|
- } else if (this.cursors.right.isDown) {
|
|
|
- this.player.setVelocityX(200);
|
|
|
- if (this.player.anims.currentAnim?.key !== 'playerRight' && !this.player.anims.paused) {
|
|
|
- this.player.anims.play('playerRight', true);
|
|
|
- }
|
|
|
- } else if (this.cursors.up.isDown) {
|
|
|
- this.player.setVelocityY(-200);
|
|
|
- if (this.player.anims.currentAnim?.key === 'playerLeft' && !this.player.anims.paused) {
|
|
|
- this.player.anims.play('playerLeft', true);
|
|
|
- } else if (this.player.anims.currentAnim?.key === 'playerRight' && !this.player.anims.paused) {
|
|
|
- this.player.anims.play('playerRight', true);
|
|
|
- } else {
|
|
|
- this.player.anims.play('playerLeft', true);
|
|
|
- }
|
|
|
- } else if (this.cursors.down.isDown) {
|
|
|
- this.player.setVelocityY(200);
|
|
|
- if (this.player.anims.currentAnim?.key === 'playerLeft' && !this.player.anims.paused) {
|
|
|
- this.player.anims.play('playerLeft', true);
|
|
|
- } else if (this.player.anims.currentAnim?.key === 'playerRight' && !this.player.anims.paused) {
|
|
|
- this.player.anims.play('playerRight', true);
|
|
|
+ // 玩家移动逻辑(原有代码保持不变)
|
|
|
+ if (this.player && this.player.active) {
|
|
|
+ if (this.cursors.left.isDown) {
|
|
|
+ this.player.setVelocityX(-200);
|
|
|
+ if (this.player.anims.currentAnim?.key !== 'playerLeft' && !this.player.anims.paused) {
|
|
|
+ this.player.anims.play('playerLeft', true);
|
|
|
+ }
|
|
|
+ } else if (this.cursors.right.isDown) {
|
|
|
+ this.player.setVelocityX(200);
|
|
|
+ if (this.player.anims.currentAnim?.key !== 'playerRight' && !this.player.anims.paused) {
|
|
|
+ this.player.anims.play('playerRight', true);
|
|
|
+ }
|
|
|
+ } else if (this.cursors.up.isDown) {
|
|
|
+ this.player.setVelocityY(-200);
|
|
|
+ if (this.player.anims.currentAnim?.key === 'playerLeft' && !this.player.anims.paused) {
|
|
|
+ this.player.anims.play('playerLeft', true);
|
|
|
+ } else if (this.player.anims.currentAnim?.key === 'playerRight' && !this.player.anims.paused) {
|
|
|
+ this.player.anims.play('playerRight', true);
|
|
|
+ } else {
|
|
|
+ this.player.anims.play('playerLeft', true);
|
|
|
+ }
|
|
|
+ } else if (this.cursors.down.isDown) {
|
|
|
+ this.player.setVelocityY(200);
|
|
|
+ if (this.player.anims.currentAnim?.key === 'playerLeft' && !this.player.anims.paused) {
|
|
|
+ this.player.anims.play('playerLeft', true);
|
|
|
+ } else if (this.player.anims.currentAnim?.key === 'playerRight' && !this.player.anims.paused) {
|
|
|
+ this.player.anims.play('playerRight', true);
|
|
|
+ } else {
|
|
|
+ this.player.anims.play('playerLeft', true);
|
|
|
+ }
|
|
|
} else {
|
|
|
- this.player.anims.play('playerLeft', true);
|
|
|
+ this.player.setVelocityX(0);
|
|
|
+ this.player.setVelocityY(0);
|
|
|
+ this.player.anims.stop();
|
|
|
}
|
|
|
- } else {
|
|
|
- this.player.setVelocityX(0);
|
|
|
- this.player.setVelocityY(0);
|
|
|
- this.player.anims.stop();
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
// 添加 clearScene 方法
|
|
|
-clearScene() {
|
|
|
- // 清理射门场景的元素
|
|
|
- if (this.goal) this.goal.destroy();
|
|
|
- if (this.goalkeeper) this.goalkeeper.destroy();
|
|
|
- if (this.ball) {
|
|
|
- this.ball.destroy();
|
|
|
- this.ball = null; // 显式置空
|
|
|
- }
|
|
|
- if (this.shootHint) this.shootHint.destroy();
|
|
|
+ clearScene() {
|
|
|
+ // 清理射门场景的元素
|
|
|
+ if (this.goal) this.goal.destroy();
|
|
|
+ if (this.goalkeeper) this.goalkeeper.destroy();
|
|
|
+ if (this.ball) {
|
|
|
+ this.ball.destroy();
|
|
|
+ this.ball = null; // 显式置空
|
|
|
+ }
|
|
|
+ if (this.shootHint) this.shootHint.destroy();
|
|
|
|
|
|
- // 清理所有障碍物和道具
|
|
|
- this.obstacles.forEach(obs => obs.destroy());
|
|
|
- this.powerUps.forEach(p => p.destroy());
|
|
|
- this.obstacles = [];
|
|
|
- this.powerUps = [];
|
|
|
+ // 清理所有障碍物和道具
|
|
|
+ this.obstacles.forEach(obs => obs.destroy());
|
|
|
+ this.powerUps.forEach(p => p.destroy());
|
|
|
+ this.obstacles = [];
|
|
|
+ this.powerUps = [];
|
|
|
|
|
|
- // 停止所有动画
|
|
|
- this.tweens.killAll();
|
|
|
-}
|
|
|
+ // 停止所有动画
|
|
|
+ this.tweens.killAll();
|
|
|
+ }
|
|
|
|
|
|
// 新增:场景销毁时清理资源
|
|
|
destroy() {
|