Skip to content

Commit

Permalink
added basic simon example
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Westover <[email protected]>
  • Loading branch information
scottwestover committed Jan 14, 2024
1 parent e66d681 commit 9aacf2b
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 5 deletions.
2 changes: 1 addition & 1 deletion games/simon/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"cSpell.words": [
"devshareacademy",
Expand Down
13 changes: 13 additions & 0 deletions games/simon/project-task.todo
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
☐ project setup
☐ create buttons
☐ add hover events with alpha
☐ core simon logic
☐ generate a random element in the sequence
☐ method to handle player input
☐ track player input until sequence match, or mismatch
☐ reset game
☐ connect simon to core scene
☐ add simple state for tracking game state
☐ play a sequence
☐ change game alpha and play sound
☐ wait for player input
74 changes: 70 additions & 4 deletions games/simon/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Phaser from 'phaser';
import Simon from './simon';
import { sleep } from './utils';

const ASSET_KEYS = {
SOUND1: 'SOUND1',
Expand All @@ -7,15 +9,28 @@ const ASSET_KEYS = {
SOUND4: 'SOUND4',
} as const;

type GameState = keyof typeof GAME_STATE;

const GAME_STATE = {
INITIAL: 'INITIAL',
PLAYING_PATTERN: 'PLAYING_PATTERN',
WAITING_FOR_INPUT: 'WAITING_FOR_INPUT',
DONE: 'DONE',
} as const;

class Game extends Phaser.Scene {
#gameState!: GameState;
#simonGame!: Simon;
#buttons!: Phaser.GameObjects.Rectangle[];

constructor() {
super({ key: 'Game' });
}

public init() {
this.#gameState = GAME_STATE.INITIAL;
this.#buttons = [];
this.#simonGame = new Simon();
}

public preload(): void {
Expand All @@ -32,6 +47,11 @@ class Game extends Phaser.Scene {
const yellowButton = this.#createButton(20, 230, 0xe6e600, 0xffff33, 2, ASSET_KEYS.SOUND3);
const blueButton = this.#createButton(230, 230, 0x0066cc, 0x1589ff, 3, ASSET_KEYS.SOUND4);
this.#buttons = [redButton, greenButton, yellowButton, blueButton];

// play sequence for player to remember and transition to wait for player input
this.#playSequence().catch(() => {
// do nothing
});
}

#createButton(
Expand All @@ -51,18 +71,64 @@ class Game extends Phaser.Scene {

// add event listener for pointer over event (mouse hovers over element), when event fires update color and fill
button.on(Phaser.Input.Events.POINTER_OVER as string, () => {
button.fillColor = hoverColor;
button.setAlpha(1);
if (this.#gameState === GAME_STATE.WAITING_FOR_INPUT) {
button.fillColor = hoverColor;
button.setAlpha(1);
}
});

// add event listener for pointer out event (mouse was hovering over element and then leaves), when event fires update color and fill
button.on(Phaser.Input.Events.POINTER_OUT as string, () => {
button.fillColor = color;
button.setAlpha(0.4);
if (this.#gameState === GAME_STATE.WAITING_FOR_INPUT) {
button.fillColor = color;
button.setAlpha(0.4);
}
});

// add event listener for click events, when event fires update the player moves in the simon game logic
button.on(Phaser.Input.Events.POINTER_DOWN as string, () => {
if (this.#gameState === GAME_STATE.WAITING_FOR_INPUT) {
this.sound.play(audioAssetKey);
this.#simonGame.checkPlayerMove(button.data.values.id as number);

button.fillColor = color;
button.setAlpha(0.4);

// check to see if game is over and go to DONE state
if (this.#simonGame.isGameOver) {
this.#gameState = GAME_STATE.DONE;
console.log('Game is over');
return;
}

// check if the player sequence is complete, if so go to the next round
if (this.#simonGame.isPlayerSequenceComplete) {
this.#gameState = GAME_STATE.PLAYING_PATTERN;
this.#simonGame.generateNextSequenceElement();
this.#playSequence().catch(() => {
// do nothing
});
}
}
});
return button;
}

async #playSequence(): Promise<void> {
await sleep(1000);
const currentSequence = this.#simonGame.sequence;
for (const num of currentSequence) {
this.#buttons[num].fillColor = this.#buttons[num].data.values.hoverColor as number;
this.#buttons[num].setAlpha(1);
this.sound.play(this.#buttons[num].data.values.audioAssetKey as string);
await sleep(1000);
this.#buttons[num].fillColor = this.#buttons[num].data.values.color as number;
this.#buttons[num].setAlpha(0.4);
await sleep(400);
}

this.#gameState = GAME_STATE.WAITING_FOR_INPUT;
}
}

const gameConfig: Phaser.Types.Core.GameConfig = {
Expand Down
3 changes: 3 additions & 0 deletions games/simon/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function sleep(milliseconds: number) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}

0 comments on commit 9aacf2b

Please sign in to comment.