diff --git a/public/assets/Towers.json b/public/assets/Towers.json index 58b6fea..853ad1c 100644 --- a/public/assets/Towers.json +++ b/public/assets/Towers.json @@ -8,7 +8,7 @@ "cooldown": 2, "gemSlotsAmount": 2, "cost": 100, - "range": 7 + "range": 3 } } ] diff --git a/src/classes/game/Grid.ts b/src/classes/game/Grid.ts index 4ca283c..0f80765 100644 --- a/src/classes/game/Grid.ts +++ b/src/classes/game/Grid.ts @@ -11,7 +11,7 @@ export class Cell extends GameObject { public column: number; public isPath: boolean = false; private g: PIXI.Graphics; - private clickDetector: PIXI.Graphics; + public clickDetector: PIXI.Graphics; constructor(type: TerrainType, row: number, column: number, isPath: boolean) { super(); diff --git a/src/classes/game/MissionStats.ts b/src/classes/game/MissionStats.ts index 84af64e..265ba58 100644 --- a/src/classes/game/MissionStats.ts +++ b/src/classes/game/MissionStats.ts @@ -13,6 +13,10 @@ export default class MissionStats extends GameObject { return this.hp; } + public hasEnoughGold(amount) { + return amount <= this.gold; + } + public setHP(hp: number) { this.hp = hp; this.healthText.text = this.hp; @@ -28,6 +32,16 @@ export default class MissionStats extends GameObject { this.goldText.text = this.gold; } + public earnGold(gold: number) { + this.gold += gold; + this.goldText.text = this.gold; + } + + public spendGold(amount: number) { + this.gold -= amount; + this.goldText.text = this.gold; + } + constructor(initialHP: number, initialGold: number) { super(); this.hp = initialHP; diff --git a/src/classes/game/Tower.ts b/src/classes/game/Tower.ts new file mode 100644 index 0000000..840a9aa --- /dev/null +++ b/src/classes/game/Tower.ts @@ -0,0 +1,90 @@ +import { Globals } from '../Bastion'; +import * as PIXI from 'pixi.js'; +import GameObject from '../GameObject'; +import { TowerDefinition } from '../Definitions'; +import { Cell } from './Grid'; + +function distance(x1, y1, x2, y2) { + return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); +} + +export type TowerInstance = { + row: number; + column: number; + sprite: PIXI.Sprite; + projectiles: Array; + baseDamage: number; + damage: number; + cooldown: number; + ticksToFireAt: number; + slottedGems: Array; + cost: number; + baseRange: number; + range: number; +}; + +export enum TowerEvents { + TowerPlacedEvent = 'towerPlacedEvent', +} + +export class Tower extends GameObject { + public row: number; + public column: number; + private definition: TowerDefinition; + private sprite: PIXI.Sprite; + private antiLag = 0; + private debugGraphics: PIXI.Graphics = new PIXI.Graphics(); + private dbgtxt: any; + constructor(row, column, texture, definition) { + super(); + this.row = row; + this.column = column; + this.definition = definition; + let parent: Cell = Globals.Grid.getCellByRowAndCol(row, column); + this.sprite = new PIXI.Sprite({ + texture: texture, + height: 64, + width: 64, + zIndex: 10, + }); + this.dbgtxt = new PIXI.Text({ + text: 'instantiating', + x: 0, + y: -20, + style: { + fill: 0x0ff00f, + }, + }); + this.container.addChild(this.sprite); + this.container.addChild(this.dbgtxt); + parent.container.addChild(this.container); + parent.clickDetector.onmouseenter = (e) => { + this.debugGraphics.circle(this.column * 64 + 32, this.row * 64 + 32, this.definition.stats.range * 64); + this.debugGraphics.fill({ color: 0xff0000, alpha: 0.5 }); + }; + parent.clickDetector.onmouseleave = (e) => { + this.debugGraphics.clear(); + }; + Globals.app.stage.addChild(this.debugGraphics); + } + public GetCreepsInRange() { + let creeps = Globals.Grid.creeps; + return creeps.filter((creep) => { + const x = creep.x; + const y = creep.y; + const towerX = this.column * 64 + 32; + const towerY = this.row * 64 + 32; + const radius = this.definition.stats.range * 64; + const d = distance(towerX, towerY, x, y); + return d < radius; + }); + } + public update(elapsedMS: any): void { + if (this.antiLag >= 10) { + this.antiLag = 0; + let inrange = this.GetCreepsInRange().length; + this.dbgtxt.text = inrange; + } + this.antiLag++; + } +} diff --git a/src/classes/game/TowerManager.ts b/src/classes/game/TowerManager.ts index 47fab18..0e39940 100644 --- a/src/classes/game/TowerManager.ts +++ b/src/classes/game/TowerManager.ts @@ -3,50 +3,7 @@ import { Globals } from '../Bastion'; import { TowerDefinition } from '../Definitions'; import GameAssets from '../Assets'; import GameObject from '../GameObject'; - -export type TowerInstance = { - row: number; - column: number; - sprite: PIXI.Sprite; - projectiles: Array; - baseDamage: number; - damage: number; - cooldown: number; - ticksToFireAt: number; - slottedGems: Array; - cost: number; - baseRange: number; - range: number; -}; - -export enum TowerEvents { - TowerPlacedEvent = 'towerPlacedEvent', -} - -enum TowerSprite { - basic_tower = 'GameAssets.BasicTowerTexture', -} - -class Tower extends GameObject { - public row: number; - public column: number; - private sprite: PIXI.Sprite; - constructor(row, column, texture, definition) { - super(); - this.row = row; - this.column = column; - let parent = Globals.Grid.getCellByRowAndCol(row, column); - this.sprite = new PIXI.Sprite({ - texture: texture, - height: 64, - width: 64, - zIndex: 10, - }); - this.container.addChild(this.sprite); - parent.container.addChild(this.container); - } - public update(elapsedMS: any): void {} -} +import { Tower, TowerEvents } from './Tower'; export default class TowerManager { public isPlacingTower: boolean = false; @@ -73,7 +30,8 @@ export default class TowerManager { public PlayerClickOnGrid(row, column) { if (!this.canPlaceTowers) return; if (this.isPlacingTower) { - if (!this.selectedTower) throw console.warn('TowerManager.selectedTower is null.'); + if (!this.selectedTower) + throw console.warn('TowerManager.selectedTower is null when trying to place tower.'); this.PlaceTower(this.selectedTower, row, column); } } @@ -86,13 +44,16 @@ export default class TowerManager { }); return returnTower; } - public PlaceTower(definition: TowerDefinition, row, column) { + public PlaceTower(definition: TowerDefinition, row, column, ignoreCost?) { let idx = 0; GameAssets.Towers.forEach((item, index) => { if (item.sprite == definition.sprite) idx = index; }); const sprite = GameAssets.TowerSprites[idx]; + if (!Globals.GameScene.MissionStats.hasEnoughGold(definition.stats.cost) && !ignoreCost) + return console.warn('Does not have enough gold.'); if (!this.GetTowerByRowAndCol(row, column) && !Globals.Grid.getCellByRowAndCol(row, column).isPath) { + Globals.GameScene.MissionStats.spendGold(definition.stats.cost); let tower = new Tower(row, column, sprite, definition); this.towers.push(tower); this.ToggleChoosingTowerLocation('RESET'); @@ -104,4 +65,9 @@ export default class TowerManager { console.warn('Can not place tower on occupied spot or path. Try again.'); } } + public update(elapsedMS) { + this.towers.forEach((twr) => { + twr.update(elapsedMS); + }); + } } diff --git a/src/classes/gui/TowerTab.ts b/src/classes/gui/TowerTab.ts index dddf481..8513d79 100644 --- a/src/classes/gui/TowerTab.ts +++ b/src/classes/gui/TowerTab.ts @@ -2,7 +2,7 @@ import * as PIXI from 'pixi.js'; import GuiObject from '../GuiObject'; import GameAssets from '../Assets'; import { Globals } from '../Bastion'; -import { TowerEvents } from '../game/TowerManager'; +import { TowerEvents } from '../game/Tower'; class TowerButton extends GuiObject { private frameSprite: PIXI.NineSliceSprite; diff --git a/src/scenes/Game.ts b/src/scenes/Game.ts index cafb9fb..0a58e40 100644 --- a/src/scenes/Game.ts +++ b/src/scenes/Game.ts @@ -9,7 +9,7 @@ import Button, { ButtonTexture } from '../classes/gui/Button'; import Scene from './Scene'; import * as PIXI from 'pixi.js'; import MissionStats from '../classes/game/MissionStats'; -import TowerManager, { TowerEvents } from '../classes/game/TowerManager'; +import TowerManager from '../classes/game/TowerManager'; enum RoundMode { Purchase = 0, @@ -74,6 +74,7 @@ export class GameScene extends Scene { public update(elapsedMS) { Globals.WaveManager.update(elapsedMS); Globals.Grid.update(elapsedMS); + Globals.TowerManager.update(elapsedMS); } public onCreepEscaped(creep: Creep) {