diff --git a/.github/workflow/build.yml b/.github/workflow/build.yml
new file mode 100644
index 0000000..bed4f61
--- /dev/null
+++ b/.github/workflow/build.yml
@@ -0,0 +1,33 @@
+name: Build and Deploy
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ build-and-deploy:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v3
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '23.3.0' # Specify the Node.js version
+
+ # Step 3: Install dependencies and build
+ - name: Install Dependencies and Build
+ run: |
+ npm install
+ npm run build # Adjust to your build command
+
+ # Step 4: Deploy to GitHub Pages
+ - name: Deploy to GitHub Pages
+ uses: peaceiris/actions-gh-pages@v3
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./dist # Replace with your build output directory
+ publish_branch: deployed # Deploy to the `gh-pages` branch
diff --git a/bsrc/base/Assets.ts b/bsrc/base/Assets.ts
deleted file mode 100644
index ba81556..0000000
--- a/bsrc/base/Assets.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import * as PIXI from 'pixi.js';
-import { CreepStatsDefinition, MissionDefinition, TowerDefinition } from './Definitions';
-
-export default class Assets {
- public static async LoadAssets() {
- console.log('Loading Texture Assets');
- Assets.ButtonTexture = await PIXI.Assets.load({
- src: '/assets/gui/button_02.png',
- });
- Assets.SidebarTexture = await PIXI.Assets.load({
- src: '/assets/gui/frame.png',
- });
- Assets.Frame2Texture = await PIXI.Assets.load({
- src: '/assets/gui/frame_02.png',
- });
- Assets.HealthTexture = await PIXI.Assets.load({
- src: '/assets/gui/heart.png',
- });
- Assets.GoldTexture = await PIXI.Assets.load({
- src: '/assets/gui/star.png',
- });
- Assets.BasicCreepTexture = await PIXI.Assets.load({
- src: '/assets/creeps/basic.jpg',
- });
- await this.LoadMissions();
- await this.LoadTowers();
- await this.LoadCreepStats();
- }
-
- public static async LoadCreepStats() {
- const res = await fetch('/assets/CreepStats.json');
- const stats = await res.json();
- this.CreepStats = stats;
- }
-
- private static async LoadMissions() {
- Assets.Missions = [await this.LoadMission('/assets/missions/mission_01.json')];
- }
-
- private static async LoadTowers() {
- const res = await fetch('/assets/Towers.json');
- const towers = await res.json();
- Assets.Towers = towers;
- }
-
- private static async LoadMission(missionUrl: string) {
- const res = await fetch(missionUrl);
- const mission = await res.json();
- await this.LoadBackground(mission.mapImage.url);
- return mission;
- }
-
- private static async LoadBackground(backgroundUrl: string) {
- let index = this.MissionBackgrounds.length - 1;
- if (index == -1) index = 0;
- this.MissionBackgrounds[index] = await PIXI.Assets.load({
- src: backgroundUrl,
- });
- }
-
- public static BasicCreepTexture: PIXI.Texture;
-
- public static ButtonTexture: PIXI.Texture;
- public static SidebarTexture: PIXI.Texture;
- public static Frame2Texture: PIXI.Texture;
- public static HealthTexture: PIXI.Texture;
- public static GoldTexture: PIXI.Texture;
-
- public static MissionBackgrounds: PIXI.Texture[] = [];
- public static Missions: MissionDefinition[];
- public static Towers: TowerDefinition[];
- public static CreepStats: CreepStatsDefinition[];
- public static DebuggingEnabled: boolean = true;
-}
diff --git a/bsrc/base/Button.ts b/bsrc/base/Button.ts
deleted file mode 100644
index 6bbeaf0..0000000
--- a/bsrc/base/Button.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import GameObject from './GameObject';
-import Assets from './Assets';
-import * as PIXI from 'pixi.js';
-
-export default class Button extends GameObject {
- private caption: string;
- private color: PIXI.Color;
- private buttonTexture: PIXI.Texture;
- private enabled: boolean = true;
-
- setCaption(caption: string) {
- this.caption = caption;
- this.draw();
- }
-
- setEnabled(enabled: boolean) {
- this.enabled = enabled;
- }
-
- constructor(
- caption: string,
- color: PIXI.Color,
- enabled: boolean = true,
- bounds?: PIXI.Rectangle
- ) {
- super(bounds);
- this.caption = caption;
- this.color = color;
- this.container.interactive = true;
- this.buttonTexture = Assets.ButtonTexture;
- this.enabled = enabled;
- this.draw();
- }
-
- protected draw() {
- this.container.removeChildren();
- // const button = new PIXI.Graphics();
- // button.rect(0, 0, this.bounds.width, this.bounds.height);
- // button.fill(this.color);
- //console.log(this.buttonTexture);
- const button = new PIXI.NineSliceSprite({
- texture: this.buttonTexture,
- leftWidth: 100,
- topHeight: 100,
- rightWidth: 100,
- bottomHeight: 100,
- });
- button.x = 0;
- button.y = 0;
- button.width = this.bounds.width;
- button.height = this.bounds.height;
- this.container.addChild(button);
- const text = new PIXI.Text({
- text: this.caption,
- style: new PIXI.TextStyle({
- fill: 0xffffff,
- fontSize: 24,
- }),
- });
- this.container.addChild(text);
- text.anchor.set(0.5, 0.5);
- text.x = this.bounds.width / 2;
- text.y = this.bounds.height / 2;
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- this.container.on('click', () => {
- if (!this.enabled) return;
- this.events.emit('click');
- });
- }
-}
diff --git a/bsrc/base/Definitions.ts b/bsrc/base/Definitions.ts
deleted file mode 100644
index 4f8bcaa..0000000
--- a/bsrc/base/Definitions.ts
+++ /dev/null
@@ -1,84 +0,0 @@
-export type MissionDefinition = {
- name: string;
- description: string;
- mapImage: MapImageDefinition;
- gameMap: GameMapDefinition;
- rounds: MissionRoundDefinition[];
-};
-
-export type MapImageDefinition = {
- url: string;
- width: number;
- height: number;
-};
-
-export type GameMapDefinition = {
- rows: number;
- columns: number;
- cells: TerrainType[][];
- paths: PathDefinition[];
-};
-
-export type MissionRoundDefinition = {
- waves: WaveDefinition[];
- offeredGems: GemType[];
-};
-
-export type WaveDefinition = {
- firstCreepSpawnTick: number;
- spawnIntervalTicks: number;
- creeps: CreepType[];
-};
-
-export type CreepStatsDefinition = {
- health: number;
- speed: number;
- special: Function;
- resistance: CreepResistancesDefinition;
-};
-
-export type CreepResistancesDefinition = {
- physical: number;
- divine: number;
- fire: number;
- ice: number;
- frostfire: number;
-};
-
-export type TowerDefinition = {
- name: string;
- stats: TowerStatsDefinition;
-};
-
-export type TowerStatsDefinition = {
- damage: number;
- cooldown: number;
- gemSlotsAmount: number;
- cost: number;
- range: number;
-};
-
-export type PathDefinition = [[row: number, column: number]];
-
-export enum CreepType {
- Basic = 0,
- Fast = 1,
-}
-
-export enum TerrainType {
- Restricted = 0,
- Buildable = 1,
- Path = 9,
-}
-
-export enum GemType {
- Fire = 0,
- Yeti = 1,
- Titalium = 2,
- Soulforge = 3,
-}
-
-export enum TowerType {
- Shooting = 0,
- Circle = 1,
-}
diff --git a/bsrc/base/Game.ts b/bsrc/base/Game.ts
deleted file mode 100644
index 6a58641..0000000
--- a/bsrc/base/Game.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import MainMenu from '../scenes/MainMenu';
-import MissionMenuSelect from '../scenes/MissionSelectMenu';
-import GameScene from '../scenes/GameScene';
-import GameObject from './GameObject';
-import * as PIXI from 'pixi.js';
-import SceneBase from '../scenes/SceneBase';
-import Assets from './Assets';
-
-export default class Game extends GameObject {
- private _currentScene: SceneBase | null = null;
-
- constructor(bounds: PIXI.Rectangle) {
- super(bounds);
- let params = new URLSearchParams(location.href);
- if (params.entries().next().value[1] == 'game') {
- this.setScene(new GameScene(Assets.Missions[0], 0, this.bounds));
- } else 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 setScene(scene: SceneBase) {
- if (this._currentScene) {
- this.container.removeChild(this._currentScene.container);
- this._currentScene.destroy();
- }
- this._currentScene = scene;
- console.log('Setting scene', this._currentScene.constructor);
- this.container.addChild(scene.container);
- }
-
- private onNewGame = () => {
- console.log('New Game');
- const missionSelectScene = new MissionMenuSelect(this.bounds);
- missionSelectScene.events.on('mission', (mission) => {
- console.log('Mission selected', mission);
- this.setScene(new GameScene(mission, Assets.Missions.indexOf(mission), this.bounds));
- });
- missionSelectScene.events.on('back', () => {
- this.onMainMenu();
- });
- this.setScene(missionSelectScene);
- };
-
- private onSettings = () => {
- console.log('Settings');
- };
-
- protected triggerBoundsChanged(): void {
- if (this._currentScene) {
- this._currentScene.setBounds(0, 0, this.bounds.width, this.bounds.height);
- }
- }
-
- protected draw() {
- // Nothing to draw, scene is drawing itself.
- }
-}
diff --git a/bsrc/base/GameObject.ts b/bsrc/base/GameObject.ts
deleted file mode 100644
index 5647012..0000000
--- a/bsrc/base/GameObject.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-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 setBounds(bounds: PIXI.Rectangle): void;
- public setBounds(x: number, y: number, width: number, height: number): void;
- public setBounds(boundsOrX: PIXI.Rectangle | number, y?: number, width?: number, height?: number) {
- if (boundsOrX instanceof PIXI.Rectangle) {
- this.bounds = boundsOrX;
- } else {
- this.bounds = new PIXI.Rectangle(boundsOrX, y, width, height);
- }
- this.triggerBoundsChanged(); // GameObject implements this.
- }
-
- public destroy() {
- this._events.removeAllListeners();
- if (this._container.parent) this._container.parent.removeChild(this._container);
- this._container.destroy();
- }
-
- public get container(): PIXI.Container {
- return this._container;
- }
-
- public get events(): PIXI.EventEmitter {
- return this._events;
- }
-
- public getBounds(): PIXI.Rectangle {
- return this.bounds;
- }
-
- protected triggerBoundsChanged() {
- this.draw();
- }
-
- protected abstract draw(): void;
-
- constructor(bounds?: PIXI.Rectangle) {
- this.bounds = bounds ?? new PIXI.Rectangle(0, 0, 0, 0);
- this._container = new PIXI.Container();
- }
-}
diff --git a/bsrc/base/ScrollingFrame.ts b/bsrc/base/ScrollingFrame.ts
deleted file mode 100644
index 69415f1..0000000
--- a/bsrc/base/ScrollingFrame.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import GameObject from './GameObject';
-import Assets from './Assets';
-import * as PIXI from 'pixi.js';
-
-export class Child extends GameObject {
- protected draw() {}
-}
-
-export class ScrollingFrame extends GameObject {
- private canScroll: boolean = false;
- private children: Child[];
- constructor(children: Child[], bounds?: PIXI.Rectangle) {
- super(bounds);
- this.children = children;
- this.container.interactive = true;
- document.addEventListener('wheel', (e) => this.scrollWheel(e));
- this.draw();
- }
- private scrollWheel(e) {
- let scrollBy = e.deltaY;
- console.log(this.canScroll);
- console.log(scrollBy);
- }
-
- protected draw() {
- this.container.removeChildren();
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- this.container.on('mouseentercapture', () => {
- console.log('A');
- this.canScroll = true;
- });
- this.container.on('mouseleavecapture', () => {
- console.log('B');
- this.canScroll = false;
- });
- }
- public destroy() {
- super.destroy();
- document.removeEventListener('wheel', this.scrollWheel);
- }
-}
diff --git a/bsrc/components/Creep.ts b/bsrc/components/Creep.ts
deleted file mode 100644
index 0f927c1..0000000
--- a/bsrc/components/Creep.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-import Assets from '../base/Assets';
-import { CreepStatsDefinition, CreepType, PathDefinition } from '../base/Definitions';
-import GameObject from '../base/GameObject';
-import * as PIXI from 'pixi.js';
-import GameScene from '../scenes/GameScene';
-
-export enum CreepEvents {
- Died = 'died',
- TakenDamage = 'takenDamage',
- Escaped = 'escaped',
- Moved = 'moved',
-}
-
-export default class Creep extends GameObject {
- public creepType: CreepType;
- private path: PathDefinition;
- private stats: CreepStatsDefinition;
- private pathIndex: number = 0;
- private speed: number;
- private gameScene: GameScene;
- public health: number;
- public escaped: boolean = false;
- public died: boolean = false;
- public x: number; // X and Y are local to the grid, not canvas
- public y: number;
- constructor(creepType: CreepType, path: PathDefinition, gameScene: GameScene, bounds?: PIXI.Rectangle) {
- super(bounds);
- this.gameScene = gameScene;
- this.creepType = creepType;
- this.stats = Assets.CreepStats[this.creepType];
- this.speed = this.stats.speed;
- this.health = this.stats.health;
- this.path = path;
- this.x = path[0][1] + 0.5; // centered
- this.y = path[0][0] + 0.5;
- this.gameScene.grid.container.addChild(this.container);
- }
- private gridUnitsToPixels(gridUnits) {
- return this.gameScene.grid.gridUnitsToPixels(gridUnits);
- }
- public update(elapsedMS: number) {
- if (this.pathIndex + 1 == this.path.length) {
- if (this.escaped) return;
- this.events.emit(CreepEvents.Escaped, this);
- this.escaped = true;
- return;
- }
- const currentCell = this.path[this.pathIndex];
- const targetCell = this.path[this.pathIndex + 1];
-
- const targetX = targetCell[1] + 0.5;
- const targetY = targetCell[0] + 0.5;
- const directionX = targetCell[1] - currentCell[1];
- const directionY = targetCell[0] - currentCell[0];
- let deltaX = this.speed * elapsedMS * directionX;
- let deltaY = this.speed * elapsedMS * directionY;
- let increaseIndex = false;
-
- if (deltaX > 0 && this.x + deltaX > targetX) {
- // limit to center of target cell
- deltaX = targetX - this.x;
- increaseIndex = true;
- }
- if (deltaX < 0 && this.x + deltaX < targetX) {
- // limit to center of target cell
- deltaX = targetX - this.x;
- increaseIndex = true;
- }
- if (deltaY > 0 && this.y + deltaY > targetY) {
- // limit to center of target cell
- deltaY = targetY - this.y;
- increaseIndex = true;
- }
- if (deltaY < 0 && this.y + deltaY < targetY) {
- // limit to center of target cell
- deltaY = targetY - this.y;
- increaseIndex = true;
- }
- this.x += deltaX;
- this.y += deltaY;
- if (increaseIndex) this.pathIndex++;
- this.setBounds(
- new PIXI.Rectangle(
- this.gridUnitsToPixels(this.x),
- this.gridUnitsToPixels(this.y),
- this.gridUnitsToPixels(0.5),
- this.gridUnitsToPixels(0.6)
- )
- );
- }
-
- public takeDamage(amount: number) {
- this.health -= amount;
- if (this.health < 0 && !this.died) {
- this.died = true;
- this.events.emit(CreepEvents.Died, this);
- }
- }
-
- public override destroy() {
- super.destroy();
- this.draw = null;
- this.container.removeChildren();
- }
- protected draw() {
- this.container.removeChildren();
- const sprite = new PIXI.Sprite(Assets.BasicCreepTexture);
- sprite.x = 0;
- sprite.y = 0;
- sprite.anchor.set(0.5, 0.5);
- sprite.width = this.bounds.width;
- sprite.height = this.bounds.height;
- this.container.addChild(sprite);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-}
diff --git a/bsrc/components/Grid.ts b/bsrc/components/Grid.ts
deleted file mode 100644
index 4cc5e0b..0000000
--- a/bsrc/components/Grid.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import * as PIXI from 'pixi.js';
-import GameObject from '../base/GameObject';
-import { GameMapDefinition, TerrainType } from '../base/Definitions';
-import Creep, { CreepEvents } from './Creep';
-import GameScene from '../scenes/GameScene';
-import Assets from '../base/Assets';
-
-export class Cell extends GameObject {
- public type: TerrainType;
- public row: number;
- public column: number;
- public isPath: boolean = false;
- private grid: Grid;
-
- constructor(type: TerrainType, row: number, column: number, isPath: boolean, grid: Grid, bounds?: PIXI.Rectangle) {
- super(bounds);
- this.type = type;
- this.row = row;
- this.column = column;
- this.isPath = isPath;
- this.grid = grid;
- this.draw();
- }
-
- protected draw() {
- this.container.removeChildren();
- let g = new PIXI.Graphics();
- g.rect(0, 0, this.bounds.width, this.bounds.height);
- switch (this.type) {
- case TerrainType.Restricted:
- g.fill(0xff0000);
- break;
- case TerrainType.Path:
- g.fill(0xff00ff);
- break;
- case TerrainType.Buildable:
- g.stroke(0x00ff00);
- break;
- }
- this.container.addChild(g);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- if (!Assets.DebuggingEnabled) return;
- const text = new PIXI.Text({
- text: `${this.row}|${this.column}`,
- style: new PIXI.TextStyle({
- fill: 0xffffff,
- dropShadow: true,
- fontSize: 16,
- }),
- });
- this.container.addChild(text);
- text.anchor.set(0.5, 0.5);
- text.x = this.bounds.width / 2;
- text.y = this.bounds.height / 2;
- if (this.isPath) text.text += 'P';
- }
-}
-
-export class Grid extends GameObject {
- private gameMap: GameMapDefinition;
- private cells: Cell[] = [];
- private gameScene: GameScene;
- public creeps: Creep[] = [];
-
- constructor(map: GameMapDefinition, gameScene: GameScene, bounds?: PIXI.Rectangle) {
- super(bounds);
- this.gameMap = map;
- this.gameScene = gameScene;
- console.log(this.gameMap.paths);
- for (let y = 0; y < this.gameMap.columns; y++) {
- for (let x = 0; x < this.gameMap.rows; x++) {
- let type;
- try {
- type = this.gameMap.cells[x][y];
- } catch (e) {
- type = 1;
- }
- const isPath = this.gameMap.paths.some((path) => path.some((p) => p[0] === x && p[1] === y));
- if (isPath) type = TerrainType.Path;
- let cell = new Cell(type, x, y, isPath, this);
- this.cells.push(cell);
- }
- }
- console.log(this.cells);
- this.draw();
- }
- public addCreep(creep: Creep) {
- this.creeps.push(creep);
- creep.events.on(CreepEvents.Died, (diedCreep) => {
- this.onCreepDiedOrEscaped(diedCreep);
- });
- creep.events.on(CreepEvents.Escaped, (escapedCreep) => {
- this.onCreepDiedOrEscaped(escapedCreep);
- });
- }
- private onCreepDiedOrEscaped(creep: Creep) {
- this.creeps.splice(this.creeps.indexOf(creep), 1);
- creep.destroy();
- }
- protected draw() {
- console.log('Drawing Grid', this.bounds);
- this.container.removeChildren();
- let background = new PIXI.Sprite(Assets.MissionBackgrounds[this.gameScene.missionIndex]);
- background.x = 0;
- background.y = 0;
- background.width = this.bounds.width;
- background.height = this.bounds.height;
- this.container.addChild(background);
- for (let cell of this.cells) {
- cell.setBounds(
- parseFloat(this.gridUnitsToPixels(cell.column).toFixed(2)),
- parseFloat(this.gridUnitsToPixels(cell.row).toFixed(2)),
- this.gridUnitsToPixels(1),
- this.gridUnitsToPixels(1)
- );
- this.container.addChild(cell.container);
- }
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-
- private getPixelScalingFactor() {
- const pixelScaleX = this.container.width / this.gameMap.columns;
- const pixelScaleY = this.container.height / this.gameMap.rows;
- return pixelScaleX < pixelScaleY ? pixelScaleX : pixelScaleY;
- }
-
- public gridUnitsToPixels(amount: number): number {
- return amount * this.getPixelScalingFactor();
- }
-
- public pixelsToGridUnits(pixels: number): number {
- return pixels / this.getPixelScalingFactor();
- }
-}
diff --git a/bsrc/components/MissionStats.ts b/bsrc/components/MissionStats.ts
deleted file mode 100644
index c452e03..0000000
--- a/bsrc/components/MissionStats.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import Assets from '../base/Assets';
-import GameObject from '../base/GameObject';
-import * as PIXI from 'pixi.js';
-
-export default class MissionStats extends GameObject {
- private hp: number = 100;
- private gold: number = 0;
-
- public getHP() {
- return this.hp;
- }
-
- public setHP(hp: number) {
- this.hp = hp;
- this.draw();
- }
-
- public takeDamage(damage: number) {
- this.hp -= damage;
- this.draw();
- }
-
- public setGold(gold: number) {
- this.gold = gold;
- this.draw();
- }
-
- constructor(initialHP: number, initialGold: number, bounds?: PIXI.Rectangle) {
- super(bounds);
- this.hp = initialHP;
- this.gold = initialGold;
- this.draw();
- }
-
- protected draw() {
- this.container.removeChildren();
- const sprite = new PIXI.NineSliceSprite({
- texture: Assets.SidebarTexture,
- leftWidth: 100,
- topHeight: 100,
- rightWidth: 100,
- bottomHeight: 100,
- });
- sprite.width = this.bounds.width + 200;
- sprite.height = this.bounds.height + 5;
- sprite.x = sprite.x - 100;
- sprite.y = sprite.y - 5;
- const healthText = new PIXI.Text({
- text: `HP: ${this.hp}`,
- style: new PIXI.TextStyle({
- fill: 'white',
- fontSize: 24,
- fontWeight: 'bold',
- dropShadow: true,
- }),
- });
- healthText.x = 400;
- const goldText = new PIXI.Text({
- text: `Gold: ${this.gold}`,
- style: new PIXI.TextStyle({
- fill: 'white',
- fontSize: 24,
- fontWeight: 'bold',
- dropShadow: true,
- }),
- });
- goldText.x = 400;
- goldText.y = 30;
-
- const healthSprite = new PIXI.Sprite(Assets.HealthTexture);
- healthSprite.x = 365;
- healthSprite.width = 30;
- healthSprite.height = 26;
- healthSprite.y = 1;
-
- const goldSprite = new PIXI.Sprite(Assets.GoldTexture);
- goldSprite.x = 365;
- goldSprite.width = 30;
- goldSprite.height = 26;
- goldSprite.y = 30;
- this.container.addChild(sprite);
- this.container.addChild(healthText);
- this.container.addChild(goldText);
- this.container.addChild(healthSprite);
- this.container.addChild(goldSprite);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-}
diff --git a/bsrc/components/Sidebar.ts b/bsrc/components/Sidebar.ts
deleted file mode 100644
index 3969cf2..0000000
--- a/bsrc/components/Sidebar.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as PIXI from 'pixi.js';
-import GameObject from '../base/GameObject';
-import GameScene from '../scenes/GameScene';
-import Assets from '../base/Assets';
-
-export default class Sidebar extends GameObject {
- private gameScene: GameScene;
- constructor(gameScene: GameScene, bounds?: PIXI.Rectangle) {
- super(bounds);
- this.gameScene = gameScene;
- }
- protected draw() {
- this.container.removeChildren();
- const sprite = new PIXI.NineSliceSprite({
- texture: Assets.SidebarTexture,
- leftWidth: 100,
- topHeight: 100,
- rightWidth: 100,
- bottomHeight: 100,
- });
- sprite.width = this.bounds.width;
- sprite.height = this.bounds.height;
- this.container.addChild(sprite);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-}
diff --git a/bsrc/components/Tower.ts b/bsrc/components/Tower.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/bsrc/components/TowerPicker.ts b/bsrc/components/TowerPicker.ts
deleted file mode 100644
index c6ce642..0000000
--- a/bsrc/components/TowerPicker.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import * as PIXI from 'pixi.js';
-import GameObject from '../base/GameObject';
-import GameScene from '../scenes/GameScene';
-import Assets from '../base/Assets';
-import { ScrollingFrame } from '../base/ScrollingFrame';
-
-export default class TowerPicker extends GameObject {
- private gameScene: GameScene;
- private scrollingFrame: ScrollingFrame;
- constructor(gameScene: GameScene, bounds?: PIXI.Rectangle) {
- super(bounds);
- this.gameScene = gameScene;
- this.scrollingFrame = new ScrollingFrame(null, this.bounds);
- }
- protected draw() {
- this.container.removeChildren();
- const sprite = new PIXI.NineSliceSprite({
- texture: Assets.Frame2Texture,
- leftWidth: 100,
- topHeight: 100,
- rightWidth: 100,
- bottomHeight: 100,
- });
-
- this.scrollingFrame.setBounds(this.bounds);
- this.container.addChild(this.scrollingFrame.container);
- sprite.width = this.bounds.width;
- sprite.height = this.bounds.height;
- this.container.addChild(sprite);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-}
diff --git a/bsrc/components/WaveManager.ts b/bsrc/components/WaveManager.ts
deleted file mode 100644
index 387a57b..0000000
--- a/bsrc/components/WaveManager.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { CreepType, MissionRoundDefinition, PathDefinition } from '../base/Definitions';
-import * as PIXI from 'pixi.js';
-import Creep, { CreepEvents } from './Creep';
-import GameScene from '../scenes/GameScene';
-
-export enum WaveManagerEvents {
- CreepSpawned = 'creepSpawned',
- Finished = 'finished',
-}
-
-type CreepInstance = {
- creep: Creep;
- tickToSpawnAt: number;
- spawned: boolean;
-};
-
-export default class WaveManager {
- // Doesn't need to extend GameObject since it does not render
- // public currentRound: number = 0;
- private creeps: CreepInstance[] = [];
- private rounds: MissionRoundDefinition[];
- private paths: PathDefinition[];
- private ticks: number = 0;
- private started: boolean = false;
- private gameScene: GameScene;
- public finished: boolean = false;
- public events = new PIXI.EventEmitter();
- constructor(rounds: MissionRoundDefinition[], paths: PathDefinition[], gameScene) {
- this.rounds = rounds;
- this.paths = paths;
- this.gameScene = gameScene;
- }
- public start(roundIndex) {
- this.started = true;
- this.ticks = 0;
- this.creeps = [];
- this.finished = false;
- let tickToSpawnAt = 0;
- this.rounds[roundIndex].waves.forEach((wave) => {
- tickToSpawnAt += wave.firstCreepSpawnTick;
- wave.creeps.forEach((creep) => {
- const creepObj = new Creep(creep, this.paths[0], this.gameScene);
- const creepInstance = {
- creep: creepObj,
- tickToSpawnAt,
- spawned: false,
- };
- tickToSpawnAt += wave.spawnIntervalTicks;
- this.creeps.push(creepInstance);
- });
- });
- console.log(this.creeps);
- }
- public end() {
- this.started = false;
- }
- public update(elapsedMS: number): void {
- if (this.started == false) return;
- this.ticks += elapsedMS;
- this.creeps.forEach((creep) => {
- if (!creep.spawned && creep.tickToSpawnAt <= this.ticks) {
- creep.spawned = true;
- this.events.emit(WaveManagerEvents.CreepSpawned, creep.creep);
- console.log('Wave manager creep spawned, ', creep, this.ticks);
- if (!this.finished && this.creeps.every((creep) => creep.spawned)) {
- this.finished = true;
- console.log('wave maanger finisehd');
- this.events.emit(WaveManagerEvents.Finished);
- }
- } else if (creep.spawned) {
- creep.creep.update(elapsedMS);
- }
- });
- }
-}
diff --git a/bsrc/main.ts b/bsrc/main.ts
deleted file mode 100644
index 5f5c14b..0000000
--- a/bsrc/main.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import * as PIXI from "pixi.js";
-import Game from "./base/Game";
-import Assets from "./base/Assets";
-(async () => {
- const app = new PIXI.Application();
- await app.init({
- width: 640,
- height: 360,
- resizeTo: document.body,
- backgroundColor: "white",
- sharedTicker: true,
- preference: "webgl",
- });
-
- document.body.appendChild(app.canvas);
- await Assets.LoadAssets();
- 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/bsrc/scenes/GameScene.ts b/bsrc/scenes/GameScene.ts
deleted file mode 100644
index 06be50a..0000000
--- a/bsrc/scenes/GameScene.ts
+++ /dev/null
@@ -1,155 +0,0 @@
-import Button from '../base/Button';
-import { MissionDefinition } from '../base/Definitions';
-import Creep, { CreepEvents } from '../components/Creep';
-import { Grid } from '../components/Grid';
-import MissionStats from '../components/MissionStats';
-import Sidebar from '../components/Sidebar';
-import TowerPicker from '../components/TowerPicker';
-import WaveManager, { WaveManagerEvents } from '../components/WaveManager';
-import SceneBase from './SceneBase';
-import * as PIXI from 'pixi.js';
-
-enum RoundMode {
- Purchase = 0,
- Combat = 1,
-}
-
-export default class GameScene extends SceneBase {
- public grid: Grid;
- private ticker: PIXI.Ticker;
- private stats: MissionStats;
- private waveManager: WaveManager;
- private sidebar: Sidebar;
- private towerPicker: TowerPicker;
- private roundMode = RoundMode.Purchase;
- private changeRoundButton: Button;
- private currentRound: number = 0;
- public missionIndex: number;
-
- private gridWidth: number;
- private gridHeight: number;
-
- constructor(mission: MissionDefinition, missionIndex: number, bounds: PIXI.Rectangle) {
- super(bounds);
- this.waveManager = new WaveManager(mission.rounds, mission.gameMap.paths, this);
- this.waveManager.events.on(WaveManagerEvents.CreepSpawned, (creep: Creep) => {
- this.grid.addCreep(creep);
- creep.events.on(CreepEvents.Escaped, () => {
- this.onCreepEscaped(creep);
- });
- });
- this.stats = new MissionStats(100, 200);
- this.grid = new Grid(mission.gameMap, this);
- this.sidebar = new Sidebar(this);
- this.towerPicker = new TowerPicker(this);
- this.gridWidth = mission.mapImage.width;
- this.gridHeight = mission.mapImage.height;
- this.ticker = new PIXI.Ticker();
- this.ticker.maxFPS = 60;
- this.ticker.minFPS = 30;
- this.ticker.add(() => this.update(this.ticker.elapsedMS)); // bruh
- this.ticker.start();
- this.missionIndex = missionIndex;
- this.changeRoundButton = new Button('Start', new PIXI.Color('white'), true);
- this.changeRoundButton.events.on('click', () => {
- console.log('clicked');
- this.changeRoundButton.setEnabled(false);
- this.changeRoundButton.setCaption('[X]');
- this.setRoundMode(RoundMode.Combat);
- });
- this.draw();
- }
-
- public destroy() {
- super.destroy();
- this.ticker.stop();
- this.ticker.destroy();
- }
-
- public update(elapsedMS: number) {
- if (this.checkGameOver()) return;
- this.waveManager.update(elapsedMS);
- this.grid.creeps.forEach((creep) => creep.update(elapsedMS));
- this.checkToEndCombat();
- }
-
- private setRoundMode(roundMode: RoundMode) {
- this.roundMode = roundMode;
- if (this.roundMode == RoundMode.Combat) {
- this.waveManager.start(this.currentRound);
- } else {
- this.waveManager.end();
- }
- }
-
- private checkToEndCombat() {
- let isFinished = false; // todo: implement
- if (!this.waveManager.finished) {
- isFinished = false;
- }
- if (isFinished) {
- this.currentRound++;
- this.setRoundMode(RoundMode.Purchase);
- }
- }
-
- private checkGameOver() {
- if (this.stats.getHP() <= 0) {
- // TODO: end game
- return true;
- }
- return false;
- }
-
- private onCreepEscaped(creep: Creep) {
- this.stats.takeDamage(creep.health);
- }
-
- protected draw() {
- console.log('Drawing Game Scene ', this.bounds);
- this.container.removeChildren();
- const g = new PIXI.Graphics();
- g.rect(0, 0, this.bounds.width, this.bounds.height);
- g.fill(0x000033);
- this.container.addChild(g);
- this.stats.setBounds(this.getStatusBounds());
- this.grid.setBounds(this.getGridBounds());
- this.sidebar.setBounds(this.getSidebarBounds());
- this.towerPicker.setBounds(this.getTowerPickerBounds());
- this.changeRoundButton.setBounds(this.getChangeRoundButtonBounds());
- this.container.addChild(this.sidebar.container);
- this.container.addChild(this.stats.container);
- this.container.addChild(this.towerPicker.container);
- this.container.addChild(this.grid.container);
- this.container.addChild(this.changeRoundButton.container);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-
- private getSidebarBounds(): PIXI.Rectangle {
- return new PIXI.Rectangle(this.bounds.width - 350, 0, 350, this.bounds.height);
- }
- private getTowerPickerBounds(): PIXI.Rectangle {
- return new PIXI.Rectangle(this.bounds.width - 350, 100, 350, this.bounds.height - 250);
- }
- private getStatusBounds(): PIXI.Rectangle {
- // Top / Center
- return new PIXI.Rectangle(0, 0, this.bounds.width, 100);
- }
-
- private getGridBounds(): PIXI.Rectangle {
- // Center / Center
- return new PIXI.Rectangle(
- this.bounds.width / 2 - this.gridWidth / 2,
- this.bounds.height / 2 - this.gridHeight / 2,
- this.gridWidth,
- this.gridHeight
- );
- }
- private getChangeRoundButtonBounds(): PIXI.Rectangle {
- // Center / Center
- let width = 350;
- let height = 150;
- return new PIXI.Rectangle(this.bounds.width - width, this.bounds.height - height, width, height);
- }
-}
diff --git a/bsrc/scenes/MainMenu.ts b/bsrc/scenes/MainMenu.ts
deleted file mode 100644
index d45d145..0000000
--- a/bsrc/scenes/MainMenu.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import Button from '../base/Button';
-import SceneBase from './SceneBase';
-import * as PIXI from 'pixi.js';
-
-export default class MainMenu extends SceneBase {
- private _newGameButton: Button;
- private _settingsButton: Button;
-
- constructor(bounds?: PIXI.Rectangle) {
- super(bounds);
- this._newGameButton = new Button('New Game', new PIXI.Color('blue'));
- this._newGameButton.events.on('click', () => {
- this.events.emit('newGame');
- });
- this._settingsButton = new Button('Settings', new PIXI.Color('gray'));
- this._settingsButton.events.on('click', () => {
- this.events.emit('settings');
- });
- this.draw();
- }
-
- protected draw() {
- 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.setBounds(
- this.bounds.width / 2 - 300 / 2,
- this.bounds.height / 2 - 80,
- 300,
- 60
- );
- this._settingsButton.setBounds(
- this.bounds.width / 2 - 300 / 2,
- this.bounds.height / 2 + 20,
- 300,
- 60
- );
- this.container.addChild(this._newGameButton.container);
- this.container.addChild(this._settingsButton.container);
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-}
diff --git a/bsrc/scenes/MissionSelectMenu.ts b/bsrc/scenes/MissionSelectMenu.ts
deleted file mode 100644
index e7b9779..0000000
--- a/bsrc/scenes/MissionSelectMenu.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import Assets from '../base/Assets';
-import Button from '../base/Button';
-import { MissionDefinition } from '../base/Definitions';
-import SceneBase from './SceneBase';
-import * as PIXI from 'pixi.js';
-
-export default class MissionMenuSelect extends SceneBase {
- private _buttons: Button[] = [];
-
- constructor(bounds: PIXI.Rectangle) {
- super(bounds);
- for (const mission of Assets.Missions) {
- this.addMission(mission);
- }
- this.addButton('Back', () => {
- this.events.emit('back');
- });
- this.draw();
- }
-
- protected draw() {
- 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);
- let y = 50;
- for (const button of this._buttons) {
- button.setBounds(this.bounds.width / 2 - 300 / 2, y, 300, 60);
- y += 80;
- this.container.addChild(button.container);
- }
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-
- private addMission(mission: MissionDefinition) {
- this.addButton(mission.name, () => {
- this.events.emit('mission', mission);
- });
- }
-
- private addButton(caption: string, onClick: () => void) {
- const button = new Button(caption, new PIXI.Color('white'));
- button.events.on('click', onClick);
- this._buttons.push(button);
- }
-}
diff --git a/bsrc/scenes/SceneBase.ts b/bsrc/scenes/SceneBase.ts
deleted file mode 100644
index 5ad4249..0000000
--- a/bsrc/scenes/SceneBase.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import * as PIXI from 'pixi.js';
-import GameObject from '../base/GameObject';
-export default abstract class SceneBase extends GameObject {
- constructor(bounds: PIXI.Rectangle) {
- super(bounds);
- }
-}
diff --git a/bsrc/scenes/SettingsMenu.ts b/bsrc/scenes/SettingsMenu.ts
deleted file mode 100644
index ab003aa..0000000
--- a/bsrc/scenes/SettingsMenu.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import Button from '../base/Button';
-import SceneBase from './SceneBase';
-import * as PIXI from 'pixi.js';
-
-export default class SettingsMenu extends SceneBase {
- constructor(bounds: PIXI.Rectangle) {
- super(bounds);
- this.draw();
- }
-
- protected draw() {
- this.container.removeChildren();
- const g = new PIXI.Graphics();
- g.rect(0, 0, this.bounds.width, this.bounds.height);
- g.fill(0x000000);
-
- this.container.x = this.bounds.x;
- this.container.y = this.bounds.y;
- }
-}
diff --git a/bsrc/typescript.svg b/bsrc/typescript.svg
deleted file mode 100644
index d91c910..0000000
--- a/bsrc/typescript.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/bsrc/vite-env.d.ts b/bsrc/vite-env.d.ts
deleted file mode 100644
index 11f02fe..0000000
--- a/bsrc/vite-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/tsconfig.json b/tsconfig.json
index cbbd5ac..582a3a3 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -18,6 +18,6 @@
"allowJs": true,
"checkJs": false
},
- "include": ["bsrc/**/*"],
+ "include": ["src/**/*"],
"exclude": ["node_modules", "build"]
}