Merge pull request #2 from koneko/egocentric

Egocentric
This commit is contained in:
Koneko 2024-11-05 15:33:56 +01:00 committed by GitHub
commit d984fb1092
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 145 additions and 27 deletions

12
public/assets/Towers.json Normal file
View File

@ -0,0 +1,12 @@
[
{
"name": "Basic Tower",
"stats": {
"damage": 2,
"cooldown": 2,
"gemSlotsAmount": 2,
"cost": 100,
"range": 7
}
}
]

0
public/assets/gui/button_02.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

BIN
public/assets/gui/frame.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
public/assets/gui/heart.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
public/assets/gui/shield.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
public/assets/gui/star.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
public/assets/gui/star_empty.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
public/assets/gui/sword_01.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
public/assets/gui/sword_02.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -1,5 +1,5 @@
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
import { CreepStats, MissionDefinition } from './Definitions'; import { CreepStatsDefinition, MissionDefinition, TowerDefinition } from './Definitions';
export default class Assets { export default class Assets {
public static async LoadAssets() { public static async LoadAssets() {
@ -7,11 +7,20 @@ export default class Assets {
Assets.ButtonTexture = await PIXI.Assets.load({ Assets.ButtonTexture = await PIXI.Assets.load({
src: '/assets/gui/button_02.png', src: '/assets/gui/button_02.png',
}); });
Assets.SidebarTexture = await PIXI.Assets.load({
src: '/assets/gui/frame.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({ Assets.BasicCreepTexture = await PIXI.Assets.load({
src: '/assets/creeps/basic.jpg', src: '/assets/creeps/basic.jpg',
}); });
console.log('Loading Missions');
await this.LoadMissions(); await this.LoadMissions();
await this.LoadTowers();
await this.LoadCreepStats(); await this.LoadCreepStats();
} }
@ -25,6 +34,12 @@ export default class Assets {
Assets.Missions = [await this.LoadMission('/assets/missions/mission_01.json')]; 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) { private static async LoadMission(missionUrl: string) {
const res = await fetch(missionUrl); const res = await fetch(missionUrl);
const mission = await res.json(); const mission = await res.json();
@ -40,10 +55,16 @@ export default class Assets {
}); });
} }
public static ButtonTexture: PIXI.Texture;
public static BasicCreepTexture: PIXI.Texture; public static BasicCreepTexture: PIXI.Texture;
public static ButtonTexture: PIXI.Texture;
public static SidebarTexture: PIXI.Texture;
public static HealthTexture: PIXI.Texture;
public static GoldTexture: PIXI.Texture;
public static MissionBackgrounds: PIXI.Texture[] = []; public static MissionBackgrounds: PIXI.Texture[] = [];
public static Missions: MissionDefinition[]; public static Missions: MissionDefinition[];
public static CreepStats: CreepStats[]; public static Towers: TowerDefinition[];
public static CreepStats: CreepStatsDefinition[];
public static DebuggingEnabled: boolean = true;
} }

View File

