Skip to content

Commit 852c95a

Browse files
committed
修复输入问题
1 parent 9220948 commit 852c95a

File tree

3 files changed

+77
-67
lines changed

3 files changed

+77
-67
lines changed

src/scenes/GameScene.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ import SummonManager from "../managers/SummonManager";
1616
import RenderManager from "../managers/RenderManager";
1717
import WeatherManager from "../managers/WeatherManager";
1818
import AudioManager from "../managers/AudioManager";
19+
import InputZones from "../ui/InputZones";
1920

2021
export default class GameScene extends Phaser.Scene {
2122
// ✅ 1. 类型改为 Player 类
2223
public player!: Player;
24+
private inputZones!: InputZones; // ✅ 新增属性
2325
// ✅ 修改类型:现在这是“可交互实体”组,不仅放云,以后也能放鸟
2426
public interactables!: Phaser.Physics.Arcade.Group;
2527
public backgroundManager!: BackgroundManager; // ✅ 新增
@@ -114,6 +116,7 @@ export default class GameScene extends Phaser.Scene {
114116
);
115117

116118
this.scene.launch(SceneKeys.UI); // 启动 UI 场景
119+
this.inputZones = new InputZones(this, this.player);
117120

118121
// --- 事件 ---
119122
this.setupEvents();
@@ -205,14 +208,19 @@ export default class GameScene extends Phaser.Scene {
205208
// 1. 导演层:决定游戏所处阶段 (切换状态、刷怪开关、物理环境)
206209
this.phaseManager.update(delta);
207210

211+
208212
// 2. 实体层:玩家逻辑 (Buff倒计时、物理运动、输入)
209213
this.player.update(time, delta);
214+
if (this.inputZones) {
215+
this.inputZones.update();
216+
}
210217
this.spawnManager.update(this.worldWidth); // 简化参数
211218
this.scoreManager.update(this.player.y); // ✅ 更新分数/高度
212219

213220
// 3. 视差滚动
214221
this.cameraManager.update(delta);
215222
this.weatherManager.update(delta);
223+
216224

217225
if (this.inputHintLeft || this.inputHintRight) {
218226
if (this.scoreManager.getCurrentHeightMeters() >= 300) {

src/scenes/UIScene.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import InfoBar from "../ui/InfoBar";
99
import LifeBar from "../ui/LifeBar";
1010
import ColdnessBar from "../ui/ColdnessBar";
1111
import RenderManager from "../managers/RenderManager";
12-
import InputZones from "../ui/InputZones";
12+
// import InputZones from "../ui/InputZones";
1313

1414
export default class UIScene extends Phaser.Scene {
1515
private renderManager!: RenderManager;
@@ -23,7 +23,7 @@ export default class UIScene extends Phaser.Scene {
2323
private gauge!: SciFiGauge;
2424

2525
private coldnessBar!: ColdnessBar;
26-
private inputZones!: InputZones;
26+
// private inputZones!: InputZones;
2727

2828
constructor() {
2929
super(SceneKeys.UI);
@@ -53,7 +53,7 @@ export default class UIScene extends Phaser.Scene {
5353
// 2. 传递给 ColdnessBar
5454
this.coldnessBar = new ColdnessBar(this, 50, 400, this.renderManager);
5555
this.coldnessBar.setColdness(0);
56-
this.inputZones = new InputZones(this);
56+
// this.inputZones = new InputZones(this);
5757
// new InputZones(this);
5858

5959

@@ -156,8 +156,8 @@ export default class UIScene extends Phaser.Scene {
156156
if (this.coldnessBar) {
157157
this.coldnessBar.update(time, delta);
158158
}
159-
if (this.inputZones) {
160-
this.inputZones.update();
161-
}
159+
// if (this.inputZones) {
160+
// this.inputZones.update();
161+
// }
162162
}
163163
}

src/ui/InputZones.ts

Lines changed: 63 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,107 @@
11
import Phaser from 'phaser';
22
import { EVENTS, gameEvents } from '../config/Events';
33

4+
// 定义一个简单的接口,只需要对象有 x 坐标即可
5+
// 这样不需要导入具体的 Player 类,避免循环依赖
6+
export interface IControlTarget {
7+
x: number;
8+
}
9+
410
export default class InputZones {
511
private scene: Phaser.Scene;
6-
private leftDown = false;
7-
private rightDown = false;
12+
private target: IControlTarget; // 存储风筝/玩家的引用
13+
14+
private isDown: boolean = false; // 是否正在按压
815
private cursors?: Phaser.Types.Input.Keyboard.CursorKeys;
916
private lastDir = 0;
10-
private leftZone: Phaser.GameObjects.Zone;
11-
private rightZone: Phaser.GameObjects.Zone;
17+
private inputZone: Phaser.GameObjects.Zone;
1218

13-
constructor(scene: Phaser.Scene) {
19+
// 灵敏度死区:防止手指正好按在风筝上时左右鬼畜抖动
20+
private readonly DEAD_ZONE = 10;
21+
22+
/**
23+
* @param scene 场景
24+
* @param target 被控制的对象(必须包含 x 属性),通常传入 this.player
25+
*/
26+
constructor(scene: Phaser.Scene, target: IControlTarget) {
1427
this.scene = scene;
28+
this.target = target;
1529
const { width, height } = scene.scale;
16-
const halfWidth = width / 2;
17-
18-
const leftDebug = scene.add.rectangle(halfWidth / 2, height / 2, halfWidth, height, 0x00ff00, 0.0);
19-
const rightDebug = scene.add.rectangle(halfWidth + halfWidth / 2, height / 2, halfWidth, height, 0xff0000, 0.0);
20-
leftDebug.setScrollFactor(0).setDepth(-1000);
21-
rightDebug.setScrollFactor(0).setDepth(-1000);
2230

23-
this.leftZone = scene.add.zone(halfWidth / 2, height / 2, halfWidth, height);
24-
this.rightZone = scene.add.zone(halfWidth + halfWidth / 2, height / 2, halfWidth, height);
25-
this.leftZone.setScrollFactor(0).setDepth(-999);
26-
this.rightZone.setScrollFactor(0).setDepth(-999);
31+
// 1. 创建全屏触控区
32+
// 深度设为极低,确保作为背景层接收输入,不阻挡 UI 按钮
33+
this.inputZone = scene.add.zone(width / 2, height / 2, width, height);
34+
this.inputZone.setScrollFactor(0).setDepth(-999);
35+
this.inputZone.setInteractive();
2736

28-
this.leftZone.setInteractive();
29-
this.rightZone.setInteractive();
30-
31-
this.leftZone.on('pointerdown', () => {
32-
this.leftDown = true;
33-
this.emitDirection();
34-
});
35-
this.leftZone.on('pointerup', () => {
36-
this.leftDown = false;
37-
this.emitDirection();
38-
});
39-
this.leftZone.on('pointerout', () => {
40-
this.leftDown = false;
41-
this.emitDirection();
42-
});
43-
this.leftZone.on('pointerupoutside', () => {
44-
this.leftDown = false;
37+
// 2. 绑定事件
38+
// 按下时标记状态,并立即触发一次方向检测
39+
this.inputZone.on('pointerdown', () => {
40+
this.isDown = true;
4541
this.emitDirection();
4642
});
4743

48-
this.rightZone.on('pointerdown', () => {
49-
this.rightDown = true;
50-
this.emitDirection();
51-
});
52-
this.rightZone.on('pointerup', () => {
53-
this.rightDown = false;
54-
this.emitDirection();
55-
});
56-
this.rightZone.on('pointerout', () => {
57-
this.rightDown = false;
58-
this.emitDirection();
59-
});
60-
this.rightZone.on('pointerupoutside', () => {
61-
this.rightDown = false;
62-
this.emitDirection();
63-
});
44+
// 各种松开的情况
45+
this.inputZone.on('pointerup', this.handleUp, this);
46+
this.inputZone.on('pointerupoutside', this.handleUp, this);
47+
48+
// 全局松开作为保险
49+
scene.input.on('pointerup', this.handleUp, this);
6450

51+
// 3. 键盘备用 (保持原有键盘逻辑)
6552
this.cursors = scene.input.keyboard?.createCursorKeys();
66-
67-
scene.input.on('pointerup', this.handleGlobalPointerUp, this);
6853
}
6954

70-
private handleGlobalPointerUp() {
71-
if (!this.leftDown && !this.rightDown) return;
72-
this.leftDown = false;
73-
this.rightDown = false;
55+
private handleUp() {
56+
if (!this.isDown) return;
57+
this.isDown = false;
7458
this.emitDirection();
7559
}
7660

7761
private emitDirection() {
7862
const dir = this.getDirection();
63+
// 只有方向改变时才发送事件,优化性能
7964
if (dir === this.lastDir) return;
8065
this.lastDir = dir;
8166
gameEvents.emit(EVENTS.INPUT_DIR, dir);
8267
}
8368

8469
public update() {
85-
if (!this.cursors) return;
70+
// 每一帧都检测,确保如果风筝飞过了手指位置,方向会实时反转
8671
const dir = this.getDirection();
8772
if (dir === this.lastDir) return;
8873
this.lastDir = dir;
8974
gameEvents.emit(EVENTS.INPUT_DIR, dir);
9075
}
9176

9277
private getDirection(): number {
93-
if (this.leftDown) return -1;
94-
if (this.rightDown) return 1;
78+
// A. 优先检测触摸/鼠标
79+
if (this.isDown) {
80+
const pointer = this.scene.input.activePointer;
81+
// 使用 worldX 以兼容摄像机移动
82+
const targetX = pointer.worldX;
83+
const currentX = this.target.x;
84+
85+
const diff = targetX - currentX;
86+
87+
// 如果距离非常近(死区内),则不移动,防止抖动
88+
if (Math.abs(diff) < this.DEAD_ZONE) {
89+
return 0;
90+
}
91+
92+
// 返回 1 (向右) 或 -1 (向左)
93+
return Math.sign(diff);
94+
}
95+
96+
// B. 如果没有触摸,检测键盘 (作为备用/PC端控制)
9597
if (this.cursors?.left?.isDown) return -1;
9698
if (this.cursors?.right?.isDown) return 1;
99+
97100
return 0;
98101
}
99102

100103
destroy() {
101-
this.scene.input.off('pointerup', this.handleGlobalPointerUp, this);
102-
this.leftZone.destroy();
103-
this.rightZone.destroy();
104+
this.scene.input.off('pointerup', this.handleUp, this);
105+
this.inputZone.destroy();
104106
}
105-
}
107+
}

0 commit comments

Comments
 (0)