this is difficult
This commit is contained in:
parent
b394ff9e0a
commit
086c733bb3
23
index.html
23
index.html
@ -1,13 +1,16 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="style.css" />
|
<link rel="stylesheet" href="style.css" />
|
||||||
<title>Bastion App</title>
|
<title>Bastion App</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<div id="game-container" style="background-color: black; width: 100%; height: 100%; overflow: hidden">
|
||||||
</body>
|
<canvas id="game-canvas"></canvas>
|
||||||
|
</div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
1890
package-lock.json
generated
1890
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
33
package.json
33
package.json
@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "bastion",
|
"name": "bastion",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.5.3",
|
"typescript": "^5.5.3",
|
||||||
"vite": "^5.4.1"
|
"vite": "^5.4.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pixi.js": "^8.4.0"
|
"pixi-viewport": "^6.0.3",
|
||||||
}
|
"pixi.js": "^8.4.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
28
public/Mission01.tmx
Normal file
28
public/Mission01.tmx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="20" height="20" tilewidth="64" tileheight="64" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||||
|
<tileset firstgid="1" source="Tileset.tsx"/>
|
||||||
|
<layer id="1" name="Tile Layer 1" width="20" height="20">
|
||||||
|
<data encoding="csv">
|
||||||
|
15,15,15,15,15,15,15,16,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,15,15,15,
|
||||||
|
4,4,4,4,4,4,4,4,4,4,4,5,15,15,15,15,15,15,15,15,
|
||||||
|
32,32,32,32,32,32,32,32,32,32,7,19,15,15,15,15,15,15,15,16,
|
||||||
|
15,15,15,15,15,15,16,15,15,15,17,19,15,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,17,19,15,15,15,15,15,15,15,15,
|
||||||
|
15,16,15,15,15,15,15,15,15,15,17,19,15,15,16,15,15,15,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,17,20,4,4,4,4,4,5,15,15,
|
||||||
|
15,15,15,15,16,15,15,15,15,15,31,32,32,32,32,32,7,19,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,19,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,19,15,15,
|
||||||
|
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,19,15,15,
|
||||||
|
15,16,15,15,3,4,4,4,4,4,4,4,4,4,4,4,21,19,15,15,
|
||||||
|
15,15,15,15,17,6,32,32,32,32,32,32,32,32,32,32,32,33,15,15,
|
||||||
|
15,15,15,15,17,19,16,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,17,19,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,17,19,15,15,15,15,15,15,15,16,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,17,19,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||||
|
15,15,15,15,17,19,15,15,15,15,15,15,15,15,15,15,15,15,15,15
|
||||||
|
</data>
|
||||||
|
</layer>
|
||||||
|
</map>
|
4
public/Tileset.tsx
Normal file
4
public/Tileset.tsx
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<tileset version="1.10" tiledversion="1.11.0" name="TiledTDThree64" tilewidth="64" tileheight="64" tilecount="140" columns="14">
|
||||||
|
<image source="../../../../dumping/tiles/TiledTDThree64.png" width="896" height="640"/>
|
||||||
|
</tileset>
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 127 KiB |
@ -3,11 +3,11 @@
|
|||||||
"description": "This is the first mission",
|
"description": "This is the first mission",
|
||||||
"mapImage": {
|
"mapImage": {
|
||||||
"url": "/assets/maps/mission_01.png",
|
"url": "/assets/maps/mission_01.png",
|
||||||
"width": 1200,
|
"width": 1280,
|
||||||
"height": 900
|
"height": 1280
|
||||||
},
|
},
|
||||||
"gameMap": {
|
"gameMap": {
|
||||||
"rows": 15,
|
"rows": 20,
|
||||||
"columns": 20,
|
"columns": 20,
|
||||||
"cells": [
|
"cells": [
|
||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
@ -24,6 +24,12 @@
|
|||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||||
],
|
],
|
||||||
"paths": [
|
"paths": [
|
||||||
|
14
public/maps.tiled-project
Normal file
14
public/maps.tiled-project
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"automappingRulesFile": "",
|
||||||
|
"commands": [
|
||||||
|
],
|
||||||
|
"compatibilityVersion": 1100,
|
||||||
|
"extensionsPath": "extensions",
|
||||||
|
"folders": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"properties": [
|
||||||
|
],
|
||||||
|
"propertyTypes": [
|
||||||
|
]
|
||||||
|
}
|
43
public/maps.tiled-session
Normal file
43
public/maps.tiled-session
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"Map/SizeTest": {
|
||||||
|
"height": 4300,
|
||||||
|
"width": 2
|
||||||
|
},
|
||||||
|
"activeFile": "",
|
||||||
|
"expandedProjectPaths": [
|
||||||
|
"."
|
||||||
|
],
|
||||||
|
"file.lastUsedOpenFilter": "All Files (*)",
|
||||||
|
"fileStates": {
|
||||||
|
"": {
|
||||||
|
"scaleInDock": 0.33
|
||||||
|
},
|
||||||
|
"#TiledTDThree128": {
|
||||||
|
"scaleInDock": 0.33,
|
||||||
|
"scaleInEditor": 1
|
||||||
|
},
|
||||||
|
"/home/koneko/dumping/tiles/TiledTDThree64.tmx": {
|
||||||
|
"scale": 0.187625,
|
||||||
|
"selectedLayer": 0,
|
||||||
|
"viewCenter": {
|
||||||
|
"x": 3197.8680879413732,
|
||||||
|
"y": 3197.8680879413732
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tileset.tsx": {
|
||||||
|
"scaleInDock": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last.externalTilesetPath": "/home/koneko/Programing/js/towerdefense/public",
|
||||||
|
"map.lastUsedFormat": "tmx",
|
||||||
|
"map.tileHeight": 64,
|
||||||
|
"map.tileWidth": 64,
|
||||||
|
"map.width": 20,
|
||||||
|
"openFiles": [
|
||||||
|
],
|
||||||
|
"project": "maps.tiled-project",
|
||||||
|
"recentFiles": [
|
||||||
|
"/home/koneko/dumping/tiles/TiledTDThree64.tmx"
|
||||||
|
],
|
||||||
|
"tileset.lastUsedFilter": "Tiled tileset files (*.tsx *.xml)"
|
||||||
|
}
|
@ -7,9 +7,9 @@ html {
|
|||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: black;
|
/* background-color: white;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center; */
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,55 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import { CreepStatsDefinition, MissionDefinition, TowerDefinition } from './Definitions';
|
import { CreepStatsDefinition, MissionDefinition, TowerDefinition } from './Definitions';
|
||||||
|
import { Globals } from './Bastion';
|
||||||
|
|
||||||
export default class Assets {
|
export default class GameAssets {
|
||||||
public static async LoadAssets() {
|
public static async LoadAssets() {
|
||||||
console.log('Loading Texture Assets');
|
console.log('Loading Texture Assets');
|
||||||
Assets.Button01Texture = await PIXI.Assets.load({
|
const text = new PIXI.Text({
|
||||||
|
text: 'Loading textures. This might take a while.',
|
||||||
|
style: new PIXI.TextStyle({
|
||||||
|
fill: 0xffffff,
|
||||||
|
fontSize: 50,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
text.x = Globals.WindowWidth / 2;
|
||||||
|
text.y = Globals.WindowHeight / 2;
|
||||||
|
text.anchor.set(0.5, 0.5);
|
||||||
|
Globals.app.stage.addChild(text);
|
||||||
|
GameAssets.Button01Texture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/button_01.png',
|
src: '/assets/gui/button_01.png',
|
||||||
});
|
});
|
||||||
Assets.Button02Texture = await PIXI.Assets.load({
|
GameAssets.Button02Texture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/button_02.png',
|
src: '/assets/gui/button_02.png',
|
||||||
});
|
});
|
||||||
Assets.Frame01Texture = await PIXI.Assets.load({
|
GameAssets.Frame01Texture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/frame_01.png',
|
src: '/assets/gui/frame_01.png',
|
||||||
});
|
});
|
||||||
Assets.Frame02Texture = await PIXI.Assets.load({
|
GameAssets.Frame02Texture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/frame_02.png',
|
src: '/assets/gui/frame_02.png',
|
||||||
});
|
});
|
||||||
Assets.FrameGreenTexture = await PIXI.Assets.load({
|
GameAssets.FrameGreenTexture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/frame_green.png',
|
src: '/assets/gui/frame_green.png',
|
||||||
});
|
});
|
||||||
Assets.FrameRedTexture = await PIXI.Assets.load({
|
GameAssets.FrameRedTexture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/frame_red.png',
|
src: '/assets/gui/frame_red.png',
|
||||||
});
|
});
|
||||||
Assets.FrameVioletTexture = await PIXI.Assets.load({
|
GameAssets.FrameVioletTexture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/frame_violet.png',
|
src: '/assets/gui/frame_violet.png',
|
||||||
});
|
});
|
||||||
Assets.HealthTexture = await PIXI.Assets.load({
|
GameAssets.HealthTexture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/heart.png',
|
src: '/assets/gui/heart.png',
|
||||||
});
|
});
|
||||||
Assets.GoldTexture = await PIXI.Assets.load({
|
GameAssets.GoldTexture = await PIXI.Assets.load({
|
||||||
src: '/assets/gui/star.png',
|
src: '/assets/gui/star.png',
|
||||||
});
|
});
|
||||||
Assets.BasicCreepTexture = await PIXI.Assets.load({
|
GameAssets.BasicCreepTexture = await PIXI.Assets.load({
|
||||||
src: '/assets/creeps/basic.jpg',
|
src: '/assets/creeps/basic.jpg',
|
||||||
});
|
});
|
||||||
await this.LoadMissions();
|
await this.LoadMissions();
|
||||||
await this.LoadTowers();
|
await this.LoadTowers();
|
||||||
await this.LoadCreepStats();
|
await this.LoadCreepStats();
|
||||||
|
text.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async LoadCreepStats() {
|
public static async LoadCreepStats() {
|
||||||
@ -46,13 +59,13 @@ export default class Assets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async LoadMissions() {
|
private static async LoadMissions() {
|
||||||
Assets.Missions = [await this.LoadMission('/assets/missions/mission_01.json')];
|
GameAssets.Missions = [await this.LoadMission('/assets/missions/mission_01.json')];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async LoadTowers() {
|
private static async LoadTowers() {
|
||||||
const res = await fetch('/assets/Towers.json');
|
const res = await fetch('/assets/Towers.json');
|
||||||
const towers = await res.json();
|
const towers = await res.json();
|
||||||
Assets.Towers = towers;
|
GameAssets.Towers = towers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async LoadMission(missionUrl: string) {
|
private static async LoadMission(missionUrl: string) {
|
||||||
|
@ -2,13 +2,15 @@ import * as PIXI from 'pixi.js';
|
|||||||
import GameObject from './GameObject';
|
import GameObject from './GameObject';
|
||||||
import GuiObject from './GuiObject';
|
import GuiObject from './GuiObject';
|
||||||
import Scene from '../scenes/Scene';
|
import Scene from '../scenes/Scene';
|
||||||
|
import { Grid } from './game/Grid';
|
||||||
|
|
||||||
export class environment {
|
export class Globals {
|
||||||
public static app: PIXI.Application;
|
public static app: PIXI.Application;
|
||||||
public static GameMaster: GameMaster;
|
public static GameMaster: GameMaster;
|
||||||
public static WindowHeight: number;
|
public static WindowHeight: number;
|
||||||
public static WindowWidth: number;
|
public static WindowWidth: number;
|
||||||
public static AspectRatio: number = 4 / 3;
|
public static AspectRatio: number = 16 / 9;
|
||||||
|
public static Grid: Grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class GameMaster {
|
export default class GameMaster {
|
||||||
@ -17,7 +19,7 @@ export default class GameMaster {
|
|||||||
private ticker: PIXI.Ticker;
|
private ticker: PIXI.Ticker;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
environment.GameMaster = this;
|
Globals.GameMaster = this;
|
||||||
this.ticker = new PIXI.Ticker();
|
this.ticker = new PIXI.Ticker();
|
||||||
this.ticker.maxFPS = 60;
|
this.ticker.maxFPS = 60;
|
||||||
this.ticker.minFPS = 30;
|
this.ticker.minFPS = 30;
|
||||||
@ -26,22 +28,24 @@ export default class GameMaster {
|
|||||||
|
|
||||||
public _CreateGameObject(object: GameObject) {
|
public _CreateGameObject(object: GameObject) {
|
||||||
this.GameObjects.push(object);
|
this.GameObjects.push(object);
|
||||||
environment.app.stage.addChild(object.container);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public _RemoveGameObject(object: GameObject) {
|
public _RemoveGameObject(object: GameObject) {
|
||||||
this.GameObjects.splice(this.GameObjects.indexOf(object), 1);
|
this.GameObjects.splice(this.GameObjects.indexOf(object), 1);
|
||||||
environment.app.stage.removeChild(object.container);
|
}
|
||||||
|
|
||||||
|
public GetGameObjectByName(name: string) {
|
||||||
|
return this.GameObjects.filter((obj) => obj.name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public _CreateGuiObject(object: GuiObject) {
|
public _CreateGuiObject(object: GuiObject) {
|
||||||
this.currentScene.gui.push(object);
|
this.currentScene.gui.push(object);
|
||||||
environment.app.stage.addChild(object.container);
|
Globals.app.stage.addChild(object.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public _RemoveGuiObject(object: GuiObject) {
|
public _RemoveGuiObject(object: GuiObject) {
|
||||||
this.currentScene.gui.splice(this.currentScene.gui.indexOf(object), 1);
|
this.currentScene.gui.splice(this.currentScene.gui.indexOf(object), 1);
|
||||||
environment.app.stage.removeChild(object.container);
|
Globals.app.stage.removeChild(object.container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public changeScene(newScene: Scene) {
|
public changeScene(newScene: Scene) {
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import { environment } from './Bastion';
|
import { Globals } from './Bastion';
|
||||||
|
|
||||||
export default abstract class GameObject {
|
export default abstract class GameObject {
|
||||||
public readonly name: string = this.constructor.name;
|
public readonly name: string = this.constructor.name;
|
||||||
|
|
||||||
protected _container: PIXI.Container = new PIXI.Container();
|
protected _container: PIXI.Container = new PIXI.Container();
|
||||||
|
|
||||||
|
// bb = bounding box
|
||||||
|
protected bb: PIXI.Rectangle = new PIXI.Rectangle();
|
||||||
|
|
||||||
protected _events: PIXI.EventEmitter = new PIXI.EventEmitter();
|
protected _events: PIXI.EventEmitter = new PIXI.EventEmitter();
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
environment.GameMaster._RemoveGameObject(this);
|
Globals.GameMaster._RemoveGameObject(this);
|
||||||
this._events.removeAllListeners();
|
this._events.removeAllListeners();
|
||||||
if (this._container.parent) this._container.parent.removeChild(this._container);
|
if (this._container.parent) this._container.parent.removeChild(this._container);
|
||||||
this._container.destroy();
|
this._container.destroy();
|
||||||
@ -24,8 +27,4 @@ export default abstract class GameObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract update(elapsedMS): void;
|
public abstract update(elapsedMS): void;
|
||||||
|
|
||||||
constructor() {
|
|
||||||
environment.GameMaster._CreateGameObject(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import { environment } from './Bastion';
|
import { Globals } from './Bastion';
|
||||||
|
|
||||||
export default abstract class GuiObject {
|
export default abstract class GuiObject {
|
||||||
public readonly name: string = this.constructor.name;
|
public readonly name: string = this.constructor.name;
|
||||||
@ -37,7 +37,7 @@ export default abstract class GuiObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(interactive?: boolean) {
|
constructor(interactive?: boolean) {
|
||||||
environment.GameMaster._CreateGuiObject(this);
|
Globals.GameMaster._CreateGuiObject(this);
|
||||||
if (!interactive) return;
|
if (!interactive) return;
|
||||||
this._container.interactive = true;
|
this._container.interactive = true;
|
||||||
this._container.onwheel = (e) => {
|
this._container.onwheel = (e) => {
|
||||||
|
105
src/classes/game/Grid.ts
Normal file
105
src/classes/game/Grid.ts
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import * as PIXI from 'pixi.js';
|
||||||
|
import GameObject from '../GameObject';
|
||||||
|
import { GameMapDefinition, TerrainType } from '../Definitions';
|
||||||
|
// import Creep, { CreepEvents } from './Creep';
|
||||||
|
import GameAssets from '../Assets';
|
||||||
|
import { Viewport } from 'pixi-viewport';
|
||||||
|
import { Globals } from '../Bastion';
|
||||||
|
|
||||||
|
export class Cell extends GameObject {
|
||||||
|
public type: TerrainType;
|
||||||
|
public row: number;
|
||||||
|
public column: number;
|
||||||
|
public isPath: boolean = false;
|
||||||
|
|
||||||
|
constructor(type: TerrainType, row: number, column: number, isPath: boolean) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.row = row;
|
||||||
|
this.column = column;
|
||||||
|
this.isPath = isPath;
|
||||||
|
// this.bb.x = parseFloat(environment.Grid.gridUnitsToPixels(this.column).toFixed(2));
|
||||||
|
// this.bb.y = parseFloat(environment.Grid.gridUnitsToPixels(this.row).toFixed(2));
|
||||||
|
if (column == 24 || column == 23) console.log(`col ${column} ` + Globals.Grid.gridUnitsToPixels(this.column));
|
||||||
|
this.bb.x = Globals.Grid.gridUnitsToPixels(this.column);
|
||||||
|
this.bb.y = Globals.Grid.gridUnitsToPixels(this.row);
|
||||||
|
this.bb.width = Globals.Grid.gridUnitsToPixels(1);
|
||||||
|
this.bb.height = Globals.Grid.gridUnitsToPixels(1);
|
||||||
|
Globals.Grid.container.addChild(this.container);
|
||||||
|
Globals.GameMaster._CreateGameObject(this);
|
||||||
|
let g = new PIXI.Graphics();
|
||||||
|
g.rect(0, 0, this.bb.width, this.bb.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.bb.x;
|
||||||
|
this.container.y = this.bb.y;
|
||||||
|
if (!GameAssets.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.bb.width / 2;
|
||||||
|
text.y = this.bb.height / 2;
|
||||||
|
if (this.isPath) text.text += 'P';
|
||||||
|
}
|
||||||
|
public update() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Grid extends GameObject {
|
||||||
|
private gameMap: GameMapDefinition;
|
||||||
|
private cells: Cell[] = [];
|
||||||
|
// public creeps: Creep[] = [];
|
||||||
|
|
||||||
|
constructor(map: GameMapDefinition, missionIndex) {
|
||||||
|
super();
|
||||||
|
this.gameMap = map;
|
||||||
|
Globals.Grid = this;
|
||||||
|
this.container.isRenderGroup = true;
|
||||||
|
this.bb.x = 0;
|
||||||
|
this.bb.y = 110;
|
||||||
|
this.bb.width = Globals.WindowWidth - 360;
|
||||||
|
this.bb.height = Globals.WindowHeight - 110;
|
||||||
|
Globals.app.stage.addChild(this.container);
|
||||||
|
Globals.GameMaster._CreateGameObject(this);
|
||||||
|
|
||||||
|
let background = new PIXI.Sprite(GameAssets.MissionBackgrounds[missionIndex]);
|
||||||
|
background.x = 0;
|
||||||
|
background.y = 0;
|
||||||
|
this.bb.width = this.gridUnitsToPixels(1) * this.gameMap.columns;
|
||||||
|
this.bb.height = this.gridUnitsToPixels(1) * this.gameMap.rows;
|
||||||
|
background.width = this.bb.width;
|
||||||
|
background.height = this.bb.height;
|
||||||
|
|
||||||
|
this.container.addChild(background);
|
||||||
|
}
|
||||||
|
public update() {}
|
||||||
|
private getPixelScalingFactor() {
|
||||||
|
const pixelScaleX = this.bb.width / this.gameMap.columns;
|
||||||
|
const pixelScaleY = this.bb.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,6 +1,6 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import GuiObject from '../GuiObject';
|
import GuiObject from '../GuiObject';
|
||||||
import Assets from '../Assets';
|
import GameAssets from '../Assets';
|
||||||
|
|
||||||
export default class Sidebar extends GuiObject {
|
export default class Sidebar extends GuiObject {
|
||||||
private bounds: PIXI.Rectangle;
|
private bounds: PIXI.Rectangle;
|
||||||
@ -11,10 +11,8 @@ export default class Sidebar extends GuiObject {
|
|||||||
this.bounds = bounds;
|
this.bounds = bounds;
|
||||||
this.container.x = this.bounds.x;
|
this.container.x = this.bounds.x;
|
||||||
this.container.y = this.bounds.y;
|
this.container.y = this.bounds.y;
|
||||||
this.container.width = this.bounds.width;
|
|
||||||
this.container.height = this.bounds.height;
|
|
||||||
this.sidebarSprite = new PIXI.NineSliceSprite({
|
this.sidebarSprite = new PIXI.NineSliceSprite({
|
||||||
texture: Assets.Frame01Texture,
|
texture: GameAssets.Frame01Texture,
|
||||||
leftWidth: 100,
|
leftWidth: 100,
|
||||||
topHeight: 100,
|
topHeight: 100,
|
||||||
rightWidth: 100,
|
rightWidth: 100,
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
|
||||||
import GuiObject from '../GuiObject';
|
|
||||||
import Assets from '../Assets';
|
|
||||||
|
|
||||||
export default class Topbar extends GuiObject {
|
|
||||||
private bounds: PIXI.Rectangle;
|
|
||||||
private sidebarSprite: PIXI.NineSliceSprite;
|
|
||||||
|
|
||||||
constructor(bounds: PIXI.Rectangle) {
|
|
||||||
super(false);
|
|
||||||
this.bounds = bounds;
|
|
||||||
this.container.x = this.bounds.x;
|
|
||||||
this.container.y = this.bounds.y;
|
|
||||||
this.container.width = this.bounds.width;
|
|
||||||
this.container.height = this.bounds.height;
|
|
||||||
this.sidebarSprite = new PIXI.NineSliceSprite({
|
|
||||||
texture: Assets.Frame01Texture,
|
|
||||||
leftWidth: 100,
|
|
||||||
topHeight: 100,
|
|
||||||
rightWidth: 100,
|
|
||||||
bottomHeight: 100,
|
|
||||||
});
|
|
||||||
this.sidebarSprite.x = -40;
|
|
||||||
this.sidebarSprite.y = -40;
|
|
||||||
this.sidebarSprite.width = this.bounds.width + 40;
|
|
||||||
this.sidebarSprite.height = this.bounds.height;
|
|
||||||
this.container.addChild(this.sidebarSprite);
|
|
||||||
}
|
|
||||||
}
|
|
33
src/main.ts
33
src/main.ts
@ -1,39 +1,36 @@
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import GameMaster, { environment } from './classes/Bastion';
|
import GameMaster, { Globals } from './classes/Bastion';
|
||||||
import Assets from './classes/Assets';
|
import Assets from './classes/Assets';
|
||||||
import { MainScene } from './scenes/Main';
|
import { MainScene } from './scenes/Main';
|
||||||
import { GameScene } from './scenes/Game';
|
import { GameScene } from './scenes/Game';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const app = new PIXI.Application();
|
const app = new PIXI.Application();
|
||||||
const aspectRatio = environment.AspectRatio;
|
const aspectRatio = Globals.AspectRatio;
|
||||||
const maxWidth = window.innerWidth;
|
const maxWidth = window.innerWidth;
|
||||||
const maxHeight = window.innerHeight;
|
const maxHeight = window.innerHeight;
|
||||||
const width = Math.min(maxWidth * 0.75, maxHeight * aspectRatio);
|
const width = Math.min(maxWidth * 0.75, maxHeight * aspectRatio);
|
||||||
const height = width / aspectRatio;
|
const height = width / aspectRatio;
|
||||||
environment.WindowWidth = width;
|
Globals.app = app;
|
||||||
environment.WindowHeight = height;
|
|
||||||
environment.app = app;
|
|
||||||
|
|
||||||
await app.init({
|
await app.init({
|
||||||
width: width,
|
width: maxWidth,
|
||||||
height: height,
|
height: maxHeight,
|
||||||
backgroundColor: 'gray',
|
backgroundColor: 'black',
|
||||||
sharedTicker: true,
|
sharedTicker: true,
|
||||||
preference: 'webgl',
|
preference: 'webgl',
|
||||||
});
|
});
|
||||||
|
const screenRatio = maxWidth / maxHeight;
|
||||||
|
const scale = screenRatio < aspectRatio ? maxWidth / width : maxHeight / height;
|
||||||
|
|
||||||
|
app.stage.scale.x = scale;
|
||||||
|
app.stage.scale.y = scale;
|
||||||
|
Globals.WindowWidth = maxWidth / scale;
|
||||||
|
Globals.WindowHeight = maxHeight / scale;
|
||||||
document.body.appendChild(app.canvas);
|
document.body.appendChild(app.canvas);
|
||||||
await Assets.LoadAssets();
|
await Assets.LoadAssets();
|
||||||
new GameMaster();
|
new GameMaster();
|
||||||
environment.GameMaster.changeScene(new MainScene());
|
Globals.GameMaster.changeScene(new MainScene());
|
||||||
let params = new URLSearchParams(location.href);
|
let params = new URLSearchParams(location.href);
|
||||||
if (params.entries().next().value[1] == 'game') environment.GameMaster.changeScene(new GameScene('Mission 1'));
|
if (params.entries().next().value[1] == 'game') Globals.GameMaster.changeScene(new GameScene('Mission 1'));
|
||||||
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
const newWidth = Math.min(window.innerWidth * 0.75, window.innerHeight * aspectRatio);
|
|
||||||
const newHeight = newWidth / aspectRatio;
|
|
||||||
environment.WindowWidth = newWidth;
|
|
||||||
environment.WindowHeight = newHeight;
|
|
||||||
app.renderer.resize(newWidth, newHeight);
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
import Assets from '../classes/Assets';
|
import GameAssets from '../classes/Assets';
|
||||||
import { environment } from '../classes/Bastion';
|
import { Globals } from '../classes/Bastion';
|
||||||
import { MissionDefinition } from '../classes/Definitions';
|
import { MissionDefinition } from '../classes/Definitions';
|
||||||
|
import { Grid } from '../classes/game/Grid';
|
||||||
import Sidebar from '../classes/gui/Sidebar';
|
import Sidebar from '../classes/gui/Sidebar';
|
||||||
import Topbar from '../classes/gui/Topbar';
|
|
||||||
import Scene from './Scene';
|
import Scene from './Scene';
|
||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
|
|
||||||
export class GameScene extends Scene {
|
export class GameScene extends Scene {
|
||||||
public mission: MissionDefinition;
|
public mission: MissionDefinition;
|
||||||
|
public missionIndex: number;
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
super();
|
super();
|
||||||
Assets.Missions.forEach((mission) => {
|
GameAssets.Missions.forEach((mission, index) => {
|
||||||
if (mission.name == name) this.mission = mission;
|
if (mission.name == name) {
|
||||||
|
this.mission = mission;
|
||||||
|
this.missionIndex = index;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public init() {
|
public init() {
|
||||||
const SidebarRect = new PIXI.Rectangle(environment.WindowWidth - 400, 0, 400, environment.WindowHeight);
|
const SidebarRect = new PIXI.Rectangle(Globals.WindowWidth - 400, 0, 400, Globals.WindowHeight);
|
||||||
const TopbarRect = new PIXI.Rectangle(0, 0, environment.WindowWidth, 150);
|
|
||||||
|
|
||||||
new Topbar(TopbarRect);
|
|
||||||
new Sidebar(SidebarRect);
|
new Sidebar(SidebarRect);
|
||||||
|
new Grid(this.mission.gameMap, this.missionIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { environment } from '../classes/Bastion';
|
import { Globals } from '../classes/Bastion';
|
||||||
import Button, { ButtonTexture } from '../classes/gui/Button';
|
import Button, { ButtonTexture } from '../classes/gui/Button';
|
||||||
import { MissionPickerScene } from './MissionPicker';
|
import { MissionPickerScene } from './MissionPicker';
|
||||||
import Scene from './Scene';
|
import Scene from './Scene';
|
||||||
@ -8,19 +8,19 @@ export class MainScene extends Scene {
|
|||||||
public init() {
|
public init() {
|
||||||
const NewGameButton = {
|
const NewGameButton = {
|
||||||
caption: 'New Game',
|
caption: 'New Game',
|
||||||
rect: new PIXI.Rectangle(environment.WindowWidth / 2 - 300 / 2, environment.WindowHeight / 2 - 80, 300, 60),
|
rect: new PIXI.Rectangle(Globals.WindowWidth / 2 - 300 / 2, Globals.WindowHeight / 2 - 80, 300, 60),
|
||||||
texture: ButtonTexture.Button01,
|
texture: ButtonTexture.Button01,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SettingsButton = {
|
const SettingsButton = {
|
||||||
caption: 'Settings',
|
caption: 'Settings',
|
||||||
rect: new PIXI.Rectangle(environment.WindowWidth / 2 - 300 / 2, environment.WindowHeight / 2 + 20, 300, 60),
|
rect: new PIXI.Rectangle(Globals.WindowWidth / 2 - 300 / 2, Globals.WindowHeight / 2 + 20, 300, 60),
|
||||||
texture: ButtonTexture.Button01,
|
texture: ButtonTexture.Button01,
|
||||||
};
|
};
|
||||||
|
|
||||||
const button01 = new Button(NewGameButton.rect, NewGameButton.caption, NewGameButton.texture, true);
|
const button01 = new Button(NewGameButton.rect, NewGameButton.caption, NewGameButton.texture, true);
|
||||||
button01.onClick = (e) => {
|
button01.onClick = (e) => {
|
||||||
environment.GameMaster.changeScene(new MissionPickerScene());
|
Globals.GameMaster.changeScene(new MissionPickerScene());
|
||||||
};
|
};
|
||||||
|
|
||||||
new Button(SettingsButton.rect, SettingsButton.caption, SettingsButton.texture, true);
|
new Button(SettingsButton.rect, SettingsButton.caption, SettingsButton.texture, true);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Assets from '../classes/Assets';
|
import Assets from '../classes/Assets';
|
||||||
import { environment } from '../classes/Bastion';
|
import { Globals } from '../classes/Bastion';
|
||||||
import Button, { ButtonTexture } from '../classes/gui/Button';
|
import Button, { ButtonTexture } from '../classes/gui/Button';
|
||||||
import { GameScene } from './Game';
|
import { GameScene } from './Game';
|
||||||
import Scene from './Scene';
|
import Scene from './Scene';
|
||||||
@ -9,17 +9,12 @@ export class MissionPickerScene extends Scene {
|
|||||||
public init() {
|
public init() {
|
||||||
Assets.Missions.forEach((mission, index) => {
|
Assets.Missions.forEach((mission, index) => {
|
||||||
const button = new Button(
|
const button = new Button(
|
||||||
new PIXI.Rectangle(
|
new PIXI.Rectangle(Globals.WindowWidth / 2 - 300 / 2, Globals.WindowHeight / 5 + index * 80, 300, 60),
|
||||||
environment.WindowWidth / 2 - 300 / 2,
|
|
||||||
environment.WindowHeight / 5 + index * 80,
|
|
||||||
300,
|
|
||||||
60
|
|
||||||
),
|
|
||||||
mission.name,
|
mission.name,
|
||||||
ButtonTexture.Button01
|
ButtonTexture.Button01
|
||||||
);
|
);
|
||||||
button.onClick = (e) => {
|
button.onClick = (e) => {
|
||||||
environment.GameMaster.changeScene(new GameScene(mission.name));
|
Globals.GameMaster.changeScene(new GameScene(mission.name));
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ export default class Scene {
|
|||||||
public GetGuiObject(object: GuiObject) {
|
public GetGuiObject(object: GuiObject) {
|
||||||
return this.gui.find((obj) => obj == object);
|
return this.gui.find((obj) => obj == object);
|
||||||
}
|
}
|
||||||
|
public GetGuiObjectByName(name: string) {
|
||||||
|
return this.gui.filter((obj) => obj.name == name);
|
||||||
|
}
|
||||||
public init() {
|
public init() {
|
||||||
// Definitions for scene elements.
|
// Definitions for scene elements.
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user