initial
This commit is contained in:
161
src/stories/SlotMultipliersSystem.stories.ts
Normal file
161
src/stories/SlotMultipliersSystem.stories.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
import { Assets, Ticker } from 'pixi.js';
|
||||
import { Meta, PixiStory, StoryFn } from '@pixi/storybook-renderer';
|
||||
import HoldAndWinMachine from 'src/slotMachines/HoldAndWinMachine';
|
||||
import { SlotMachineConfig } from 'src/types/SlotMachineConfig';
|
||||
import { centerView } from 'src/stories/utils/resize';
|
||||
import MachineContainer from 'src/stories/utils/MachineContainer';
|
||||
import { createScreenInputMap } from 'src/stories/utils/createScreenInputMap';
|
||||
import SlotMultipliersSystem from 'src/systems/SlotMultipliersSystem';
|
||||
import SlotMultiplierEntity from 'src/entities/SlotMultiplierEntity';
|
||||
import { STATES } from 'src/states/BasicStateMachine';
|
||||
import {argTypes, getDefaultArgs} from "src/stories/utils/argTypes";
|
||||
|
||||
const args = {
|
||||
accelerationTime: 1,
|
||||
backCoef: 1.1,
|
||||
maxSpeed: 15,
|
||||
reelStartDelay: 0.2,
|
||||
reelStopDelay: 0.5,
|
||||
slotStopDelay: 0,
|
||||
spinningDuration: 2,
|
||||
blur: false,
|
||||
bounce: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates argTypes with fractional range steps for finer Hold & Win tuning.
|
||||
*/
|
||||
const createHoldAndWinArgTypes = (initialArgs: typeof args): ReturnType<typeof argTypes> => {
|
||||
const baseArgTypes = argTypes(initialArgs);
|
||||
|
||||
Object.keys(initialArgs).forEach((key) => {
|
||||
|
||||
const descriptor = baseArgTypes[key];
|
||||
const control = descriptor?.control;
|
||||
|
||||
if (!control || control.type !== 'range') return;
|
||||
|
||||
baseArgTypes[key] = {
|
||||
...descriptor,
|
||||
control: {
|
||||
...control,
|
||||
step: control.step && control.step < 1 ? control.step : 0.1,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return baseArgTypes;
|
||||
};
|
||||
|
||||
const meta: Meta<typeof SlotMultipliersSystem> = {
|
||||
title: 'systems/SlotMultipliersSystem',
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: 'Displays Spine-based multiplier overlays for every slot based on the slotMultipliers map.',
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: createHoldAndWinArgTypes(args),
|
||||
args: getDefaultArgs(args),
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
|
||||
/**
|
||||
* Updates the multiplier map with random positive values and zeroed blanks.
|
||||
*/
|
||||
function randomiseMultipliers(machine: HoldAndWinMachine): void
|
||||
{
|
||||
const total = machine.config.reels * machine.config.slots;
|
||||
machine.maps.slotMultipliers = Array.from({ length: total }, () =>
|
||||
(Math.random() > 0.6 ? Math.ceil(Math.random() * 10) : 0));
|
||||
}
|
||||
|
||||
export const HoldAndWinMultipliers: StoryFn = (_params, context) => new PixiStory({
|
||||
context,
|
||||
init: async (view) => {
|
||||
Assets.reset();
|
||||
await Assets.init({ manifest: 'hold-and-win/manifest.json' });
|
||||
await Assets.loadBundle('configs');
|
||||
await Assets.loadBundle('symbols');
|
||||
await Assets.loadBundle('addons');
|
||||
|
||||
const config: SlotMachineConfig = Assets.get('slot_machine_config');
|
||||
const machine = new HoldAndWinMachine(config);
|
||||
const container = new MachineContainer(machine);
|
||||
container.scale.set(1);
|
||||
view.addChild(container);
|
||||
|
||||
context.machine = machine;
|
||||
context.prevSpinState = machine.systems.spin.state;
|
||||
|
||||
machine.inputs.initMap = createScreenInputMap(config);
|
||||
machine.inputs.screenMap = machine.inputs.initMap;
|
||||
|
||||
const slotMultipliersSystem = new SlotMultipliersSystem(machine);
|
||||
slotMultipliersSystem.setSettings({ entityClass: SlotMultiplierEntity });
|
||||
machine.systems.slotMultipliers = slotMultipliersSystem;
|
||||
// Apply story args to spin system and trigger spin
|
||||
machine.systems.spin.setSettings(_params as any);
|
||||
|
||||
const idleState = machine.stateMachine.states[STATES.IDLE];
|
||||
if (idleState && !idleState.systems.includes('slotMultipliers'))
|
||||
{
|
||||
idleState.systems.push('slotMultipliers');
|
||||
}
|
||||
|
||||
const spinningState = machine.stateMachine.states[STATES.SPINNING];
|
||||
if (spinningState && !spinningState.systems.includes('slotMultipliers'))
|
||||
{
|
||||
spinningState.systems.push('slotMultipliers');
|
||||
}
|
||||
|
||||
randomiseMultipliers(machine);
|
||||
machine.inputs.spin = true;
|
||||
|
||||
context.spinDelayMs = 0;
|
||||
|
||||
centerView(view);
|
||||
},
|
||||
resize: centerView,
|
||||
update: () => {
|
||||
const machine: HoldAndWinMachine | undefined = context.machine;
|
||||
if (!machine) return;
|
||||
|
||||
const dt = Ticker.shared.deltaMS;
|
||||
machine.update(dt);
|
||||
|
||||
const spinSystem = machine.systems.spin;
|
||||
const prevState = context.prevSpinState ?? spinSystem.state;
|
||||
|
||||
if (prevState !== spinSystem.state)
|
||||
{
|
||||
if (spinSystem.state === 'starting')
|
||||
{
|
||||
machine.inputs.spin = false;
|
||||
}
|
||||
|
||||
if (spinSystem.state === 'stopped')
|
||||
{
|
||||
context.spinDelayMs = 500;
|
||||
}
|
||||
|
||||
context.prevSpinState = spinSystem.state;
|
||||
}
|
||||
|
||||
if ((context.spinDelayMs ?? 0) > 0)
|
||||
{
|
||||
context.spinDelayMs -= dt;
|
||||
|
||||
if (context.spinDelayMs <= 0)
|
||||
{
|
||||
randomiseMultipliers(machine);
|
||||
machine.inputs.spin = true;
|
||||
context.spinDelayMs = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user