From d55bbf3309d6615595855b7f758da5456d454016 Mon Sep 17 00:00:00 2001 From: Admin Date: Fri, 18 Sep 2026 05:28:24 +0000 Subject: [PATCH] Use analog helm and independent broadsides --- src/game-v4.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/game-v4.js b/src/game-v4.js index 1c29f85..f8e55f5 100644 --- a/src/game-v4.js +++ b/src/game-v4.js @@ -42,7 +42,8 @@ class GameScene extends Phaser.Scene { this.playerSpeed = 0; this.playerHull = PLAYER_MAX_HULL; this.gameState = 'playing'; - this.lastPlayerShot = 0; + this.lastPlayerShot = { port: 0, starboard: 0 }; + this.helmVector = { x: 0, y: 0 }; this.pendingPlayerHits = []; this.lastDiagnosticsAt = -Infinity; this.wave = 1; @@ -113,6 +114,11 @@ class GameScene extends Phaser.Scene { }); this.cursors = this.input.keyboard.createCursorKeys(); + this.handleHelmVector = (event) => { + this.helmVector.x = clamp(Number(event.detail?.x) || 0, -1, 1); + this.helmVector.y = clamp(Number(event.detail?.y) || 0, -1, 1); + }; + window.addEventListener('airship:helm-vector', this.handleHelmVector); this.keys = this.input.keyboard.addKeys({ firePort: Phaser.Input.Keyboard.KeyCodes.Q, fireStarboard: Phaser.Input.Keyboard.KeyCodes.E, @@ -130,6 +136,7 @@ class GameScene extends Phaser.Scene { this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => { this.scale.off('resize', this.layoutHud, this); registerDebugSnapshot(null); + window.removeEventListener('airship:helm-vector', this.handleHelmVector); airshipLog('scene:shutdown', { gameState: this.gameState, hull: this.playerHull, @@ -392,20 +399,26 @@ class GameScene extends Phaser.Scene { updatePlayer(dt, deltaMs) { if (!this.player?.body) return; - if (this.cursors.up.isDown) this.playerSpeed += PLAYER_ACCELERATION * dt; - if (this.cursors.down.isDown) this.playerSpeed -= PLAYER_BRAKE * dt; + const helmX = Math.abs(this.helmVector.x) > 0.08 ? this.helmVector.x : 0; + const helmY = Math.abs(this.helmVector.y) > 0.08 ? this.helmVector.y : 0; + const throttleForward = this.cursors.up.isDown ? 1 : Math.max(0, -helmY); + const throttleReverse = this.cursors.down.isDown ? 1 : Math.max(0, helmY); + + if (throttleForward > 0) this.playerSpeed += PLAYER_ACCELERATION * throttleForward * dt; + if (throttleReverse > 0) this.playerSpeed -= PLAYER_BRAKE * throttleReverse * dt; if (this.keys.stop.isDown) this.playerSpeed *= Math.pow(0.025, dt); - if (!this.cursors.up.isDown && !this.cursors.down.isDown && !this.keys.stop.isDown) { + if (throttleForward === 0 && throttleReverse === 0 && !this.keys.stop.isDown) { this.playerSpeed *= Math.pow(0.985, deltaMs / 16.667); } this.playerSpeed = clamp(this.playerSpeed, PLAYER_REVERSE_SPEED, PLAYER_MAX_SPEED); const turnStrength = clamp(Math.abs(this.playerSpeed) / 100, 0.28, 1); const directionSign = this.playerSpeed < 0 ? -1 : 1; + const keyboardTurn = (this.cursors.right.isDown ? 1 : 0) - (this.cursors.left.isDown ? 1 : 0); + const turnInput = keyboardTurn || helmX; - if (this.cursors.left.isDown) this.player.angle -= PLAYER_TURN_RATE * turnStrength * directionSign * dt; - if (this.cursors.right.isDown) this.player.angle += PLAYER_TURN_RATE * turnStrength * directionSign * dt; + this.player.angle += PLAYER_TURN_RATE * turnStrength * directionSign * turnInput * dt; const h = headingRad(this.player); this.player.setVelocity(Math.cos(h) * this.playerSpeed, Math.sin(h) * this.playerSpeed); @@ -449,9 +462,10 @@ class GameScene extends Phaser.Scene { } playerBroadside(side) { - if (this.time.now - this.lastPlayerShot < 850) return; + const broadside = side < 0 ? 'port' : 'starboard'; + if (this.time.now - this.lastPlayerShot[broadside] < 850) return; this.fireBroadside(this.player, side, this.playerShots, 'player-shot', 16, 1.0); - this.lastPlayerShot = this.time.now; + this.lastPlayerShot[broadside] = this.time.now; } fireBroadside(ship, side, group, texture, damage, velocityScale) {