From 73eba44e5efe479574e97aae5818f46464806d47 Mon Sep 17 00:00:00 2001 From: koneko <67551503+koneko@users.noreply.github.com> Date: Sun, 22 Sep 2024 22:58:08 +0200 Subject: [PATCH] base work on engine, expanded --- public/assets/gui/button_02.png | Bin 0 -> 43336 bytes src/base/Button.ts | 44 +++++++++++++++++++++++ src/base/Game.ts | 55 +++++++++++++++++++++++++++++ src/base/GameObject.ts | 32 +++++++++++++++++ src/classes/GUI.ts | 0 src/classes/Game.ts | 15 -------- src/classes/Grid.ts | 60 -------------------------------- src/classes/Renderer.ts | 5 --- src/classes/Scenes.ts | 31 ----------------- src/classes/Tower.ts | 1 - src/main.ts | 10 ++++-- src/scenes/Base.ts | 12 +++++++ src/scenes/MainMenu.ts | 52 +++++++++++++++++++++++++++ src/scenes/MissionSelectMenu.ts | 47 +++++++++++++++++++++++++ src/scenes/SettingsMenu.ts | 51 +++++++++++++++++++++++++++ 15 files changed, 300 insertions(+), 115 deletions(-) create mode 100755 public/assets/gui/button_02.png create mode 100644 src/base/Button.ts create mode 100644 src/base/Game.ts create mode 100644 src/base/GameObject.ts delete mode 100644 src/classes/GUI.ts delete mode 100644 src/classes/Game.ts delete mode 100644 src/classes/Grid.ts delete mode 100644 src/classes/Renderer.ts delete mode 100644 src/classes/Scenes.ts delete mode 100644 src/classes/Tower.ts create mode 100644 src/scenes/Base.ts create mode 100644 src/scenes/MainMenu.ts create mode 100644 src/scenes/MissionSelectMenu.ts create mode 100644 src/scenes/SettingsMenu.ts diff --git a/public/assets/gui/button_02.png b/public/assets/gui/button_02.png new file mode 100755 index 0000000000000000000000000000000000000000..7ef79b1e4eb49f31766887d7e61b321833da9a2b GIT binary patch literal 43336 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 { + this.events.emit("click"); + }); + } +} diff --git a/src/base/Game.ts b/src/base/Game.ts new file mode 100644 index 0000000..b571856 --- /dev/null +++ b/src/base/Game.ts @@ -0,0 +1,55 @@ +import MainMenu from "../scenes/MainMenu"; +import MissionMenuSelect from "../scenes/MissionSelectMenu"; +import GameObject from "./GameObject"; +import * as PIXI from "pixi.js"; + +export default class Game extends GameObject { + private _currentScene: GameObject | null = null; + + constructor(bounds: PIXI.Rectangle) { + super(bounds); + this.onMainMenu(); + } + + private onMainMenu() { + const mainScene = new MainMenu(this.bounds); + mainScene.events.on("newGame", this.onNewGame); + mainScene.events.on("settings", this.onSettings); + this.setScene(mainScene); + } + + private onNewGame = () => { + console.log("New Game"); + const missionSelectScene = new MissionMenuSelect(this.bounds); + missionSelectScene.events.on("mission", (mission) => { + console.log("Mission selected", mission); + }); + missionSelectScene.events.on("back", () => { + this.onMainMenu(); + }); + this.setScene(missionSelectScene); + }; + + private onSettings = () => { + console.log("Settings"); + }; + + private setScene(scene: GameObject) { + if (this._currentScene) { + this.container.removeChild(this._currentScene.container); + } + this._currentScene = scene; + this.container.addChild(scene.container); + this.drawScene(); + } + + protected triggerBoundsChanged(): void { + this.drawScene(); + } + + private drawScene() { + if (this._currentScene) { + this._currentScene.setBounds(0, 0, this.bounds.width, this.bounds.height); + } + } +} diff --git a/src/base/GameObject.ts b/src/base/GameObject.ts new file mode 100644 index 0000000..12648a5 --- /dev/null +++ b/src/base/GameObject.ts @@ -0,0 +1,32 @@ +import * as PIXI from "pixi.js"; +export default abstract class GameObject { + protected _container: PIXI.Container; + + protected bounds: PIXI.Rectangle; + + private _events: PIXI.EventEmitter = new PIXI.EventEmitter(); + + public getBounds(): PIXI.Rectangle { + return this.bounds; + } + + public setBounds(x: number, y: number, width: number, height: number) { + this.bounds = new PIXI.Rectangle(x, y, width, height); + this.triggerBoundsChanged(); // GameObject implements this. + } + + public get container(): PIXI.Container { + return this._container; + } + + public get events(): PIXI.EventEmitter { + return this._events; + } + + protected abstract triggerBoundsChanged(); + + constructor(bounds: PIXI.Rectangle) { + this.bounds = bounds; + this._container = new PIXI.Container(); + } +} diff --git a/src/classes/GUI.ts b/src/classes/GUI.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/classes/Game.ts b/src/classes/Game.ts deleted file mode 100644 index a962b9c..0000000 --- a/src/classes/Game.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Renderer } from "./Renderer.ts"; -import { BaseScene, SceneType, makeSceneFromType } from "./Scenes.ts"; - -export class Game { - public Renderer: Renderer; - public currentScene: BaseScene; - constructor(sceneType: SceneType) { - this.Renderer = new Renderer(); - this.changeScene(sceneType); - } - changeScene(sceneType): void { - if (this.currentScene != undefined) this.currentScene.destroy(); - this.currentScene = makeSceneFromType(sceneType); - } -} diff --git a/src/classes/Grid.ts b/src/classes/Grid.ts deleted file mode 100644 index 012172b..0000000 --- a/src/classes/Grid.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as PIXI from "pixi.js"; -import { Tower } from "./Tower.ts"; - -export enum CellType { - Path, - NoBuild, - Build, - Undefined, -} - -export class Cell { - public x: number; - public y: number; - public type: CellType; - public tower: Tower; - constructor(x, y, type) { - this.x = x; - this.y = y; - this.type = type; - } -} - -export class Grid { - public rows: number; - public columns: number; - public gridObject: PIXI.Container; - public cells: Array; - constructor(x, y, width, height, rows, columns) { - this.rows = rows; - this.columns = columns; - this.gridObject = new PIXI.Container({ - width: width, - height: height, - x: x, - y: y, - }); - for (let y = 0; y < rows; y++) { - for (let x = 0; x < columns; x++) { - let cell = new Cell(x, y, CellType.Undefined); - this.cells.push(cell); - } - } - } - - getPixelScalingFactor() { - const pixelScaleX = this.gridObject.width / this.columns; - const pixelScaleY = this.gridObject.height / this.rows; - return pixelScaleX < pixelScaleY ? pixelScaleX : pixelScaleY; - } - - gridUnitsToPixels(amount: number): number { - return amount * this.getPixelScalingFactor(); - } - - pixelsToGridUnits(pixels: number): number { - return pixels / this.getPixelScalingFactor(); - } - - render() {} -} diff --git a/src/classes/Renderer.ts b/src/classes/Renderer.ts deleted file mode 100644 index d75bb80..0000000 --- a/src/classes/Renderer.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as PIXI from "pixi.js"; - -export class Renderer { - constructor() {} -} diff --git a/src/classes/Scenes.ts b/src/classes/Scenes.ts deleted file mode 100644 index 09c474e..0000000 --- a/src/classes/Scenes.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as PIXI from "pixi.js"; - -export function makeSceneFromType(type: SceneType) { - if (type == SceneType.MainMenu) { - return new MainMenu(); - } - if (type == SceneType.MissionSelect) { - return new MissionSelect(); - } -} - -export enum SceneType { - MainMenu, - MissionSelect, -} - -export class BaseScene { - public type: SceneType = null; - public destroy(): boolean { - return true; // return when destroyed - } -} - -export class MainMenu extends BaseScene { - public type: SceneType = SceneType.MainMenu; - public; -} - -export class MissionSelect extends BaseScene { - public type: SceneType = SceneType.MissionSelect; -} diff --git a/src/classes/Tower.ts b/src/classes/Tower.ts deleted file mode 100644 index 221d44e..0000000 --- a/src/classes/Tower.ts +++ /dev/null @@ -1 +0,0 @@ -export class Tower {} diff --git a/src/main.ts b/src/main.ts index 99ead5d..7649048 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,5 @@ import * as PIXI from "pixi.js"; -import { Game } from "./classes/Game.ts"; -import { SceneType } from "./classes/Scenes.ts"; +import Game from "./base/Game"; (async () => { const app = new PIXI.Application(); await app.init({ @@ -11,5 +10,10 @@ import { SceneType } from "./classes/Scenes.ts"; }); document.body.appendChild(app.canvas); - globalThis.Game = new Game(SceneType.MainMenu); + const game = new Game(app.screen); + app.stage.addChild(game.container); + window.addEventListener("resize", () => { + app.renderer.resize(window.innerWidth, window.innerHeight); + game.setBounds(0, 0, app.screen.width, app.screen.height); + }); })(); diff --git a/src/scenes/Base.ts b/src/scenes/Base.ts new file mode 100644 index 0000000..f731867 --- /dev/null +++ b/src/scenes/Base.ts @@ -0,0 +1,12 @@ +import * as PIXI from "pixi.js"; +import GameObject from "../base/GameObject"; +export default abstract class Scene extends GameObject { + constructor(bounds: PIXI.Rectangle) { + super(bounds); + this.createScene(); + } + protected triggerBoundsChanged() { + this.createScene(); + } + protected abstract createScene(); +} diff --git a/src/scenes/MainMenu.ts b/src/scenes/MainMenu.ts new file mode 100644 index 0000000..ffe7090 --- /dev/null +++ b/src/scenes/MainMenu.ts @@ -0,0 +1,52 @@ +import Button from "../base/Button"; +import Scene from "./Base"; +import * as PIXI from "pixi.js"; + +export default class MainMenu extends Scene { + private _newGameButton: Button; + private _settingsButton: Button; + + constructor(bounds: PIXI.Rectangle) { + super(bounds); + } + + protected createScene() { + console.log("Creating main menu scene", this.bounds); + this.container.removeChildren(); + const g = new PIXI.Graphics(); + g.rect(0, 0, this.bounds.width, this.bounds.height); + g.fill(0x000000); + this.container.addChild(g); + this._newGameButton = new Button( + "New Game", + new PIXI.Rectangle( + 100, + this.bounds.height / 2 - 80, + this.bounds.width - 200, + 60 + ), + new PIXI.Color("blue") + ); + this._newGameButton.events.on("click", () => { + this.events.emit("newGame"); + }); + this.container.addChild(this._newGameButton.container); + + this._settingsButton = new Button( + "Settings", + new PIXI.Rectangle( + 100, + this.bounds.height / 2 + 20, + this.bounds.width - 200, + 60 + ), + new PIXI.Color("gray") + ); + this._settingsButton.events.on("click", () => { + this.events.emit("settings"); + }); + this.container.addChild(this._settingsButton.container); + this.container.x = this.bounds.x; + this.container.y = this.bounds.y; + } +} diff --git a/src/scenes/MissionSelectMenu.ts b/src/scenes/MissionSelectMenu.ts new file mode 100644 index 0000000..5f9770a --- /dev/null +++ b/src/scenes/MissionSelectMenu.ts @@ -0,0 +1,47 @@ +import Button from "../base/Button"; +import Scene from "./Base"; +import * as PIXI from "pixi.js"; + +export default class MissionMenuSelect extends Scene { + private _buttons: Button[] = []; + + constructor(bounds: PIXI.Rectangle) { + super(bounds); + } + + protected createScene() { + this.container.removeChildren(); + this._buttons = []; + const g = new PIXI.Graphics(); + g.rect(0, 0, this.bounds.width, this.bounds.height); + g.fill(0x000000); + this.container.addChild(g); + this.addMission("Mission 1"); + this.addMission("Mission 2"); + this.addMission("Mission 3"); + this.addMission("Mission 4"); + this.addButton("Back", () => { + this.events.emit("back"); + }); + this.container.x = this.bounds.x; + this.container.y = this.bounds.y; + } + + private addMission(mission: string) { + this.addButton(mission, () => { + this.events.emit("mission", mission); + }); + } + + private addButton(caption: string, onClick: () => void) { + const yOffset = this._buttons.length * 80 + 100; + const button = new Button( + caption, + new PIXI.Rectangle(100, yOffset, this.bounds.width - 200, 60), + new PIXI.Color("white") + ); + button.events.on("click", onClick); + this._buttons.push(button); + this.container.addChild(button.container); + } +} diff --git a/src/scenes/SettingsMenu.ts b/src/scenes/SettingsMenu.ts new file mode 100644 index 0000000..5e2d136 --- /dev/null +++ b/src/scenes/SettingsMenu.ts @@ -0,0 +1,51 @@ +import Button from "../base/Button"; +import Scene from "./Base"; +import * as PIXI from "pixi.js"; + +export default class SettingsMenu extends Scene { + private _newGameButton: Button; + private _settingsButton: Button; + + constructor(bounds: PIXI.Rectangle) { + super(bounds); + } + + protected createScene() { + this.container.removeChildren(); + const g = new PIXI.Graphics(); + g.rect(0, 0, this.bounds.width, this.bounds.height); + g.fill(0x000000); + this.container.addChild(g); + this._newGameButton = new Button( + "New Game", + new PIXI.Rectangle( + 100, + this.bounds.height / 2 - 80, + this.bounds.width - 200, + 60 + ), + new PIXI.Color("blue") + ); + this._newGameButton.events.on("click", () => { + this.events.emit("newGame"); + }); + this.container.addChild(this._newGameButton.container); + + this._settingsButton = new Button( + "Settings", + new PIXI.Rectangle( + 100, + this.bounds.height / 2 + 20, + this.bounds.width - 200, + 60 + ), + new PIXI.Color("gray") + ); + this._settingsButton.events.on("click", () => { + this.events.emit("settings"); + }); + this.container.addChild(this._settingsButton.container); + this.container.x = this.bounds.x; + this.container.y = this.bounds.y; + } +}