From 64795b1ebf8278c058d214b2e32fb8e553a52d8f Mon Sep 17 00:00:00 2001 From: koneko <67551503+koneko@users.noreply.github.com> Date: Fri, 17 Jan 2025 00:29:51 +0100 Subject: [PATCH] add proper asset loading and use for towers + projectiles (also projectile animation) + add health bars --- .../gui/{frame_c3_01.png => frame_03.png} | Bin public/assets/json/Towers.json | 2 ++ public/assets/projectiles/basic_tower.png | Bin 1201 -> 0 bytes public/assets/projectiles/basic_tower/0.png | Bin 0 -> 6283 bytes public/assets/projectiles/basic_tower/1.png | Bin 0 -> 6106 bytes public/assets/projectiles/basic_tower/2.png | Bin 0 -> 5842 bytes public/assets/projectiles/basic_tower/3.png | Bin 0 -> 6232 bytes public/assets/projectiles/basic_tower/4.png | Bin 0 -> 6283 bytes src/classes/Assets.ts | 25 +++++++++----- src/classes/Definitions.ts | 4 ++- src/classes/game/Creep.ts | 19 +++++++++++ src/classes/game/Grid.ts | 15 +------- src/classes/game/Projectile.ts | 8 ++--- src/classes/game/Tower.ts | 18 ++++++---- src/classes/game/TowerManager.ts | 15 +++++--- src/classes/gui/SelectedTowerPanel.ts | 32 ++++++++++++++++++ src/classes/gui/Tooltip.ts | 30 ++++++++++++++++ src/utils.ts | 3 -- 18 files changed, 129 insertions(+), 42 deletions(-) rename public/assets/gui/{frame_c3_01.png => frame_03.png} (100%) delete mode 100644 public/assets/projectiles/basic_tower.png create mode 100644 public/assets/projectiles/basic_tower/0.png create mode 100644 public/assets/projectiles/basic_tower/1.png create mode 100644 public/assets/projectiles/basic_tower/2.png create mode 100644 public/assets/projectiles/basic_tower/3.png create mode 100644 public/assets/projectiles/basic_tower/4.png create mode 100644 src/classes/gui/SelectedTowerPanel.ts create mode 100644 src/classes/gui/Tooltip.ts delete mode 100644 src/utils.ts diff --git a/public/assets/gui/frame_c3_01.png b/public/assets/gui/frame_03.png similarity index 100% rename from public/assets/gui/frame_c3_01.png rename to public/assets/gui/frame_03.png diff --git a/public/assets/json/Towers.json b/public/assets/json/Towers.json index eac4067..f60e715 100644 --- a/public/assets/json/Towers.json +++ b/public/assets/json/Towers.json @@ -4,6 +4,8 @@ "behaviour": "BasicTowerBehaviour", "sprite": "basic_tower", "texture": null, + "projectileTextures": [], + "projectileTexturesArrayLength": 5, "description": "The building block of society, nothing more basic exists.", "stats": { "damage": 2, diff --git a/public/assets/projectiles/basic_tower.png b/public/assets/projectiles/basic_tower.png deleted file mode 100644 index 272ad5179135cffec2bd40e03c5034e986582e55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1201 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 B7)$^F literal 0 HcmV?d00001 diff --git a/public/assets/projectiles/basic_tower/1.png b/public/assets/projectiles/basic_tower/1.png new file mode 100644 index 0000000000000000000000000000000000000000..40ff7ae5731a881f2dad1145b2014bd1efc8e4aa GIT binary patch literal 6106 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 literal 0 HcmV?d00001 diff --git a/public/assets/projectiles/basic_tower/2.png b/public/assets/projectiles/basic_tower/2.png new file mode 100644 index 0000000000000000000000000000000000000000..1fe70f0cea6871e7201dfa7c5292dfb9314abb59 GIT binary patch literal 5842 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 literal 0 HcmV?d00001 diff --git a/public/assets/projectiles/basic_tower/3.png b/public/assets/projectiles/basic_tower/3.png new file mode 100644 index 0000000000000000000000000000000000000000..b5258c0c1821f17fa71db63990bb2e054a3c8807 GIT binary patch literal 6232 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 B7)$^F literal 0 HcmV?d00001 diff --git a/src/classes/Assets.ts b/src/classes/Assets.ts index 86a1189..a9a016a 100644 --- a/src/classes/Assets.ts +++ b/src/classes/Assets.ts @@ -1,14 +1,11 @@ import * as PIXI from 'pixi.js'; -import { CreepDefinition, CreepStatsDefinition, MissionDefinition, TowerDefinition } from './Definitions'; +import { CreepDefinition, MissionDefinition, TowerDefinition } from './Definitions'; import { Engine } from './Bastion'; export default class GameAssets { - public static BasicTowerTexture: PIXI.Texture; - - public static BasicProjectileTexture: PIXI.Texture; - public static Frame01Texture: PIXI.Texture; public static Frame02Texture: PIXI.Texture; + public static Frame03Texture: PIXI.Texture; public static FrameBackground: PIXI.Texture; public static FrameTowerTab: PIXI.Texture; public static VioletBackground: PIXI.Texture; @@ -29,6 +26,7 @@ export default class GameAssets { private static text; private static async Load(src) { this.text.text = 'Loading asset: ' + src; + console.log('LOADING ' + src); return await PIXI.Assets.load({ src: src, }); @@ -63,11 +61,12 @@ export default class GameAssets { this.text.y = Engine.app.canvas.height / 2 + 50; this.text.anchor.set(0.5, 0.5); Engine.app.stage.addChild(this.text); - this.Load('/aclonica.woff2'); + await this.Load('/aclonica.woff2'); this.Button01Texture = await this.Load('/assets/gui/button_01.png'); this.Button02Texture = await this.Load('/assets/gui/button_02.png'); this.Frame01Texture = await this.Load('/assets/gui/frame_01.png'); this.Frame02Texture = await this.Load('/assets/gui/frame_02.png'); + this.Frame03Texture = await this.Load('/assets/gui/frame_03.png'); this.FrameBackground = await this.Load('/assets/gui/background_01.png'); this.FrameTowerTab = await this.Load('/assets/gui/background_02.png'); this.VioletBackground = await this.Load('/assets/gui/frame_violet.png'); @@ -76,8 +75,6 @@ export default class GameAssets { this.HealthTexture = await this.Load('/assets/gui/heart.png'); this.GoldTexture = await this.Load('/assets/gui/money.png'); this.WaveTexture = await this.Load('/assets/gui/wave.png'); - this.BasicTowerTexture = await this.Load('/assets/towers/basic_tower.png'); - this.BasicProjectileTexture = await this.Load('/assets/projectiles/basic_tower.png'); await this.LoadMissions(); await this.LoadTowers(); await this.LoadCreeps(); @@ -108,7 +105,17 @@ export default class GameAssets { private static async LoadTowers() { const res = await fetch('/assets/json/Towers.json'); const towers = await res.json(); - GameAssets.Towers = towers; + this.Towers = towers; + console.log(this.Towers); + for (let idx = 0; idx < this.Towers.length; idx++) { + const tower = this.Towers[idx]; + for (let i = 0; i < tower.projectileTexturesArrayLength; i++) { + console.log(`WANT TO LOAD /assets/projectiles/${tower.sprite}/${i}.png`); + const texture = await this.Load(`/assets/projectiles/${tower.sprite}/${i}.png`); + tower.projectileTextures[i] = texture; + console.log(tower.projectileTextures); + } + } towers.forEach(async (tower) => { let index = this.TowerSprites.length - 1; if (index == -1) index = 0; diff --git a/src/classes/Definitions.ts b/src/classes/Definitions.ts index c75319d..da4701d 100644 --- a/src/classes/Definitions.ts +++ b/src/classes/Definitions.ts @@ -57,6 +57,8 @@ export type TowerDefinition = { sprite: string; description: string; texture: PIXI.Texture; + projectileTextures: PIXI.Texture[]; + projectileTexturesArrayLength: number; stats: TowerStatsDefinition; }; @@ -90,6 +92,6 @@ export enum GemType { } export enum TowerType { - Shooting = 0, + Basic = 0, Circle = 1, } diff --git a/src/classes/game/Creep.ts b/src/classes/game/Creep.ts index 78e9403..2b6e1cc 100644 --- a/src/classes/game/Creep.ts +++ b/src/classes/game/Creep.ts @@ -21,6 +21,8 @@ export default class Creep extends GameObject { private pathIndex: number = 0; private speed: number; private direction: number = 1; + private healthBarGraphics: PIXI.Graphics = new PIXI.Graphics(); + private healthBarWidth = 50; public health: number; public maxHealth: number; public escaped: boolean = false; @@ -37,6 +39,7 @@ export default class Creep extends GameObject { // Initially flip sprite to the right, since the asset is facing left. this.sprite.scale.x *= -1; this.sprite.anchor.set(0.5, 0.5); + this.sprite.animationSpeed = 0.3; this.sprite.play(); this.id = id; // Explanation: WaveManager spawns all creeps instantly, and since I don't want @@ -46,6 +49,7 @@ export default class Creep extends GameObject { this.container.y = -50; this.sprite.width = Engine.GridCellSize; this.sprite.height = Engine.GridCellSize; + this.bb.width = this.sprite.width; this.speed = this.stats.speed / 60; this.health = this.stats.health; this.maxHealth = this.stats.health; @@ -56,9 +60,24 @@ export default class Creep extends GameObject { Engine.GameScene.events.on(CreepEvents.TakenDamage, (creepID, damage) => { if (creepID != this.id) return; this.health -= damage; + this.UpdateHealthbar(); }); Engine.Grid.container.addChild(this.container); + this.container.addChild(this.healthBarGraphics); this.container.addChild(this.sprite); + this.UpdateHealthbar(); + } + private UpdateHealthbar() { + this.healthBarGraphics.clear(); + const hp = this.health; + const maxHp = this.maxHealth; + const percent = hp / maxHp; + const width = this.healthBarWidth * percent; + // ! TODO: MAKE THIS BETTER! It works like this now, but I don't like how its implemented. + this.healthBarGraphics.rect(-this.healthBarWidth / 2 + 5, -30, this.healthBarWidth, 10); + this.healthBarGraphics.fill({ color: 0x00ff00 }); + this.healthBarGraphics.rect(-this.healthBarWidth / 2 + 5, -30, width, 10); + this.healthBarGraphics.fill({ color: 0xff0000 }); } public update(elapsedMS: number) { if (this.dead) return; diff --git a/src/classes/game/Grid.ts b/src/classes/game/Grid.ts index 7959cf6..1209044 100644 --- a/src/classes/game/Grid.ts +++ b/src/classes/game/Grid.ts @@ -37,20 +37,6 @@ export class Cell extends GameObject { this.clickDetector.onpointerdown = (e) => { Engine.Grid.onGridCellClicked(row, column); }; - - // 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 (isPath) text.text += 'p'; } public gDraw() { this.g = new PIXI.Graphics({ @@ -143,5 +129,6 @@ export class Grid extends GameObject { public getCellByRowAndCol(row, column) { return this.cells.filter((item) => item.row == row && item.column == column)[0]; } + // Not defined here, rather GameScene defines it. This is just for TS. public onGridCellClicked(row, column) {} } diff --git a/src/classes/game/Projectile.ts b/src/classes/game/Projectile.ts index d36bb38..e4811ac 100644 --- a/src/classes/game/Projectile.ts +++ b/src/classes/game/Projectile.ts @@ -11,21 +11,21 @@ export function calculateAngleToPoint(x, y, targetX, targetY) { export default class Projectile extends GameObject { public deleteMe: boolean = false; - public sprite: PIXI.Sprite; + public sprite: PIXI.AnimatedSprite; public x: number; public y: number; public angle: number; public speed: number; public damage: number; public timeToLive: number = 1; - constructor(x, y, spriteTexture, angle, damage) { + constructor(x, y, textures, angle, damage) { super(); this.x = x; this.y = y; this.damage = damage; - - this.sprite = new PIXI.Sprite({ texture: spriteTexture, scale: 0.5, rotation: angle }); + this.sprite = new PIXI.AnimatedSprite({ textures: textures, scale: 0.25, rotation: angle }); this.sprite.anchor.set(0.5); + this.sprite.play(); this.container.x = this.x; this.container.y = this.y; this.container.addChild(this.sprite); diff --git a/src/classes/game/Tower.ts b/src/classes/game/Tower.ts index 971d2a5..d2506d8 100644 --- a/src/classes/game/Tower.ts +++ b/src/classes/game/Tower.ts @@ -57,17 +57,21 @@ export class Tower extends GameObject { this.container.addChild(this.sprite); parent.container.addChild(this.container); parent.clickDetector.onmouseenter = (e) => { - this.graphics.circle( - this.column * Engine.GridCellSize + Engine.GridCellSize / 2, - this.row * Engine.GridCellSize + Engine.GridCellSize / 2, - this.definition.stats.range * Engine.GridCellSize - ); - this.graphics.fill({ color: 0xff0000, alpha: 0.5 }); + this.showRangeDisplay(); }; parent.clickDetector.onmouseleave = (e) => { this.graphics.clear(); }; Engine.GameMaster.currentScene.stage.addChild(this.graphics); + this.showRangeDisplay(); + } + public showRangeDisplay() { + this.graphics.circle( + this.column * Engine.GridCellSize + Engine.GridCellSize / 2, + this.row * Engine.GridCellSize + Engine.GridCellSize / 2, + this.definition.stats.range * Engine.GridCellSize + ); + this.graphics.fill({ color: 0xff0000, alpha: 0.5 }); } public GetCreepsInRange() { let creeps = Engine.Grid.creeps; @@ -86,7 +90,7 @@ export class Tower extends GameObject { let y = this.row * Engine.GridCellSize + Engine.GridCellSize / 2; let angle = calculateAngleToPoint(x, y, creep.x, creep.y); this.projectiles.push( - new Projectile(x, y, GameAssets.BasicProjectileTexture, angle, this.definition.stats.damage) + new Projectile(x, y, this.definition.projectileTextures, angle, this.definition.stats.damage) ); } public update(elapsedMS: any): void { diff --git a/src/classes/game/TowerManager.ts b/src/classes/game/TowerManager.ts index afc8d28..e4fcd73 100644 --- a/src/classes/game/TowerManager.ts +++ b/src/classes/game/TowerManager.ts @@ -2,8 +2,8 @@ import * as PIXI from 'pixi.js'; import { Engine } from '../Bastion'; import { TerrainType, TowerDefinition } from '../Definitions'; import GameAssets from '../Assets'; -import GameObject from '../GameObject'; import { Tower, TowerEvents } from './Tower'; +import { Cell } from './Grid'; export enum TowerBehaviours { BasicTowerBehaviour = 'BasicTowerBehaviour', @@ -34,8 +34,13 @@ export default class TowerManager { public PlayerClickOnGrid(row, column) { if (!this.canPlaceTowers) return; if (this.isPlacingTower) { - if (!this.selectedTower) + if (!this.selectedTower) { + Engine.NotificationManager.Notify( + 'TowerManager.selectedTower is null when trying to place tower.', + 'danger' + ); throw console.warn('TowerManager.selectedTower is null when trying to place tower.'); + } this.PlaceTower(this.selectedTower, row, column, this.selectedTower.behaviour); } } @@ -65,11 +70,13 @@ export default class TowerManager { let tower = new Tower(row, column, sprite, definition, behaviour); this.towers.push(tower); this.ToggleChoosingTowerLocation('RESET'); - console.log('SHOULDVE PLACED TOWER'); - console.log(this.selectedTower); this.selectedTower = null; Engine.GameScene.events.emit(TowerEvents.TowerPlacedEvent, definition.name); } else { + Engine.NotificationManager.Notify( + 'Can not place tower on path or other tower, choose another spot.', + 'warn' + ); console.warn('Can not place tower on occupied spot or path. Try again.'); } } diff --git a/src/classes/gui/SelectedTowerPanel.ts b/src/classes/gui/SelectedTowerPanel.ts new file mode 100644 index 0000000..322f407 --- /dev/null +++ b/src/classes/gui/SelectedTowerPanel.ts @@ -0,0 +1,32 @@ +import * as PIXI from 'pixi.js'; +import GuiObject from '../GuiObject'; +import GameAssets from '../Assets'; +import { Engine } from '../Bastion'; + +// ! TODO NEXT! + +export default class SelectedTowerPanel extends GuiObject { + private bounds: PIXI.Rectangle; + private towerPanel: PIXI.NineSliceSprite; + + constructor(bounds: PIXI.Rectangle) { + super(false); + this.bounds = bounds; + this.container.x = this.bounds.x; + this.container.y = this.bounds.y; + this.towerPanel = new PIXI.NineSliceSprite({ + texture: GameAssets.FrameTowerTab, + leftWidth: 1000, + topHeight: 1000, + rightWidth: 1000, + bottomHeight: 1000, + }); + this.towerPanel.x = -300; + this.towerPanel.y = -300; + this.towerPanel.width = this.bounds.width; + this.towerPanel.height = this.bounds.height; + + this.container.addChild(this.towerPanel); + Engine.GameMaster.currentScene.stage.addChild(this.container); + } +} diff --git a/src/classes/gui/Tooltip.ts b/src/classes/gui/Tooltip.ts new file mode 100644 index 0000000..28cdb15 --- /dev/null +++ b/src/classes/gui/Tooltip.ts @@ -0,0 +1,30 @@ +import * as PIXI from 'pixi.js'; +import GuiObject from '../GuiObject'; +import GameAssets from '../Assets'; + +// ! TODO NEXT! + +export default class Tooltip extends GuiObject { + private bounds: PIXI.Rectangle; + private tooltipSprite: PIXI.NineSliceSprite; + + constructor(bounds: PIXI.Rectangle) { + super(false); + this.bounds = bounds; + this.container.x = this.bounds.x; + this.container.y = this.bounds.y; + this.tooltipSprite = new PIXI.NineSliceSprite({ + texture: GameAssets.FrameTowerTab, + leftWidth: 1000, + topHeight: 1000, + rightWidth: 1000, + bottomHeight: 1000, + }); + this.tooltipSprite.x = 0; + this.tooltipSprite.y = 0; + this.tooltipSprite.width = this.bounds.width; + this.tooltipSprite.height = this.bounds.height; + + this.container.addChild(this.tooltipSprite); + } +} diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index c604173..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function log(msg: any) { - console.log(msg); -}