124 lines
4.3 KiB
TypeScript
124 lines
4.3 KiB
TypeScript
import { Engine } from '../Bastion';
|
|
import * as PIXI from 'pixi.js';
|
|
import GameObject from '../GameObject';
|
|
import { TowerDefinition } from '../Definitions';
|
|
import { Cell } from './Grid';
|
|
import { TowerBehaviours } from './TowerManager';
|
|
import Projectile, { calculateAngleToPoint } from './Projectile';
|
|
import GameAssets from '../Assets';
|
|
import Creep from './Creep';
|
|
|
|
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<any>;
|
|
baseDamage: number;
|
|
damage: number;
|
|
cooldown: number;
|
|
ticksToFireAt: number;
|
|
slottedGems: Array<any>;
|
|
cost: number;
|
|
baseRange: number;
|
|
range: number;
|
|
};
|
|
|
|
export enum TowerEvents {
|
|
TowerPlacedEvent = 'towerPlacedEvent',
|
|
TowerSoldEvent = 'towerSoldEvent',
|
|
}
|
|
|
|
export class Tower extends GameObject {
|
|
public row: number;
|
|
public column: number;
|
|
private projectiles: Projectile[] = [];
|
|
private behaviour: string;
|
|
private definition: TowerDefinition;
|
|
private sprite: PIXI.Sprite;
|
|
private ticksUntilNextShot: number;
|
|
private graphics: PIXI.Graphics = new PIXI.Graphics();
|
|
private parent: Cell;
|
|
|
|
constructor(row, column, texture, definition, behaviour) {
|
|
super();
|
|
this.row = row;
|
|
this.column = column;
|
|
this.behaviour = behaviour;
|
|
this.definition = definition;
|
|
this.ticksUntilNextShot = 0;
|
|
this.parent = Engine.Grid.getCellByRowAndCol(row, column);
|
|
console.log(texture);
|
|
this.sprite = new PIXI.Sprite({
|
|
texture: texture,
|
|
height: Engine.GridCellSize,
|
|
width: Engine.GridCellSize,
|
|
zIndex: 10,
|
|
});
|
|
this.container.addChild(this.sprite);
|
|
this.parent.container.addChild(this.container);
|
|
this.container.interactiveChildren = true;
|
|
this.parent.clickDetector.on('pointerenter', this.onParentCellEnter);
|
|
this.parent.clickDetector.on('pointerleave', this.onParentCellLeave);
|
|
Engine.GameMaster.currentScene.stage.addChild(this.graphics);
|
|
}
|
|
|
|
private onParentCellEnter = (e) => {
|
|
if (!Engine.TowerManager.isPlacingTower) this.parent.showRangePreview(false, this.definition.stats.range);
|
|
};
|
|
|
|
private onParentCellLeave = (e) => {
|
|
this.graphics.clear();
|
|
};
|
|
|
|
public GetCreepsInRange() {
|
|
let creeps = Engine.Grid.creeps;
|
|
return creeps.filter((creep) => {
|
|
const x = creep.x;
|
|
const y = creep.y;
|
|
const towerX = this.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
|
const towerY = this.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
|
const radius = this.definition.stats.range * Engine.GridCellSize;
|
|
const d = distance(towerX, towerY, x, y);
|
|
return d < radius + (Engine.GridCellSize * 2) / 3;
|
|
});
|
|
}
|
|
public Shoot(creep: Creep) {
|
|
let x = this.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
|
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, this.definition.projectileTextures, angle, this.definition.stats.damage)
|
|
);
|
|
}
|
|
public update(elapsedMS: any): void {
|
|
this.projectiles.forEach((proj) => {
|
|
if (proj.deleteMe) {
|
|
this.projectiles.splice(this.projectiles.indexOf(proj), 1);
|
|
proj = null;
|
|
} else proj.update(elapsedMS);
|
|
});
|
|
if (this.behaviour == TowerBehaviours.BasicTowerBehaviour) {
|
|
if (this.ticksUntilNextShot > 0) this.ticksUntilNextShot--;
|
|
let creepsInRange = this.GetCreepsInRange();
|
|
if (creepsInRange.length > 0) {
|
|
let focus = creepsInRange[0];
|
|
if (this.ticksUntilNextShot == 0) {
|
|
this.ticksUntilNextShot = this.definition.stats.cooldown;
|
|
this.Shoot(focus);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
override destroy(): void {
|
|
super.destroy();
|
|
this.parent.clickDetector.off('pointerenter', this.onParentCellEnter);
|
|
this.parent.clickDetector.off('pointerleave', this.onParentCellLeave);
|
|
this.graphics.destroy();
|
|
}
|
|
}
|