implement electric tower and buff tower

This commit is contained in:
koneko 2025-02-16 23:15:46 +01:00
parent 9c053ece61
commit f84108847b
18 changed files with 241 additions and 75 deletions

View File

@ -57,9 +57,9 @@
}
},
{
"name": "Quick Tower",
"behaviour": "QuickTowerBehaviour",
"sprite": "quick_tower",
"name": "Buff Tower",
"behaviour": "BuffTowerBehaviour",
"sprite": "buff_tower",
"texture": null,
"projectile": "blue",
"projectileTextures": [],
@ -133,9 +133,9 @@
}
},
{
"name": "Advanced Tower",
"behaviour": "AdvancedTowerBehaviour",
"sprite": "advanced_tower",
"name": "Debuff Tower",
"behaviour": "DebuffTowerBehaviour",
"sprite": "debuff_tower",
"texture": null,
"projectile": "red",
"projectileTextures": [],

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -28,6 +28,7 @@ export default class GameAssets {
public static TitleTexture: PIXI.Texture;
public static BannerGemsmith: PIXI.Texture;
public static EndScreenDialog: PIXI.Texture;
public static SpecialLightning: PIXI.Texture[] = [];
public static Tutorial01: PIXI.Texture;
public static Tutorial02: PIXI.Texture;
@ -193,6 +194,9 @@ export default class GameAssets {
}
tower.texture = await this.Load(`./assets/towers/${tower.sprite}.png`);
}
for (let idx = 0; idx < 4; idx++) {
this.SpecialLightning[idx] = await this.Load(`./assets/projectiles/lightning/${idx}.png`);
}
}
private static async LoadMission(missionUrl: string) {

View File

@ -9,6 +9,8 @@ import { AnimationManager } from './game/AnimationManager';
import NotificationManager from './game/NotificationManager';
import Gem from './game/Gem';
import GameAssets from './Assets';
import { TowerType } from './Definitions';
import DebrisManager from './game/DebrisManager';
export class Engine {
public static app: PIXI.Application;
@ -18,6 +20,7 @@ export class Engine {
public static TowerManager: TowerManager;
public static AnimationManager: AnimationManager;
public static NotificationManager: NotificationManager;
public static DebrisManager: DebrisManager;
public static GameScene: GameScene;
public static latestCommit: string;
public static latestGemId = 0;
@ -32,7 +35,7 @@ export class Engine {
let params = new URLSearchParams(location.href);
if (params.entries().next().value[1] != 'game') return;
Engine.NotificationManager.Notify('Loaded testing suite.', 'danger');
let tower = GameAssets.Towers[0];
let tower = GameAssets.Towers[TowerType.Electric];
Engine.TowerManager.ToggleChoosingTowerLocation('RESET');
Engine.TowerManager.PlaceTower(tower, 6, 10, tower.behaviour, true);
for (let i = 0; i < 29; i++) {

View File

@ -125,9 +125,9 @@ export enum TowerType {
Basic = 0,
Circle = 1,
Electric = 2,
Quick = 3,
Buff = 3,
Strong = 4,
Rail = 5,
Trapper = 6,
Advanced = 7,
Debuff = 7,
}

View File

@ -0,0 +1,41 @@
import GameObject from '../GameObject';
import { Container } from 'pixi.js';
class Debris {
public ticksToDestroyAt: number;
private debris: Container | GameObject;
constructor(debris: Container | GameObject, ticksToDestroyAt) {
this.debris = debris;
this.ticksToDestroyAt = ticksToDestroyAt;
}
public destroy() {
this.debris.destroy();
}
public update(elapsedMS) {
console.log(this.debris instanceof GameObject);
if (this.debris instanceof GameObject) {
this.debris.update(elapsedMS);
}
}
}
export default class DebrisManager extends GameObject {
private ticks: number = 0;
private debris: Debris[] = [];
public update(elapsedMS) {
this.ticks++;
for (let idx = this.debris.length - 1; idx >= 0; idx--) {
const db = this.debris[idx];
if (this.ticks >= db.ticksToDestroyAt) {
db.destroy();
this.debris.splice(idx, 1);
} else {
db.update(elapsedMS);
}
}
}
public CreateDebris(affectedObject: Container | GameObject, ticksToDestroyAt?: number) {
if (!ticksToDestroyAt) ticksToDestroyAt = 120;
this.debris.push(new Debris(affectedObject, this.ticks + ticksToDestroyAt));
}
}

View File

@ -1,10 +1,11 @@
import * as PIXI from 'pixi.js';
import GameObject from '../GameObject';
import { GameMapDefinition, TerrainType } from '../Definitions';
import { GameMapDefinition, TerrainType, TowerType } from '../Definitions';
import GameAssets from '../Assets';
import { Engine } from '../Bastion';
import Creep from './Creep';
import { CreepEvents, TowerEvents, GridEvents } from '../Events';
import { distance, Tower } from './Tower';
let genPath = [];
@ -15,6 +16,7 @@ export class Cell extends GameObject {
public isPath: boolean = false;
public g: PIXI.Graphics;
public hasTowerPlaced: boolean = false;
public isBuffedBy: Tower[] = [];
public clickDetector: PIXI.Graphics;
constructor(type: TerrainType, row: number, column: number, isPath: boolean) {
@ -55,19 +57,32 @@ export class Cell extends GameObject {
this.clickDetector.on('pointerleave', (e) => {
if (!Engine.Grid.gridInteractionEnabled || Engine.GameScene.towerPanel.isShown) return;
Engine.GameScene.events.emit(GridEvents.CellMouseLeave, this);
Engine.Grid.rangePreview.clear();
});
Engine.GameScene.events.on(TowerEvents.TowerPlacedEvent, (_, row, col) => {
Engine.GameScene.events.on(TowerEvents.TowerPlacedEvent, (towerName, row, col) => {
if (row == this.row && col == this.column) {
this.hasTowerPlaced = true;
Engine.Grid.rangePreview.clear();
} else if (towerName == GameAssets.Towers[TowerType.Buff].name) {
let twr = Engine.TowerManager.GetTowerByRowAndCol(row, col);
if (Engine.Grid.IsCellInRangeOfOtherCell(row, col, twr.computedRange, this)) {
this.isBuffedBy.push(twr);
}
}
});
Engine.GameScene.events.on(TowerEvents.TowerSoldEvent, (_, row, col) => {
Engine.GameScene.events.on(TowerEvents.TowerSoldEvent, (towerName, row, col) => {
console.log(towerName, row, col);
if (row == this.row && col == this.column) {
this.hasTowerPlaced = false;
Engine.Grid.rangePreview.clear();
} else if (towerName == GameAssets.Towers[TowerType.Buff].name) {
console.log('TRIpped!');
let twr = Engine.TowerManager.GetTowerByRowAndCol(row, col);
if (Engine.Grid.IsCellInRangeOfOtherCell(row, col, twr.computedRange, this)) {
console.log('REMOVED!');
this.isBuffedBy.splice(this.isBuffedBy.indexOf(twr), 1);
console.log(this.isBuffedBy);
}
}
});
@ -118,10 +133,12 @@ export class Cell extends GameObject {
this.row * Engine.GridCellSize + Engine.GridCellSize / 2
}y`
);
Engine.Grid.rangePreview.circle(
this.column * Engine.GridCellSize + Engine.GridCellSize / 2,
this.row * Engine.GridCellSize + Engine.GridCellSize / 2,
range * Engine.GridCellSize
console.log(
Engine.Grid.rangePreview.circle(
this.column * Engine.GridCellSize + Engine.GridCellSize / 2,
this.row * Engine.GridCellSize + Engine.GridCellSize / 2,
range * Engine.GridCellSize
)
);
Engine.Grid.rangePreview.fill({ color: color, alpha: 0.3 });
}
@ -187,6 +204,10 @@ export class Grid extends GameObject {
}
this.rangePreview = new PIXI.Graphics({
zIndex: 10,
x: 0,
y: 0,
width: Engine.app.canvas.width,
height: Engine.app.canvas.height,
});
this.container.addChild(this.rangePreview);
}
@ -216,6 +237,17 @@ export class Grid extends GameObject {
console.log(JSON.stringify(newGrid));
}
public IsCellInRangeOfOtherCell(row, col, range, otherCell) {
range = range * Engine.GridCellSize;
const x = otherCell.column * Engine.GridCellSize + Engine.GridCellSize / 2;
const y = otherCell.row * Engine.GridCellSize + Engine.GridCellSize / 2;
const cellX = col * Engine.GridCellSize + Engine.GridCellSize / 2;
const cellY = row * Engine.GridCellSize + Engine.GridCellSize / 2;
const d = distance(cellX, cellY, x, y);
if (d < range + Engine.GridCellSize / 2) return true;
else return false;
}
public toggleGrid(force?: 'hide' | 'show') {
this.cells.forEach((cell) => {
if (force) {

View File

@ -3,8 +3,9 @@ import GameObject from '../GameObject';
import { Engine } from '../Bastion';
import Creep from './Creep';
import { CreepEvents } from '../Events';
import { Tower } from './Tower';
import { distance, Tower } from './Tower';
import { CreepResistancesDefinition } from '../Definitions';
import GameAssets from '../Assets';
export function calculateAngleToPoint(x, y, targetX, targetY) {
const dx = targetX - x;
@ -55,6 +56,7 @@ export default class Projectile extends GameObject {
this.angle = angle;
this.speed = 0.9;
}
public destroy(): void {
super.destroy();
this.deleteMe = true;
@ -72,7 +74,7 @@ export default class Projectile extends GameObject {
if (!exists) {
this.collidedCreepIDs.push(creep);
this.pierce--;
this.onCollide(creep);
this.onCollide(creep, this);
return;
}
}
@ -84,14 +86,14 @@ export default class Projectile extends GameObject {
this.container.y = this.y;
}
public onCollide(creep) {
public onCollide(creep, proj) {
/*
Note:
Right now it is possible for the bullet to 'overshoot' the creep if the bullet speed is too fast and the position is updated so that the
new position is beyond the creep (i.e. the bullet is never 'in the creep').
This should be fixed so that we calculate the hit if the creep is in a line from the previous position to the new position.
*/
Engine.GameScene.events.emit(CreepEvents.TakenDamage, creep.id, this.damage, this.gemResistanceModifications);
Engine.GameScene.events.emit(CreepEvents.TakenDamage, creep.id, proj.damage, proj.gemResistanceModifications);
}
public checkCollision(creep: Creep) {
@ -102,3 +104,42 @@ export default class Projectile extends GameObject {
return mybb.getBounds().intersects(otherbb.getBounds());
}
}
export class VisualLightning extends GameObject {
public deleteMe: boolean = false;
private c: Creep;
private oc: Creep;
private Lightning: PIXI.AnimatedSprite;
constructor(creep: Creep, otherCreep: Creep) {
super();
this.c = creep;
this.oc = otherCreep;
let lightningAngle = calculateAngleToPoint(creep.x, creep.y, otherCreep.x, otherCreep.y);
this.Lightning = new PIXI.AnimatedSprite({
textures: GameAssets.SpecialLightning,
x: creep.x,
y: creep.y,
width: distance(this.c.x, this.c.y, this.oc.x, this.oc.y),
height: 64,
scale: 1.2,
rotation: lightningAngle,
});
this.Lightning.anchor.set(0, 0.5);
this.Lightning.play();
Engine.GameMaster.currentScene.stage.addChild(this.Lightning);
Engine.DebrisManager.CreateDebris(this, 30);
}
public destroy(): void {
this.deleteMe = true;
this.container.destroy();
this.Lightning.destroy();
}
public update() {
if (this.deleteMe) {
return;
}
this.Lightning.x = this.c.x;
this.Lightning.y = this.c.y;
this.Lightning.width = distance(this.c.x, this.c.y, this.oc.x, this.oc.y);
}
}

View File

@ -8,11 +8,11 @@ import Projectile, { calculateAngleToPoint } from './Projectile';
import Creep from './Creep';
import Gem from './Gem';
import {
AdvancedTowerBehaviour,
DebuffTowerBehaviour,
BasicTowerBehaviour,
CircleTowerBehaviour,
ElectricTowerBehaviour,
QuickTowerBehaviour,
BuffTowerBehaviour,
RailTowerBehaviour,
StrongTowerBehaviour,
TrapperTowerBehaviour,
@ -35,12 +35,18 @@ export class Tower extends GameObject {
public sprite: PIXI.Sprite;
public millisecondsUntilNextShot: number;
public graphics: PIXI.Graphics = new PIXI.Graphics();
public computedDamageToDeal: number;
public computedCooldown: number;
public computedRange: number;
public computedTimeToLive: number;
public computedPierce: number;
public totalGemResistanceModifications: CreepResistancesDefinition;
public computedDamageToDeal: number = 0;
public computedCooldown: number = 0;
public computedRange: number = 0;
public computedTimeToLive: number = 0;
public computedPierce: number = 0;
public totalGemResistanceModifications: CreepResistancesDefinition = {
fire: 0,
frostfire: 0,
divine: 0,
ice: 0,
physical: 0,
};
public parent: Cell;
constructor(row, column, texture, definition, behaviour) {
@ -59,6 +65,7 @@ export class Tower extends GameObject {
});
this.container.addChild(this.sprite);
this.computedDamageToDeal = this.definition.stats.damage;
this.computedRange = this.definition.stats.range;
this.parent.container.addChild(this.container);
this.container.interactiveChildren = true;
this.parent.clickDetector.on('pointerenter', this.onParentCellEnter);
@ -113,6 +120,7 @@ export class Tower extends GameObject {
return d < radius + (Engine.GridCellSize * 2) / 3;
});
}
public Shoot(angle) {
let x = this.column * Engine.GridCellSize + Engine.GridCellSize / 2;
let y = this.row * Engine.GridCellSize + Engine.GridCellSize / 2;
@ -153,11 +161,11 @@ export class Tower extends GameObject {
if (this.behaviour == TowerBehaviours.BasicTowerBehaviour) BasicTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.CircleTowerBehaviour) CircleTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.ElectricTowerBehaviour) ElectricTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.QuickTowerBehaviour) QuickTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.BuffTowerBehaviour) BuffTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.StrongTowerBehaviour) StrongTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.RailTowerBehaviour) RailTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.TrapperTowerBehaviour) TrapperTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.AdvancedTowerBehaviour) AdvancedTowerBehaviour(this, elapsedMS);
if (this.behaviour == TowerBehaviours.DebuffTowerBehaviour) DebuffTowerBehaviour(this, elapsedMS);
}
public destroy(): void {

View File

@ -1,6 +1,11 @@
import GameAssets from '../Assets';
import { Engine } from '../Bastion';
import { calculateAngleToPoint } from './Projectile';
import { Tower } from './Tower';
import { TowerType } from '../Definitions';
import { CreepEvents } from '../Events';
import Creep from './Creep';
import Projectile, { calculateAngleToPoint, VisualLightning } from './Projectile';
import { distance, Tower } from './Tower';
import * as PIXI from 'pixi.js';
/**
* Checks the projectiles of the tower and updates or removes them based on their state.
@ -44,34 +49,47 @@ export function computeGemImprovements(tower: Tower) {
physical: 0,
};
tower.slottedGems.forEach((gem) => {
let ccurrentGemImprovements = gem.currentGemImprovement();
gemDamage += ccurrentGemImprovements.damageUp;
gemAttackSpeedUp += ccurrentGemImprovements.attackSpeedUp;
gemRangeUp += ccurrentGemImprovements.rangeUp;
gemTimeToLiveUp += ccurrentGemImprovements.timeToLiveUp;
gemPierceUp += ccurrentGemImprovements.pierceUp;
let improvements = gem.currentGemImprovement();
gemDamage += improvements.damageUp;
gemAttackSpeedUp += improvements.attackSpeedUp;
gemRangeUp += improvements.rangeUp;
gemTimeToLiveUp += improvements.timeToLiveUp;
gemPierceUp += improvements.pierceUp;
let gemResMod = gem.currentGemResistanceModifications();
tower.totalGemResistanceModifications.physical += gemResMod.physical;
tower.totalGemResistanceModifications.ice += gemResMod.ice;
tower.totalGemResistanceModifications.fire += gemResMod.fire;
tower.totalGemResistanceModifications.divine += gemResMod.divine;
tower.totalGemResistanceModifications.frostfire += gemResMod.frostfire;
let resistances = gem.currentGemResistanceModifications();
tower.totalGemResistanceModifications.physical += resistances.physical;
tower.totalGemResistanceModifications.ice += resistances.ice;
tower.totalGemResistanceModifications.fire += resistances.fire;
tower.totalGemResistanceModifications.divine += resistances.divine;
tower.totalGemResistanceModifications.frostfire += resistances.frostfire;
});
tower.computedDamageToDeal = tower.definition.stats.damage + gemDamage;
tower.computedCooldown = tower.definition.stats.cooldown - gemAttackSpeedUp;
tower.computedRange = tower.definition.stats.range + gemRangeUp;
tower.computedTimeToLive = tower.definition.stats.timeToLive + gemTimeToLiveUp;
tower.computedPierce = tower.definition.stats.pierce + gemPierceUp;
// Buff tower
if (tower.parent.isBuffedBy.length > 0 && tower.definition.name != GameAssets.Towers[TowerType.Buff].name) {
let buffedBy = tower.parent.isBuffedBy[0];
tower.computedDamageToDeal += Math.ceil(buffedBy.computedDamageToDeal / 3);
tower.computedCooldown -= Math.ceil(buffedBy.computedCooldown / 5);
tower.computedRange += Math.ceil(buffedBy.computedRange / 10);
tower.computedTimeToLive += Math.ceil(buffedBy.computedTimeToLive / 5);
tower.computedPierce += Math.ceil(buffedBy.computedPierce / 4);
tower.totalGemResistanceModifications.physical +=
(buffedBy.totalGemResistanceModifications.physical * 100) / 2 / 100;
tower.totalGemResistanceModifications.ice += (buffedBy.totalGemResistanceModifications.ice * 100) / 2 / 100;
tower.totalGemResistanceModifications.fire += (buffedBy.totalGemResistanceModifications.fire * 100) / 2 / 100;
tower.totalGemResistanceModifications.divine +=
(buffedBy.totalGemResistanceModifications.divine * 100) / 2 / 100;
tower.totalGemResistanceModifications.frostfire +=
(buffedBy.totalGemResistanceModifications.frostfire * 100) / 2 / 100;
}
}
/**
* Defines the basic behavior of a tower, including computing damage, checking projectiles,
* and handling shooting at creeps within range.
*
* @param tower - The tower whose behavior is being defined.
* @param elapsedMS - The elapsed time in milliseconds since the last update.
*/
export function BasicTowerBehaviour(tower: Tower, elapsedMS: number) {
computeGemImprovements(tower);
projectileCheck(tower, elapsedMS);
@ -96,7 +114,6 @@ export function CircleTowerBehaviour(tower: Tower, elapsedMS: number) {
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
let creepsInRange = tower.GetCreepsInRange();
if (creepsInRange.length > 0) {
let focus = creepsInRange[0];
if (tower.millisecondsUntilNextShot <= 0) {
tower.millisecondsUntilNextShot = tower.computedCooldown;
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
@ -119,34 +136,52 @@ export function ElectricTowerBehaviour(tower: Tower, elapsedMS: number) {
if (tower.millisecondsUntilNextShot > 0)
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
let creepsInRange = tower.GetCreepsInRange();
if (creepsInRange.length > 0) {
let focus = creepsInRange[0];
if (tower.millisecondsUntilNextShot <= 0) {
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
tower.millisecondsUntilNextShot = tower.computedCooldown;
tower.Shoot(calculateAngleToPoint(x, y, focus.x, focus.y));
let proj = tower.Shoot(calculateAngleToPoint(x, y, focus.x, focus.y));
proj.onCollide = (creep: Creep, proj: Projectile) => {
proj.pierce = 0;
let nearByCreeps = Engine.Grid.creeps.filter((nCreep) => {
if (nCreep.id != creep.id) {
const x = nCreep.x;
const y = nCreep.y;
const radius = 3.5 * Engine.GridCellSize;
const d = distance(creep.x, creep.y, x, y);
return d < radius;
}
});
nearByCreeps.forEach((nearCreep) => {
new VisualLightning(creep, nearCreep);
Engine.GameScene.events.emit(
CreepEvents.TakenDamage,
nearCreep.id,
proj.damage / 2,
proj.gemResistanceModifications
);
});
Engine.GameScene.events.emit(
CreepEvents.TakenDamage,
creep.id,
proj.damage,
proj.gemResistanceModifications
);
};
}
}
}
export function QuickTowerBehaviour(tower: Tower, elapsedMS: number) {
export function BuffTowerBehaviour(tower: Tower, elapsedMS: number) {
computeGemImprovements(tower);
projectileCheck(tower, elapsedMS);
if (tower.millisecondsUntilNextShot > 0)
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
let creepsInRange = tower.GetCreepsInRange();
if (creepsInRange.length > 0) {
let focus = creepsInRange[0];
if (tower.millisecondsUntilNextShot <= 0) {
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
tower.millisecondsUntilNextShot = tower.computedCooldown;
tower.Shoot(calculateAngleToPoint(x, y, focus.x, focus.y));
}
}
// Buff tower does not do anything and doesn't have a behaviour.
// For how its implemented, Cell tracks when it's placed and removed (via event)
// and tower takes improvements via computeGemImprovements()
}
export function StrongTowerBehaviour(tower: Tower, elapsedMS: number) {
@ -203,7 +238,7 @@ export function TrapperTowerBehaviour(tower: Tower, elapsedMS: number) {
}
}
export function AdvancedTowerBehaviour(tower: Tower, elapsedMS: number) {
export function DebuffTowerBehaviour(tower: Tower, elapsedMS: number) {
computeGemImprovements(tower);
projectileCheck(tower, elapsedMS);

View File

@ -2,7 +2,7 @@ import * as PIXI from 'pixi.js';
import { Engine } from '../Bastion';
import { TerrainType, TowerDefinition } from '../Definitions';
import GameAssets from '../Assets';
import { Tower } from './Tower';
import { distance, Tower } from './Tower';
import { Cell } from './Grid';
import { GridEvents, TowerEvents } from '../Events';
@ -10,11 +10,11 @@ export enum TowerBehaviours {
BasicTowerBehaviour = 'BasicTowerBehaviour',
CircleTowerBehaviour = 'CircleTowerBehaviour',
ElectricTowerBehaviour = 'ElectricTowerBehaviour',
QuickTowerBehaviour = 'QuickTowerBehaviour',
BuffTowerBehaviour = 'BuffTowerBehaviour',
StrongTowerBehaviour = 'StrongTowerBehaviour',
RailTowerBehaviour = 'RailTowerBehaviour',
TrapperTowerBehaviour = 'TrapperTowerBehaviour',
AdvancedTowerBehaviour = 'AdvancedTowerBehaviour',
DebuffTowerBehaviour = 'DebuffTowerBehaviour',
}
export default class TowerManager {
@ -127,10 +127,10 @@ export default class TowerManager {
while (twr.slottedGems.length > 0) {
twr.UnslotGem(0);
}
Engine.GameScene.events.emit(TowerEvents.TowerSoldEvent, twr.definition.name, twr.row, twr.column);
Engine.GameScene.MissionStats.earnGold(twr.definition.stats.cost);
twr.destroy();
this.towers.splice(idx, 1);
Engine.GameScene.events.emit(TowerEvents.TowerSoldEvent, twr.name, twr.row, twr.column);
} else twr.update(elapsedMS);
});
}

View File

@ -7,7 +7,7 @@ import { AnimationManager } from './classes/game/AnimationManager';
import NotificationManager from './classes/game/NotificationManager';
import GameUIConstants from './classes/GameUIConstants';
import KeyboardManager from './classes/game/KeyboardManager';
import { GemType } from './classes/Definitions';
import DebrisManager from './classes/game/DebrisManager';
(async () => {
const app = new PIXI.Application();
@ -54,10 +54,12 @@ import { GemType } from './classes/Definitions';
new GameMaster();
Engine.AnimationManager = new AnimationManager();
Engine.NotificationManager = new NotificationManager();
Engine.DebrisManager = new DebrisManager();
globalThis.Engine = Engine;
PIXI.Ticker.shared.add((ticker) => {
Engine.NotificationManager.update(ticker.elapsedMS);
Engine.AnimationManager.update(ticker.elapsedMS);
Engine.DebrisManager.update(ticker.elapsedMS);
});
app.canvas.addEventListener('pointermove', function (event) {
Engine.MouseX = ((event.clientX - app.canvas.offsetLeft) / app.canvas.offsetWidth) * 1920;