|
@@ -573,134 +573,244 @@ class GameScene extends Phaser.Scene {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-enterShootingMode() {
|
|
|
|
- this.gameActive = false; // 暂停奔跑场景
|
|
|
|
- this.isShooting = true;
|
|
|
|
-
|
|
|
|
- // 清除现有障碍物
|
|
|
|
- this.obstacles.forEach(obs => obs.destroy());
|
|
|
|
- this.obstacles = [];
|
|
|
|
-
|
|
|
|
- // 创建射门场景背景
|
|
|
|
- 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(6);
|
|
|
|
-
|
|
|
|
- // 让守门员左右移动
|
|
|
|
- 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;
|
|
|
|
|
|
- // 调整球员位置(准备射门)
|
|
|
|
- this.player.setPosition(GAME_WIDTH/2, GAME_HEIGHT - 100);
|
|
|
|
- this.player.setTexture('playerShoot');
|
|
|
|
|
|
+ // 停止生成普通障碍物
|
|
|
|
+ if (this.obstacleTimer) {
|
|
|
|
+ this.obstacleTimer.remove();
|
|
|
|
+ }
|
|
|
|
|
|
- // 创建足球
|
|
|
|
- this.ball = this.physics.add.sprite(GAME_WIDTH/2, GAME_HEIGHT - 150, 'ballAnim');
|
|
|
|
- this.ball.setScale(0.8);
|
|
|
|
- this.ball.anims.play('ballAnim', true);
|
|
|
|
- this.ball.setDepth(7);
|
|
|
|
|
|
+ // 清除现有障碍物
|
|
|
|
+ this.obstacles.forEach(obs => obs.destroy());
|
|
|
|
+ this.obstacles = [];
|
|
|
|
+ this.powerUps.forEach(p => p.destroy());
|
|
|
|
+ this.powerUps = [];
|
|
|
|
|
|
- // 射门控制(空格键或触摸)
|
|
|
|
- this.input.keyboard.on('keydown-SPACE', this.shootBall, this);
|
|
|
|
- this.input.on('pointerdown', this.shootBall, this);
|
|
|
|
-}
|
|
|
|
|
|
+ // 创建射门场景背景
|
|
|
|
+ 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(6);
|
|
|
|
+
|
|
|
|
+ // 让守门员左右移动
|
|
|
|
+ this.tweens.add({
|
|
|
|
+ targets: this.goalkeeper,
|
|
|
|
+ x: [GAME_WIDTH / 2 - 50, GAME_WIDTH / 2 + 50],
|
|
|
|
+ duration: 2000,
|
|
|
|
+ ease: 'Sine.inOut',
|
|
|
|
+ repeat: -1,
|
|
|
|
+ yoyo: true
|
|
|
|
+ });
|
|
|
|
|
|
-shootBall() {
|
|
|
|
- if (!this.isShooting) return;
|
|
|
|
-
|
|
|
|
- // 移除射门输入监听(防止重复射门)
|
|
|
|
- this.input.keyboard.off('keydown-SPACE', this.shootBall, this);
|
|
|
|
- this.input.off('pointerdown', this.shootBall, this);
|
|
|
|
-
|
|
|
|
- // 足球飞行动画
|
|
|
|
- this.tweens.add({
|
|
|
|
- targets: this.ball,
|
|
|
|
- y: -50, // 飞向球门
|
|
|
|
- duration: 1000,
|
|
|
|
- ease: 'Power1',
|
|
|
|
- onUpdate: () => {
|
|
|
|
- // 检测射门结果(碰撞检测)
|
|
|
|
- if (Phaser.Geom.Intersects.RectangleToRectangle(
|
|
|
|
- this.ball.getBounds(),
|
|
|
|
- this.goalkeeper.getBounds()
|
|
|
|
- )) {
|
|
|
|
- // 被守门员挡住
|
|
|
|
- this.ball.setTint(0xff0000); // 变红
|
|
|
|
- this.failShoot();
|
|
|
|
- } else if (Phaser.Geom.Intersects.RectangleToRectangle(
|
|
|
|
- this.ball.getBounds(),
|
|
|
|
- this.goal.getBounds()
|
|
|
|
- )) {
|
|
|
|
- // 射入球门
|
|
|
|
- this.score += 3; // 射门得分
|
|
|
|
- this.updateScore();
|
|
|
|
- this.successShoot();
|
|
|
|
- }
|
|
|
|
|
|
+ // 调整球员位置(准备射门)
|
|
|
|
+ this.player.setPosition(GAME_WIDTH / 2, GAME_HEIGHT - 100);
|
|
|
|
+ this.player.setTexture('playerShoot');
|
|
|
|
+
|
|
|
|
+ // 创建足球
|
|
|
|
+ this.ball = this.physics.add.sprite(GAME_WIDTH / 2, GAME_HEIGHT - 150, 'ballAnim');
|
|
|
|
+ this.ball.setScale(0.8);
|
|
|
|
+ this.ball.anims.play('ballAnim', true);
|
|
|
|
+ this.ball.setDepth(7);
|
|
|
|
+
|
|
|
|
+ // 显示射门提示
|
|
|
|
+ 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;
|
|
|
|
+
|
|
|
|
+ // 移除射门输入监听(防止重复射门)
|
|
|
|
+ this.input.keyboard.off('keydown-SPACE', this.shootBall, this);
|
|
|
|
+ this.input.off('pointerdown', this.shootBall, this);
|
|
|
|
+
|
|
|
|
+ // 移除射门提示
|
|
|
|
+ if (this.shootHint) {
|
|
|
|
+ this.shootHint.destroy();
|
|
}
|
|
}
|
|
- });
|
|
|
|
-}
|
|
|
|
|
|
|
|
-// 射门成功处理
|
|
|
|
-successShoot() {
|
|
|
|
- this.isShooting = false;
|
|
|
|
- this.add.text(GAME_WIDTH/2, GAME_HEIGHT/2, '射门成功!', {
|
|
|
|
- fontSize: '24px',
|
|
|
|
- fill: '#0f0'
|
|
|
|
- }).setOrigin(0.5);
|
|
|
|
-
|
|
|
|
- // 2秒后返回奔跑场景
|
|
|
|
- setTimeout(() => {
|
|
|
|
- this.resetToRunningScene();
|
|
|
|
- }, 2000);
|
|
|
|
-}
|
|
|
|
|
|
+ // 足球飞行动画
|
|
|
|
+ this.tweens.add({
|
|
|
|
+ targets: this.ball,
|
|
|
|
+ y: -50, // 飞向球门
|
|
|
|
+ duration: 1000,
|
|
|
|
+ ease: 'Power1',
|
|
|
|
+ onUpdate: () => {
|
|
|
|
+ // 检测射门结果(碰撞检测)
|
|
|
|
+ if (Phaser.Geom.Intersects.RectangleToRectangle(
|
|
|
|
+ this.ball.getBounds(),
|
|
|
|
+ this.goalkeeper.getBounds()
|
|
|
|
+ )) {
|
|
|
|
+ // 被守门员挡住
|
|
|
|
+ this.ball.setTint(0xff0000); // 变红
|
|
|
|
+ this.time.addEvent({
|
|
|
|
+ delay: 500,
|
|
|
|
+ callback: this.failShoot,
|
|
|
|
+ callbackScope: this
|
|
|
|
+ });
|
|
|
|
+ } else if (Phaser.Geom.Intersects.RectangleToRectangle(
|
|
|
|
+ this.ball.getBounds(),
|
|
|
|
+ this.goal.getBounds()
|
|
|
|
+ )) {
|
|
|
|
+ // 射入球门
|
|
|
|
+ this.score += 3; // 射门得分
|
|
|
|
+ this.updateScore();
|
|
|
|
+ this.time.addEvent({
|
|
|
|
+ delay: 500,
|
|
|
|
+ callback: this.successShoot,
|
|
|
|
+ callbackScope: this
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
|
|
-// 射门失败处理
|
|
|
|
-failShoot() {
|
|
|
|
- this.isShooting = false;
|
|
|
|
- this.add.text(GAME_WIDTH/2, GAME_HEIGHT/2, '射门失败!', {
|
|
|
|
- fontSize: '24px',
|
|
|
|
- fill: '#f00'
|
|
|
|
- }).setOrigin(0.5);
|
|
|
|
-
|
|
|
|
- // 2秒后返回奔跑场景
|
|
|
|
- setTimeout(() => {
|
|
|
|
- this.resetToRunningScene();
|
|
|
|
- }, 2000);
|
|
|
|
-}
|
|
|
|
|
|
|
|
-// 重置为奔跑场景
|
|
|
|
-resetToRunningScene() {
|
|
|
|
- // 清除射门场景元素
|
|
|
|
- this.goal.destroy();
|
|
|
|
- this.goalkeeper.destroy();
|
|
|
|
- this.ball.destroy();
|
|
|
|
- this.children.each(child => {
|
|
|
|
- if (child.type === 'Text' && child.text.includes('射门')) child.destroy();
|
|
|
|
- });
|
|
|
|
|
|
+ shootBall() {
|
|
|
|
+ if (!this.isShooting) return;
|
|
|
|
+
|
|
|
|
+ // 移除射门输入监听(防止重复射门)
|
|
|
|
+ this.input.keyboard.off('keydown-SPACE', this.shootBall, this);
|
|
|
|
+ this.input.off('pointerdown', this.shootBall, this);
|
|
|
|
+
|
|
|
|
+ // 移除射门提示
|
|
|
|
+ if (this.shootHint) {
|
|
|
|
+ this.shootHint.destroy();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 足球飞行动画
|
|
|
|
+ this.tweens.add({
|
|
|
|
+ targets: this.ball,
|
|
|
|
+ y: -50, // 飞向球门
|
|
|
|
+ duration: 1000,
|
|
|
|
+ ease: 'Power1',
|
|
|
|
+ onUpdate: () => {
|
|
|
|
+ // 检测射门结果(碰撞检测)
|
|
|
|
+ if (Phaser.Geom.Intersects.RectangleToRectangle(
|
|
|
|
+ this.ball.getBounds(),
|
|
|
|
+ this.goalkeeper.getBounds()
|
|
|
|
+ )) {
|
|
|
|
+ // 被守门员挡住
|
|
|
|
+ this.ball.setTint(0xff0000); // 变红
|
|
|
|
+ this.time.addEvent({
|
|
|
|
+ delay: 500,
|
|
|
|
+ callback: this.failShoot,
|
|
|
|
+ callbackScope: this
|
|
|
|
+ });
|
|
|
|
+ } else if (Phaser.Geom.Intersects.RectangleToRectangle(
|
|
|
|
+ this.ball.getBounds(),
|
|
|
|
+ this.goal.getBounds()
|
|
|
|
+ )) {
|
|
|
|
+ // 射入球门
|
|
|
|
+ this.score += 3; // 射门得分
|
|
|
|
+ this.updateScore();
|
|
|
|
+ this.time.addEvent({
|
|
|
|
+ delay: 500,
|
|
|
|
+ callback: this.successShoot,
|
|
|
|
+ callbackScope: this
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
|
|
- // 恢复奔跑场景
|
|
|
|
- this.background.setTexture('grass');
|
|
|
|
- this.player.setTexture('playerAnim');
|
|
|
|
- this.gameActive = true;
|
|
|
|
- this.startSpawning(); // 重新开始生成障碍物
|
|
|
|
-}
|
|
|
|
|
|
+ // 射门成功处理
|
|
|
|
+ successShoot() {
|
|
|
|
+ this.isShooting = false;
|
|
|
|
+
|
|
|
|
+ // 显示成功提示
|
|
|
|
+ const successText = this.add.text(GAME_WIDTH/2, GAME_HEIGHT/2, '射门成功!+3分', {
|
|
|
|
+ fontSize: '24px',
|
|
|
|
+ fill: '#0f0',
|
|
|
|
+ stroke: '#000000',
|
|
|
|
+ strokeThickness: 2
|
|
|
|
+ }).setOrigin(0.5);
|
|
|
|
+ successText.setDepth(10);
|
|
|
|
+
|
|
|
|
+ // 2秒后返回奔跑场景
|
|
|
|
+ this.time.addEvent({
|
|
|
|
+ delay: 2000,
|
|
|
|
+ callback: this.resetToRunningScene,
|
|
|
|
+ callbackScope: this
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 射门失败处理
|
|
|
|
+ failShoot() {
|
|
|
|
+ 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);
|
|
|
|
+
|
|
|
|
+ // 2秒后返回奔跑场景
|
|
|
|
+ this.time.addEvent({
|
|
|
|
+ delay: 2000,
|
|
|
|
+ callback: this.resetToRunningScene,
|
|
|
|
+ callbackScope: this
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 重置为奔跑场景
|
|
|
|
+ resetToRunningScene() {
|
|
|
|
+ // 清除射门场景元素
|
|
|
|
+ if (this.goal) {
|
|
|
|
+ this.goal.destroy();
|
|
|
|
+ this.goal = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.goalkeeper) {
|
|
|
|
+ this.goalkeeper.destroy();
|
|
|
|
+ this.goalkeeper = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.ball) {
|
|
|
|
+ this.ball.destroy();
|
|
|
|
+ this.ball = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 移除所有文本提示
|
|
|
|
+ this.children.each(child => {
|
|
|
|
+ if (child.type === 'Text') {
|
|
|
|
+ child.destroy();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 恢复奔跑场景
|
|
|
|
+ this.background.setTexture('grass');
|
|
|
|
+ this.player.setTexture('playerAnim');
|
|
|
|
+ this.gameActive = true;
|
|
|
|
+ this.isShooting = false;
|
|
|
|
+
|
|
|
|
+ // 重新开始生成障碍物
|
|
|
|
+ this.startSpawning();
|
|
|
|
+ }
|
|
|
|
|
|
gameOver() {
|
|
gameOver() {
|
|
this.gameActive = false;
|
|
this.gameActive = false;
|
|
@@ -724,20 +834,28 @@ resetToRunningScene() {
|
|
|
|
|
|
update() {
|
|
update() {
|
|
if (!this.gameActive) return;
|
|
if (!this.gameActive) return;
|
|
-
|
|
|
|
- // 滚动背景
|
|
|
|
- this.background.tilePositionY -= this.speed * this.acceleration;
|
|
|
|
-
|
|
|
|
- // 键盘控制
|
|
|
|
- if (this.cursors.left.isDown) {
|
|
|
|
- this.player.setVelocityX(-200);
|
|
|
|
- this.player.anims.play('playerLeft', true);
|
|
|
|
- } else if (this.cursors.right.isDown) {
|
|
|
|
- this.player.setVelocityX(200);
|
|
|
|
- this.player.anims.play('playerRight', true);
|
|
|
|
- } else {
|
|
|
|
- this.player.setVelocityX(0);
|
|
|
|
- this.player.anims.stop();
|
|
|
|
|
|
+
|
|
|
|
+ // 背景滚动(根据玩家位置调整速度)
|
|
|
|
+ const scrollSpeed = this.speed * this.acceleration;
|
|
|
|
+ this.background.tilePositionY -= scrollSpeed;
|
|
|
|
+
|
|
|
|
+ // 键盘控制(仅在奔跑模式下)
|
|
|
|
+ if (!this.isShooting) {
|
|
|
|
+ if (this.cursors.left.isDown) {
|
|
|
|
+ this.player.setVelocityX(-200);
|
|
|
|
+ this.player.anims.play('playerLeft', true);
|
|
|
|
+ } else if (this.cursors.right.isDown) {
|
|
|
|
+ this.player.setVelocityX(200);
|
|
|
|
+ this.player.anims.play('playerRight', true);
|
|
|
|
+ } else if (this.cursors.up.isDown) {
|
|
|
|
+ this.player.setVelocityY(-150);
|
|
|
|
+ } else if (this.cursors.down.isDown) {
|
|
|
|
+ this.player.setVelocityY(150);
|
|
|
|
+ } else {
|
|
|
|
+ this.player.setVelocityX(0);
|
|
|
|
+ this.player.setVelocityY(0);
|
|
|
|
+ this.player.anims.stop();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|