84 lines
2.4 KiB
JavaScript
84 lines
2.4 KiB
JavaScript
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; }
|
|
}
|