Skip to content

Commit

Permalink
chore: add clock in game-machine
Browse files Browse the repository at this point in the history
  • Loading branch information
neolectron committed Jul 25, 2023
1 parent 2bba050 commit 49810e1
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 5 deletions.
80 changes: 76 additions & 4 deletions src/machines/game.machine.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { type ActorRefFrom, assign, createMachine, spawn } from 'xstate';
import { type ActorRefFrom, assign, createMachine, spawn, send } from 'xstate';
import { personMachine } from './person.machine';
import { generateUUID } from 'three/src/math/MathUtils';
import { MathUtils } from 'three';

const METERS_CONFIG = {
clock: {
initialValue: 0,
incrementValue: 1,
maxValue: 100,
clamp: (v: number) => MathUtils.clamp(v, 0, METERS_CONFIG.clock.maxValue),
},
};

export const gameMachine = createMachine(
{
/** @xstate-layout N4IgpgJg5mDOIC5QHECGBbMBiA9gOwEEIIAFMAJ1nwG0AGAXUVAAcdYBLAF3fyZAA9EAJgBsADgB0tAMwBGIQFZZtcQHYALLNnqANCACeiaQE5VE2UtVjjY9VbHSRAXyd60mXHgBKYdDgBuYGSUNAx8rBzcvEgCwupSIrRCxtIKiUJC0qo2eoYIJmYWstlW0kJiIsbGLm4Y2Pg+foEAMqiwnMFUeHSMMRFcPHh8ggjqxvHaKurSco5jDrmIALTyshJK6mJimWIKe5mqNSDu2Jzk7FAw5CcA8oHkPeFsA9GgI4rxQrJiqgr2qbRVKlFggVgopL8tlUHLRYQpqq5jnUJHgcJwAMqcVDkTiQLBnC5XTHYziPPrPKJDGIjdTgpLyZLGBSw4wiCwiEHMiTqRSVdTTVTJBQ8o4nCTMAA2qH07DwUHx50uFBIqAArrAwGSWBTBsNEOpaBJjLQDXYhLSLTyQUIZOs9hZpICfntpGJRcjJdLZfL+O1ULiJKgAGa48gACmZtAAlFgxZ6ZXKtSB+pS9aDlCIJCJszncznjCDtEIs3nS9n3ZhxWqNRAFYSKMScUmU7rqcJbbQ0vJjcYMmyUtbbXslApHVZfsKXIjURA4HwTk9Iq23ssLPEy6WCwZV9n1pDrDZHbDnIixaiMVicZBFy8qSuEFzNlVsq7HGJOwoQWCIQooYfYZ2FQVmA4pSgmUA3qmbYPoUqgaEC5QGr+qgqIWmTctmZQaLsv4GtIwFVuq17kkuryxDB5hweoIgKIygLmp+24IOUxZCChuwiAanG2OoBFBrK7CwAAFsR2qkXe5HlJmuwpJU2Y2L8JqcoaPJ-EkPIZGIxRCFOThAA */
id: 'Game',
description:
'The game machine is the root machine of the game, it handles the game state.',
context: {
persons: [],
clock: METERS_CONFIG.clock.initialValue,
},
on: {
onAddPerson: {
Expand All @@ -19,15 +31,58 @@ export const gameMachine = createMachine(
onRemoveLastPerson: {
actions: ['removeLastPerson'],
},
triggerGameOver: {
target: 'finished',
},
},
initial: 'notStarted',
states: {
notStarted: {
on: {
triggerStart: {
target: 'playing',
},
},
},
playing: {
after: {
500: {
actions: 'tick',
target: 'playing',
},
},
on: {
triggerPause: {
target: 'paused',
},
triggerEndNight: {
actions: 'endNight',
target: 'paused',
},
},
},
paused: {
on: {
triggerStart: {
target: 'playing',
},
},
},
finished: {},
},
schema: {
context: {} as {
persons: ActorRefFrom<typeof personMachine>[];
clock: number;
},
events: {} as
| { type: 'onAddPerson' }
| { type: 'onRemovePerson'; id: string }
| { type: 'onRemoveLastPerson' },
| { type: 'onRemoveLastPerson' }
| { type: 'triggerStart' }
| { type: 'triggerPause' }
| { type: 'triggerEndNight' }
| { type: 'triggerGameOver' },
},
predictableActionArguments: true,
preserveActionOrder: true,
Expand All @@ -38,7 +93,10 @@ export const gameMachine = createMachine(
addPerson: assign((context) => {
return {
...context,
persons: [...context.persons, spawn(personMachine, generateUUID())],
persons: [
...context.persons,
spawn(personMachine, MathUtils.generateUUID()),
],
};
}),
removePerson: assign((context, event) => {
Expand All @@ -55,6 +113,20 @@ export const gameMachine = createMachine(
persons: [...context.persons.slice(0, -1)],
};
}),
tick: assign((context) => {
const clock = context.clock + METERS_CONFIG.clock.incrementValue;
if (clock >= METERS_CONFIG.clock.maxValue) send('triggerEndNight');
return {
...context,
clock: METERS_CONFIG.clock.clamp(clock),
};
}),
endNight: assign((context) => {
return {
...context,
clock: METERS_CONFIG.clock.initialValue,
};
}),
},
},
);
7 changes: 6 additions & 1 deletion src/machines/game.machine.typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
export interface Typegen0 {
'@@xstate/typegen': true;
internalEvents: {
'xstate.after(500)#Game.playing': {
type: 'xstate.after(500)#Game.playing';
};
'xstate.init': { type: 'xstate.init' };
};
invokeSrcNameMap: {};
Expand All @@ -14,12 +17,14 @@ export interface Typegen0 {
};
eventsCausingActions: {
addPerson: 'onAddPerson';
endNight: 'triggerEndNight';
removeLastPerson: 'onRemoveLastPerson';
removePerson: 'onRemovePerson';
tick: 'xstate.after(500)#Game.playing';
};
eventsCausingDelays: {};
eventsCausingGuards: {};
eventsCausingServices: {};
matchesStates: undefined;
matchesStates: 'finished' | 'notStarted' | 'paused' | 'playing';
tags: never;
}

0 comments on commit 49810e1

Please sign in to comment.