remove old source + make deployment workflow
This commit is contained in:
parent
5cb7dbba09
commit
2f12f98bba
33
.github/workflow/build.yml
vendored
Normal file
33
.github/workflow/build.yml
vendored
Normal file
@ -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
|
@ -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;
|
|
||||||
}
|
|
@ -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');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,
|
|
||||||
}
|
|
@ -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.
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
23
bsrc/main.ts
23
bsrc/main.ts
@ -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);
|
|
||||||
});
|
|
||||||
})();
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path fill="#007ACC" d="M0 128v128h256V0H0z"></path><path fill="#FFF" d="m56.612 128.85l-.081 10.483h33.32v94.68h23.568v-94.68h33.321v-10.28c0-5.69-.122-10.444-.284-10.566c-.122-.162-20.4-.244-44.983-.203l-44.74.122l-.121 10.443Zm149.955-10.742c6.501 1.625 11.459 4.51 16.01 9.224c2.357 2.52 5.851 7.111 6.136 8.208c.08.325-11.053 7.802-17.798 11.988c-.244.162-1.22-.894-2.317-2.52c-3.291-4.795-6.745-6.867-12.028-7.233c-7.76-.528-12.759 3.535-12.718 10.321c0 1.992.284 3.17 1.097 4.795c1.707 3.536 4.876 5.649 14.832 9.956c18.326 7.883 26.168 13.084 31.045 20.48c5.445 8.249 6.664 21.415 2.966 31.208c-4.063 10.646-14.14 17.879-28.323 20.276c-4.388.772-14.79.65-19.504-.203c-10.28-1.828-20.033-6.908-26.047-13.572c-2.357-2.6-6.949-9.387-6.664-9.874c.122-.163 1.178-.813 2.356-1.504c1.138-.65 5.446-3.129 9.509-5.485l7.355-4.267l1.544 2.276c2.154 3.29 6.867 7.801 9.712 9.305c8.167 4.307 19.383 3.698 24.909-1.26c2.357-2.153 3.332-4.388 3.332-7.68c0-2.966-.366-4.266-1.91-6.501c-1.99-2.845-6.054-5.242-17.595-10.24c-13.206-5.69-18.895-9.224-24.096-14.832c-3.007-3.25-5.852-8.452-7.03-12.8c-.975-3.617-1.22-12.678-.447-16.335c2.723-12.76 12.353-21.659 26.25-24.3c4.51-.853 14.994-.528 19.424.569Z"></path></svg>
|
|
Before Width: | Height: | Size: 1.4 KiB |
1
bsrc/vite-env.d.ts
vendored
1
bsrc/vite-env.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
@ -18,6 +18,6 @@
|
|||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"checkJs": false
|
"checkJs": false
|
||||||
},
|
},
|
||||||
"include": ["bsrc/**/*"],
|
"include": ["src/**/*"],
|
||||||
"exclude": ["node_modules", "build"]
|
"exclude": ["node_modules", "build"]
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user