Skip to content

Commit

Permalink
Refactor menus
Browse files Browse the repository at this point in the history
  • Loading branch information
jarrettgilliam committed Nov 24, 2024
1 parent c2f3b6b commit 00d817b
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/scripts/controls/canvas-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { CanvasLabel } from './canvas-label.ts';
import { Point } from '../primitives/point.ts';
import { Game } from '../game.ts';

export class CanvasButton extends CanvasLabel {
export class CanvasButton<T> extends CanvasLabel {
public selected: boolean;

constructor(game: Game, text: string, sizeFactor: number, YFactor: number) {
constructor(game: Game, text: string, sizeFactor: number, YFactor: number, public data: T) {
super(game, text, sizeFactor, YFactor)
this.selected = false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/interfaces/save-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface SaveData {
};
}

export const InitialSaveData: SaveData = {
export const InitialState: SaveData = {
score: 0,
difficulty: DEFAULT_DIFFICULTY,
apple: {
Expand Down
11 changes: 8 additions & 3 deletions src/scripts/menus/game-over-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@ import { CanvasLabel } from '../controls/canvas-label.ts';
import { CanvasButton } from '../controls/canvas-button.ts';
import { Game } from '../game.ts';

export class GameOverMenu extends MenuBase {
export class GameOverMenu extends MenuBase<any> {

constructor(game: Game) {
super(game, GameState.StartMenu, () => this.resetButtonIndex(),
super(game,
[
new CanvasLabel(game, "GAME OVER", 2, 7 / 16),
new CanvasLabel(game, () => `DIFFICULTY: ${game.difficulty}`, 0.7, 35 / 64),
new CanvasLabel(game, () => `YOUR SCORE: ${game.score}`, 0.7, 39 / 64)
],
[
new CanvasButton(game, "Start_Over", 0.8, 22 / 32)
new CanvasButton(game, "Start_Over", 0.8, 22 / 32, null)
]);
}

acceptSelected(): GameState {
this.resetButtonIndex()
return GameState.StartMenu;
}
}
46 changes: 24 additions & 22 deletions src/scripts/menus/menu-base.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
import { Drawable } from '../interfaces/drawable.ts';
import { getCode, getValueAsFunction } from '../utils.ts';
import { getCode } from '../utils.ts';
import { CanvasLabel } from '../controls/canvas-label.ts';
import { CanvasButton } from '../controls/canvas-button.ts';
import { Keys } from '../enums/keys.ts';
import { Game } from '../game.ts';
import { GameState } from '../enums/game-state.ts';
import { Point } from '../primitives/point.ts';

export class MenuBase implements Drawable {
export abstract class MenuBase<T> implements Drawable {
protected readonly game: Game;
private readonly nextGameState: () => GameState;
private readonly acceptSelectedCallback: () => void;
private readonly labels: CanvasLabel[];
protected readonly buttons: CanvasButton[];
protected readonly buttons: CanvasButton<T>[];

constructor(game: Game,
nextGameState: GameState | (() => GameState),
acceptSelectedCallback: () => void,
labels: CanvasLabel[],
buttons: CanvasButton[]) {
protected constructor(game: Game,
labels: CanvasLabel[],
buttons: CanvasButton<T>[]) {
this.game = game;
this.nextGameState = getValueAsFunction(nextGameState);
this.acceptSelectedCallback = acceptSelectedCallback;
this.labels = labels;
this.buttons = buttons;
this.resetButtonIndex();
Expand Down Expand Up @@ -63,8 +57,11 @@ export class MenuBase implements Drawable {
}

oninput(e: any) {
this.handleTouchAndMouseInput(e);
this.handleKeyboardInput(e);
}

// handle touch and mouse input
private handleTouchAndMouseInput(e: any) {
let touch: Point | undefined;
let touchstart = false;

Expand All @@ -84,7 +81,7 @@ export class MenuBase implements Drawable {
if (touchstart) {
this.buttonIndex = i;
} else if (this.buttonIndex === i) {
this.acceptSelectedOption();
this.tryAcceptSelected();
}
break;
}
Expand All @@ -93,22 +90,22 @@ export class MenuBase implements Drawable {
this.clearButtonIndex();
}
}
}

// handle keyboard input
private handleKeyboardInput(e: any) {
if (e.type === 'keydown') {
const code = getCode(e);
if (code === Keys.Escape) {
this.clearButtonIndex();
} else if (code === Keys.Enter) {
this.acceptSelectedOption();
this.tryAcceptSelected();
} else {
if (code === Keys.ArrowLeft ||
code === Keys.A ||
code === Keys.ArrowUp ||
code === Keys.W) {
this.buttonIndex--;
}
else if (
} else if (
code === Keys.ArrowRight ||
code === Keys.D ||
code === Keys.ArrowDown ||
Expand All @@ -119,13 +116,18 @@ export class MenuBase implements Drawable {
}
}

acceptSelectedOption() {
if (this.buttonIndex >= 0) {
this.game.gameState = this.nextGameState();
this.acceptSelectedCallback();
tryAcceptSelected() {
if (this.buttonIndex >= 0 && this.buttonIndex < this.buttons.length) {
this.game.gameState = this.acceptSelected(this.buttons[this.buttonIndex].data);
}
}

/**
* Accept the selected button and return the new game state.
* @param buttonData - The data associated with the selected button.
*/
abstract acceptSelected(buttonData: T): GameState;

draw() {
this.labels.forEach(l => l.draw());
this.buttons.forEach(b => b.draw());
Expand Down
15 changes: 8 additions & 7 deletions src/scripts/menus/pause-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@ import { CanvasButton } from '../controls/canvas-button.ts';
import { GameState } from '../enums/game-state.ts';
import { Game } from '../game.ts';

export class PauseMenu extends MenuBase {
export class PauseMenu extends MenuBase<GameState> {

constructor(game: Game) {
super(game, () => this.getNextGameState(), () => this.onUnpause(),
super(game,
[
new CanvasLabel(game, "PAUSED", 2, 7 / 16),
new CanvasLabel(game, () => `DIFFICULTY: ${game.difficulty}`, 0.7, 35 / 64),
new CanvasLabel(game, () => `YOUR SCORE: ${game.score}`, 0.7, 39 / 64)
],
[
new CanvasButton(game, "Resume", 0.8, 22 / 32),
new CanvasButton(game, "Start_Over", 0.8, 22 / 32 + 1 / 12)
new CanvasButton(game, "Resume", 0.8, 22 / 32, GameState.Playing),
new CanvasButton(game, "Start_Over", 0.8, 22 / 32 + 1 / 12, GameState.StartMenu)
]);
}

getNextGameState(): GameState {
return this.buttonIndex === 0 ? GameState.Playing : GameState.StartMenu;
acceptSelected(buttonData: GameState): GameState {
this.unpause();
return buttonData;
}

onUnpause() {
unpause() {
this.game.removeSave();
this.resetButtonIndex();
}
Expand Down
22 changes: 14 additions & 8 deletions src/scripts/menus/start-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,36 @@ import { Difficulty } from '../enums/difficulty.ts';
import { CanvasButton } from '../controls/canvas-button.ts';
import { GameState } from '../enums/game-state.ts';
import { Game } from '../game.ts';
import { InitialSaveData } from '../interfaces/save-data.ts';
import { InitialState, SaveData } from '../interfaces/save-data.ts';

export class StartMenu extends MenuBase {
export class StartMenu extends MenuBase<Difficulty> {

constructor(game: Game) {
const labels = [
new CanvasLabel(game, "SNAKE", 3, 1 / 3),
new CanvasLabel(game, "CHOOSE YOUR DIFFICULTY", 0.6, 13 / 32)
];

const buttons: CanvasButton[] = [];
const buttons: CanvasButton<Difficulty>[] = [];
Object.keys(Difficulty).forEach((key, index) => {
buttons.push(new CanvasButton(game, key, 0.8, 15 / 32 + index / 12));
buttons.push(new CanvasButton(game, key, 0.8, 15 / 32 + index / 12, key as Difficulty));
});

super(game, GameState.Playing, () => this.setupGame(), labels, buttons);
super(game, labels, buttons);
}

get defaultButtonIndex() {
return this.buttons.findIndex(b => b.text() === this.game.difficulty);
}

setupGame() {
this.game.reset(InitialSaveData);
this.game.difficulty = this.buttons[this.buttonIndex].text() as Difficulty;
acceptSelected(buttonData: Difficulty): GameState {
const data: SaveData = {
...InitialState,
difficulty: buttonData
}

this.game.reset(data);

return GameState.Playing;
}
}

0 comments on commit 00d817b

Please sign in to comment.