Decouple UI controls from ocean camera movement
- Set scrollFactor(0) on all UI elements to fix them to screen - HUD, crosshair, harpoons, buttons, and messages now ignore camera sway - Only whale and ocean background move with camera - Updated collision detection to convert whale world position to screen space - Harpoons shoot straight relative to screen, not world - Creates stable aiming interface while ocean/whale sway dynamically - Much better gameplay feel with separated control and world layers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -153,6 +153,7 @@ export default class HuntingScene extends Phaser.Scene {
|
||||
|
||||
this.crosshair = this.add.sprite(400, 300, 'crosshair');
|
||||
this.crosshair.setDepth(100);
|
||||
this.crosshair.setScrollFactor(0); // Fixed to screen, ignores camera movement
|
||||
}
|
||||
|
||||
createOceanWaves() {
|
||||
@@ -175,31 +176,36 @@ export default class HuntingScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
createHUD() {
|
||||
// HUD background
|
||||
// HUD background (fixed to screen, ignores camera movement)
|
||||
const hudBg = this.add.rectangle(400, 30, 780, 50, 0x000000, 0.7);
|
||||
hudBg.setStrokeStyle(2, 0xffffff);
|
||||
hudBg.setScrollFactor(0);
|
||||
|
||||
// Stats
|
||||
// Stats (fixed to screen)
|
||||
this.statsText = this.add.text(20, 15, '', {
|
||||
fontSize: '16px',
|
||||
fill: '#fff'
|
||||
});
|
||||
this.statsText.setScrollFactor(0);
|
||||
|
||||
// Control mode indicator
|
||||
// Control mode indicator (fixed to screen)
|
||||
this.controlModeText = this.add.text(400, 15, 'Controls: MOUSE (TAB to switch)', {
|
||||
fontSize: '16px',
|
||||
fill: '#ffff00'
|
||||
}).setOrigin(0.5, 0);
|
||||
this.controlModeText.setScrollFactor(0);
|
||||
|
||||
// Return button
|
||||
// Return button (fixed to screen)
|
||||
const returnBtn = this.add.rectangle(750, 30, 80, 35, 0x8B0000);
|
||||
returnBtn.setInteractive({ useHandCursor: true });
|
||||
returnBtn.setStrokeStyle(2, 0xffffff);
|
||||
returnBtn.setScrollFactor(0);
|
||||
|
||||
this.add.text(750, 30, 'RETURN', {
|
||||
const returnText = this.add.text(750, 30, 'RETURN', {
|
||||
fontSize: '14px',
|
||||
fill: '#fff'
|
||||
}).setOrigin(0.5);
|
||||
returnText.setScrollFactor(0);
|
||||
|
||||
returnBtn.on('pointerdown', () => {
|
||||
this.returnToMap();
|
||||
@@ -223,6 +229,7 @@ export default class HuntingScene extends Phaser.Scene {
|
||||
backgroundColor: '#000000',
|
||||
padding: { x: 10, y: 5 }
|
||||
}).setOrigin(0.5);
|
||||
this.messageText.setScrollFactor(0); // Fixed to screen
|
||||
}
|
||||
|
||||
showMessage(text) {
|
||||
@@ -312,15 +319,17 @@ export default class HuntingScene extends Phaser.Scene {
|
||||
}
|
||||
|
||||
shootHarpoon() {
|
||||
// Create harpoon at crosshair position
|
||||
// Create harpoon at crosshair position (fixed to screen)
|
||||
const harpoon = this.add.rectangle(this.crosshairX, this.crosshairY, 4, 20, 0x8B4513);
|
||||
harpoon.setData('speed', 8);
|
||||
harpoon.setData('active', true);
|
||||
harpoon.setScrollFactor(0); // Fixed to screen
|
||||
|
||||
this.harpoons.push(harpoon);
|
||||
|
||||
// Sound effect simulation (flash)
|
||||
// Sound effect simulation (flash) - fixed to screen
|
||||
const flash = this.add.circle(this.crosshairX, this.crosshairY, 10, 0xffff00, 0.8);
|
||||
flash.setScrollFactor(0);
|
||||
this.tweens.add({
|
||||
targets: flash,
|
||||
alpha: 0,
|
||||
@@ -363,10 +372,15 @@ export default class HuntingScene extends Phaser.Scene {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Simple collision detection
|
||||
// Collision detection accounting for camera offset
|
||||
// Harpoon is in screen space (scrollFactor 0)
|
||||
// Whale is in world space, so convert to screen space
|
||||
const whaleScreenX = whale.x - this.cameras.main.scrollX;
|
||||
const whaleScreenY = whale.y - this.cameras.main.scrollY;
|
||||
|
||||
const distance = Phaser.Math.Distance.Between(
|
||||
harpoon.x, harpoon.y,
|
||||
whale.x, whale.y
|
||||
whaleScreenX, whaleScreenY
|
||||
);
|
||||
|
||||
if (distance < 40) {
|
||||
@@ -482,8 +496,9 @@ export default class HuntingScene extends Phaser.Scene {
|
||||
// Show success message
|
||||
this.showMessage(`Whale killed! +1 Whale Oil, -2 Fuel (Oil: ${this.inventory.whaleOil}, Fuel: ${this.inventory.fuel})`);
|
||||
|
||||
// Success flash
|
||||
// Success flash (fixed to screen)
|
||||
const flash = this.add.rectangle(400, 300, 800, 600, 0xffffff, 0.3);
|
||||
flash.setScrollFactor(0);
|
||||
this.tweens.add({
|
||||
targets: flash,
|
||||
alpha: 0,
|
||||
|
||||
Reference in New Issue
Block a user