@ -30,14 +30,14 @@ export type WaveDefinition = {
creeps: CreepType[]; creeps: CreepType[];
}; };
export type CreepStats = { export type CreepStatsDefinition = {
health: number; health: number;
speed: number; speed: number;
special: Function; special: Function;
resistance: CreepResistances; resistance: CreepResistancesDefinition;
}; };
export type CreepResistances = { export type CreepResistancesDefinition = {
physical: number; physical: number;
divine: number; divine: number;
fire: number; fire: number;
@ -45,6 +45,19 @@ export type CreepResistances = {
frostfire: 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 type PathDefinition = [[row: number, column: number]];
export enum CreepType { export enum CreepType {
@ -64,3 +77,8 @@ export enum GemType {
Titalium = 2, Titalium = 2,
Soulforge = 3, Soulforge = 3,
} }
export enum TowerType {
Shooting = 0,
Circle = 1,
}

View File

@ -1,5 +1,5 @@
import Assets from '../base/Assets'; import Assets from '../base/Assets';
import { CreepStats, CreepType, PathDefinition } from '../base/Definitions'; import { CreepStatsDefinition, CreepType, PathDefinition } from '../base/Definitions';
import GameObject from '../base/GameObject'; import GameObject from '../base/GameObject';
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
import GameScene from '../scenes/GameScene'; import GameScene from '../scenes/GameScene';
@ -14,7 +14,7 @@ export enum CreepEvents {
export default class Creep extends GameObject { export default class Creep extends GameObject {
public creepType: CreepType; public creepType: CreepType;
private path: PathDefinition; private path: PathDefinition;
private stats: CreepStats; private stats: CreepStatsDefinition;
private pathIndex: number = 0; private pathIndex: number = 0;
private speed: number; private speed: number;
private gameScene: GameScene; private gameScene: GameScene;

View File

@ -40,7 +40,7 @@ export class Cell extends GameObject {
this.container.addChild(g); this.container.addChild(g);
this.container.x = this.bounds.x; this.container.x = this.bounds.x;
this.container.y = this.bounds.y; this.container.y = this.bounds.y;
return; // comment to enable debugging if (!Assets.DebuggingEnabled) return;
const text = new PIXI.Text({ const text = new PIXI.Text({
text: `${this.row}|${this.column}`, text: `${this.row}|${this.column}`,
style: new PIXI.TextStyle({ style: new PIXI.TextStyle({
@ -101,10 +101,6 @@ export class Grid extends GameObject {
protected draw() { protected draw() {
console.log('Drawing Grid', this.bounds); console.log('Drawing Grid', this.bounds);
this.container.removeChildren(); this.container.removeChildren();
// let g = new PIXI.Graphics();
// g.rect(0, 0, this.bounds.width, this.bounds.height + 100);
// g.fill(0xffffff);
// this.container.addChild(g);
let background = new PIXI.Sprite(Assets.MissionBackgrounds[this.gameScene.missionIndex]); let background = new PIXI.Sprite(Assets.MissionBackgrounds[this.gameScene.missionIndex]);
background.x = 0; background.x = 0;
background.y = 0; background.y = 0;
@ -113,8 +109,8 @@ export class Grid extends GameObject {
this.container.addChild(background); this.container.addChild(background);
for (let cell of this.cells) { for (let cell of this.cells) {
cell.setBounds( cell.setBounds(
this.gridUnitsToPixels(cell.column), parseFloat(this.gridUnitsToPixels(cell.column).toFixed(2)),
this.gridUnitsToPixels(cell.row), parseFloat(this.gridUnitsToPixels(cell.row).toFixed(2)),
this.gridUnitsToPixels(1), this.gridUnitsToPixels(1),
this.gridUnitsToPixels(1) this.gridUnitsToPixels(1)
); );

View File

@ -1,3 +1,4 @@
import Assets from '../base/Assets';
import GameObject from '../base/GameObject'; import GameObject from '../base/GameObject';
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
@ -33,18 +34,55 @@ export default class MissionStats extends GameObject {
protected draw() { protected draw() {
this.container.removeChildren(); this.container.removeChildren();
const g = new PIXI.Graphics(); const sprite = new PIXI.NineSliceSprite({
g.rect(0, 0, this.bounds.width, this.bounds.height); texture: Assets.SidebarTexture,
g.fill(0x000000); leftWidth: 100,
this.container.addChild(g); topHeight: 100,
const text = new PIXI.Text({ rightWidth: 100,
text: `HP: ${this.hp}\nGold: ${this.gold}`, 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({ style: new PIXI.TextStyle({
fill: 'white', fill: 'white',
fontSize: 24, fontSize: 24,
fontWeight: 'bold',
dropShadow: true,
}), }),
}); });
this.container.addChild(text); 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.x = this.bounds.x;
this.container.y = this.bounds.y; this.container.y = this.bounds.y;
} }

27
src/components/Sidebar.ts Normal file
View File

@ -0,0 +1,27 @@
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;
}
}

View File

@ -3,6 +3,7 @@ import { MissionDefinition } from '../base/Definitions';
import Creep, { CreepEvents } from '../components/Creep'; import Creep, { CreepEvents } from '../components/Creep';
import { Grid } from '../components/Grid'; import { Grid } from '../components/Grid';
import MissionStats from '../components/MissionStats'; import MissionStats from '../components/MissionStats';
import Sidebar from '../components/Sidebar';
import WaveManager, { WaveManagerEvents } from '../components/WaveManager'; import WaveManager, { WaveManagerEvents } from '../components/WaveManager';
import SceneBase from './SceneBase'; import SceneBase from './SceneBase';
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
@ -17,6 +18,7 @@ export default class GameScene extends SceneBase {
private ticker: PIXI.Ticker; private ticker: PIXI.Ticker;
private stats: MissionStats; private stats: MissionStats;
private waveManager: WaveManager; private waveManager: WaveManager;
private sidebar: Sidebar;
private roundMode = RoundMode.Purchase; private roundMode = RoundMode.Purchase;
private changeRoundButton: Button; private changeRoundButton: Button;
private currentRound: number = 0; private currentRound: number = 0;
@ -36,6 +38,7 @@ export default class GameScene extends SceneBase {
}); });
this.stats = new MissionStats(100, 200); this.stats = new MissionStats(100, 200);
this.grid = new Grid(mission.gameMap, this); this.grid = new Grid(mission.gameMap, this);
this.sidebar = new Sidebar(this);
this.gridWidth = mission.mapImage.width; this.gridWidth = mission.mapImage.width;
this.gridHeight = mission.mapImage.height; this.gridHeight = mission.mapImage.height;
this.ticker = new PIXI.Ticker(); this.ticker = new PIXI.Ticker();
@ -108,7 +111,9 @@ export default class GameScene extends SceneBase {
this.container.addChild(g); this.container.addChild(g);
this.stats.setBounds(this.getStatusBounds()); this.stats.setBounds(this.getStatusBounds());
this.grid.setBounds(this.getGridBounds()); this.grid.setBounds(this.getGridBounds());
this.sidebar.setBounds(this.getSidebarBounds());
this.changeRoundButton.setBounds(this.getChangeRoundButtonBounds()); this.changeRoundButton.setBounds(this.getChangeRoundButtonBounds());
this.container.addChild(this.sidebar.container);
this.container.addChild(this.stats.container); this.container.addChild(this.stats.container);
this.container.addChild(this.grid.container); this.container.addChild(this.grid.container);
this.container.addChild(this.changeRoundButton.container); this.container.addChild(this.changeRoundButton.container);
@ -116,15 +121,16 @@ export default class GameScene extends SceneBase {
this.container.y = this.bounds.y; this.container.y = this.bounds.y;
} }
private getSidebarBounds(): PIXI.Rectangle {
return new PIXI.Rectangle(this.bounds.width - 350, 0, 350, this.bounds.height);
}
private getStatusBounds(): PIXI.Rectangle { private getStatusBounds(): PIXI.Rectangle {
// Top / Center // Top / Center
return new PIXI.Rectangle(this.bounds.width / 2 - 200 / 2, 0, 200, 100); return new PIXI.Rectangle(0, 0, this.bounds.width, 100);
} }
private getGridBounds(): PIXI.Rectangle { private getGridBounds(): PIXI.Rectangle {
// Center / Center // Center / Center
let width = 600;
let height = 600;
return new PIXI.Rectangle( return new PIXI.Rectangle(
this.bounds.width / 2 - this.gridWidth / 2, this.bounds.width / 2 - this.gridWidth / 2,
this.bounds.height / 2 - this.gridHeight / 2, this.bounds.height / 2 - this.gridHeight / 2,
@ -134,7 +140,7 @@ export default class GameScene extends SceneBase {
} }
private getChangeRoundButtonBounds(): PIXI.Rectangle { private getChangeRoundButtonBounds(): PIXI.Rectangle {
// Center / Center // Center / Center
let width = 300; let width = 350;
let height = 150; let height = 150;
return new PIXI.Rectangle(this.bounds.width - width, this.bounds.height - height, width, height); return new PIXI.Rectangle(this.bounds.width - width, this.bounds.height - height, width, height);
} }