import { SYMBOLS } from './Symbol.js'; import { Reel } from './Reel.js'; import { shouldWin, pickResults } from '../utils/RNG.js'; const REEL_GAP = 20; const REEL_WIDTH = 200; const REEL_HEIGHT = 330; // 3 * 110 (matches Reel.js SYMBOL_HEIGHT) export class SlotMachine { constructor(scene, centerX, centerY) { this.scene = scene; this.centerX = centerX; this.centerY = centerY; // Draw the machine frame this.framGfx = scene.add.graphics(); this._drawFrame(); // Three reels, side by side const totalWidth = REEL_WIDTH * 3 + REEL_GAP * 2; const startX = centerX - totalWidth / 2; const startY = centerY - REEL_HEIGHT / 2; this.reels = [ new Reel(scene, startX, startY), new Reel(scene, startX + REEL_WIDTH + REEL_GAP, startY), new Reel(scene, startX + (REEL_WIDTH + REEL_GAP) * 2, startY), ]; // Center line indicator const lineGfx = scene.add.graphics(); lineGfx.lineStyle(3, 0xffd700, 0.9); lineGfx.beginPath(); lineGfx.moveTo(startX - 10, centerY); lineGfx.lineTo(startX + totalWidth + 10, centerY); lineGfx.strokePath(); this.lastResults = null; } _drawFrame() { const g = this.framGfx; const cx = this.centerX; const cy = this.centerY; const w = REEL_WIDTH * 3 + REEL_GAP * 2 + 60; const h = REEL_HEIGHT + 60; // Outer frame g.fillStyle(0x2a1040, 1); g.fillRoundedRect(cx - w / 2, cy - h / 2, w, h, 16); g.lineStyle(4, 0xffd700, 1); g.strokeRoundedRect(cx - w / 2, cy - h / 2, w, h, 16); // Inner shadow g.lineStyle(2, 0x8844aa, 0.6); g.strokeRoundedRect(cx - w / 2 + 6, cy - h / 2 + 6, w - 12, h - 12, 12); } // spin(onComplete) — onComplete receives { win, symbols, payout } spin(onComplete) { const win = shouldWin(); const results = pickResults(SYMBOLS, win); this.lastResults = results; const payout = win ? results[0].payout : 0; let doneCount = 0; const totalReels = this.reels.length; const stopDelays = [800, 1300, 1800]; // ms before each reel starts decelerating this.reels.forEach((reel, i) => { reel.spin(results[i], stopDelays[i], () => { doneCount++; if (doneCount === totalReels) { onComplete({ win, symbols: results, payout }); } }); }); } getCenterX() { return this.centerX; } getCenterY() { return this.centerY; } }