import Phaser from 'phaser'; import { Ship as ShipType } from '@spacerace/shared'; import { FONTS } from '@spacerace/shared'; export class ShipSprite extends Phaser.GameObjects.Container { private shipData: ShipType; private label: Phaser.GameObjects.Text; private glow: Phaser.GameObjects.Arc; private body: Phaser.GameObjects.Sprite; constructor( scene: Phaser.Scene, x: number, y: number, ship: ShipType, color: number, ) { super(scene, x, y); this.shipData = ship; const angles: Record = { N: 0, E: 90, S: 180, W: 270 }; const baseAngle = angles[ship.direction] || 0; // Glow halo behind the ship (uses player's color) this.glow = scene.add.circle(0, 0, 28, color, 0.35); this.glow.setBlendMode(Phaser.BlendModes.ADD); this.glow.setDepth(-1); // Ship body — uses the procedurally generated 'ship' texture this.body = scene.add.sprite(0, 0, 'ship'); // Recolor the cyan body to the player's color via tint (preserves the white outline) this.body.setTint(color); this.add([this.glow, this.body]); // Player name label in a pill below const name = ship.playerName || ship.playerId.substring(0, 6); const labelBg = scene.add.rectangle(0, 30, Math.max(48, name.length * 7 + 14), 18, 0x000000, 0.7); labelBg.setStrokeStyle(1, color, 0.9); this.label = scene.add.text(0, 30, name, { fontFamily: FONTS.body, fontSize: '12px', color: '#ffffff', fontStyle: 'bold', }).setOrigin(0.5); this.add([labelBg, this.label]); this.setAngle(baseAngle); // Gentle pulse on the halo scene.tweens.add({ targets: this.glow, scaleX: { from: 0.85, to: 1.15 }, scaleY: { from: 0.85, to: 1.15 }, alpha: { from: 0.25, to: 0.5 }, duration: 1400, yoyo: true, repeat: -1, }); scene.add.existing(this); this.setDepth(10); } updateState(ship: ShipType): void { this.shipData = ship; if (!ship.alive) { this.setAlpha(0.3); } } }