fix: sync multitouch controls and reachable branches

This commit is contained in:
Admin 2026-09-19 05:57:59 +00:00
parent 3bceb60f15
commit 0467a669e7

View File

@ -11,7 +11,8 @@ class ForestScene extends Phaser.Scene {
this.acorns = 0;
this.mushrooms = 0;
this.totalMushrooms = 5;
this.touch = { left: false, right: false, jump: false };
this.touch = { left: false, right: false };
this.touchPointers = { left: new Set(), right: new Set() };
}
create() {
@ -240,9 +241,12 @@ class ForestScene extends Phaser.Scene {
this.add.rectangle(WORLD_WIDTH / 2, GROUND_Y + 2, WORLD_WIDTH, 20, 0x55714a);
const branchPositions = [
[520, 520], [900, 445], [1320, 525], [1680, 415], [2050, 505],
[2470, 430], [2910, 515], [3370, 405], [3800, 500], [4230, 425],
[4680, 520], [5100, 430]
[500, 545], [720, 505], [900, 465],
[1260, 545], [1480, 505], [1680, 465],
[2050, 545], [2260, 505], [2470, 465],
[2900, 545], [3140, 505], [3370, 465],
[3800, 545], [4010, 505], [4230, 465],
[4680, 545], [4890, 505], [5100, 465]
];
branchPositions.forEach(([x, y], index) => {
@ -431,8 +435,12 @@ class ForestScene extends Phaser.Scene {
this.cursors = this.input.keyboard.createCursorKeys();
this.keys = this.input.keyboard.addKeys('A,D,W,SPACE');
const makeButton = (x, y, label, onDown, onUp) => {
const circle = this.add.circle(x, y, 34, 0x15261e, 0.55)
// Phaser only tracks a limited pointer set by default. Add enough pointers
// for a movement thumb and a separate jump thumb on touch devices.
this.input.addPointer(3);
const makeButton = (x, y, label) => {
const circle = this.add.circle(x, y, 40, 0x15261e, 0.55)
.setScrollFactor(0)
.setDepth(40)
.setStrokeStyle(2, 0xe0eadb, 0.35)
@ -440,30 +448,45 @@ class ForestScene extends Phaser.Scene {
const text = this.add.text(x, y - 2, label, {
fontFamily: 'Arial, sans-serif',
fontSize: '24px',
fontSize: '26px',
color: '#edf4e9'
}).setOrigin(0.5).setScrollFactor(0).setDepth(41);
circle.on('pointerdown', onDown);
circle.on('pointerup', onUp);
circle.on('pointerout', onUp);
return { circle, text };
};
this.leftBtn = makeButton(68, this.scale.height - 70, '‹',
() => { this.touch.left = true; },
() => { this.touch.left = false; }
);
const bindHold = (button, action) => {
button.circle.on('pointerdown', pointer => {
this.touchPointers[action].add(pointer.id);
this.touch[action] = true;
});
};
this.rightBtn = makeButton(146, this.scale.height - 70, '›',
() => { this.touch.right = true; },
() => { this.touch.right = false; }
);
const releasePointer = pointer => {
for (const action of ['left', 'right']) {
this.touchPointers[action].delete(pointer.id);
this.touch[action] = this.touchPointers[action].size > 0;
}
};
this.jumpBtn = makeButton(this.scale.width - 74, this.scale.height - 70, '↑',
() => { this.touch.jump = true; },
() => { this.touch.jump = false; }
);
this.leftBtn = makeButton(68, this.scale.height - 70, '‹');
this.rightBtn = makeButton(156, this.scale.height - 70, '›');
this.jumpBtn = makeButton(this.scale.width - 74, this.scale.height - 70, '↑');
bindHold(this.leftBtn, 'left');
bindHold(this.rightBtn, 'right');
// Jump fires immediately for its own pointer while the movement pointer can
// remain held down at the same time.
this.jumpBtn.circle.on('pointerdown', () => this.tryJump());
this.input.on('pointerup', releasePointer);
this.input.on('pointerupoutside', releasePointer);
this.input.on('gameout', () => {
this.touchPointers.left.clear();
this.touchPointers.right.clear();
this.touch.left = false;
this.touch.right = false;
});
this.input.keyboard.on('keydown-UP', () => this.tryJump());
this.input.keyboard.on('keydown-W', () => this.tryJump());
@ -474,8 +497,8 @@ class ForestScene extends Phaser.Scene {
if (!this.leftBtn) return;
this.leftBtn.circle.setPosition(68, height - 70);
this.leftBtn.text.setPosition(68, height - 72);
this.rightBtn.circle.setPosition(146, height - 70);
this.rightBtn.text.setPosition(146, height - 72);
this.rightBtn.circle.setPosition(156, height - 70);
this.rightBtn.text.setPosition(156, height - 72);
this.jumpBtn.circle.setPosition(width - 74, height - 70);
this.jumpBtn.text.setPosition(width - 74, height - 72);
}
@ -483,7 +506,7 @@ class ForestScene extends Phaser.Scene {
tryJump() {
if (!this.player?.body) return;
if (this.player.body.blocked.down || this.player.body.touching.down) {
this.player.setVelocityY(-470);
this.player.setVelocityY(-520);
this.player.setAngularVelocity(this.player.flipX ? -25 : 25);
this.time.delayedCall(180, () => this.player?.setAngularVelocity(0));
}
@ -562,11 +585,6 @@ class ForestScene extends Phaser.Scene {
this.player.setAccelerationX(0);
}
if (this.touch.jump) {
this.tryJump();
this.touch.jump = false;
}
const grounded = this.player.body.blocked.down || this.player.body.touching.down;
if (grounded) {
this.player.setAngle(0);