successfully implement all mechanics
This commit is contained in:
commit
ca8bf01c78
@ -2,7 +2,7 @@ Generated by: `find ./src -name '*.ts' | xargs wc -l`
|
|||||||
92 ./src/main.ts
|
92 ./src/main.ts
|
||||||
1 ./src/vite-env.d.ts
|
1 ./src/vite-env.d.ts
|
||||||
17 ./src/classes/GameUIConstants.ts
|
17 ./src/classes/GameUIConstants.ts
|
||||||
145 ./src/classes/gui/TowerTab.ts
|
217 ./src/classes/gui/TowerTab.ts
|
||||||
375 ./src/classes/gui/TowerPanel.ts
|
375 ./src/classes/gui/TowerPanel.ts
|
||||||
52 ./src/classes/gui/TextInput.ts
|
52 ./src/classes/gui/TextInput.ts
|
||||||
211 ./src/classes/gui/ModalDialog.ts
|
211 ./src/classes/gui/ModalDialog.ts
|
||||||
@ -15,29 +15,30 @@ Generated by: `find ./src -name '*.ts' | xargs wc -l`
|
|||||||
59 ./src/classes/gui/GamePausedDialog.ts
|
59 ./src/classes/gui/GamePausedDialog.ts
|
||||||
36 ./src/classes/gui/MessageBox.ts
|
36 ./src/classes/gui/MessageBox.ts
|
||||||
205 ./src/classes/gui/Tooltip.ts
|
205 ./src/classes/gui/Tooltip.ts
|
||||||
126 ./src/classes/Definitions.ts
|
133 ./src/classes/Definitions.ts
|
||||||
77 ./src/classes/game/WaveManager.ts
|
77 ./src/classes/game/WaveManager.ts
|
||||||
260 ./src/classes/game/Grid.ts
|
264 ./src/classes/game/Grid.ts
|
||||||
51 ./src/classes/game/Gem.ts
|
51 ./src/classes/game/Gem.ts
|
||||||
114 ./src/classes/game/TowerBehaviours.ts
|
324 ./src/classes/game/TowerBehaviours.ts
|
||||||
154 ./src/classes/game/Tower.ts
|
192 ./src/classes/game/Tower.ts
|
||||||
180 ./src/classes/game/MissionStats.ts
|
180 ./src/classes/game/MissionStats.ts
|
||||||
100 ./src/classes/game/AnimationManager.ts
|
100 ./src/classes/game/AnimationManager.ts
|
||||||
177 ./src/classes/game/Creep.ts
|
239 ./src/classes/game/Creep.ts
|
||||||
47 ./src/classes/game/KeyboardManager.ts
|
47 ./src/classes/game/KeyboardManager.ts
|
||||||
104 ./src/classes/game/Projectile.ts
|
251 ./src/classes/game/Projectile.ts
|
||||||
86 ./src/classes/game/NotificationManager.ts
|
86 ./src/classes/game/NotificationManager.ts
|
||||||
130 ./src/classes/game/TowerManager.ts
|
40 ./src/classes/game/DebrisManager.ts
|
||||||
|
135 ./src/classes/game/TowerManager.ts
|
||||||
71 ./src/classes/game/HighScoreManager.ts
|
71 ./src/classes/game/HighScoreManager.ts
|
||||||
76 ./src/classes/GuiObject.ts
|
76 ./src/classes/GuiObject.ts
|
||||||
203 ./src/classes/Assets.ts
|
209 ./src/classes/Assets.ts
|
||||||
52 ./src/classes/GameObject.ts
|
52 ./src/classes/GameObject.ts
|
||||||
68 ./src/classes/Bastion.ts
|
71 ./src/classes/Bastion.ts
|
||||||
30 ./src/classes/Events.ts
|
31 ./src/classes/Events.ts
|
||||||
37 ./src/scenes/Scene.ts
|
37 ./src/scenes/Scene.ts
|
||||||
17 ./src/scenes/Settings.ts
|
17 ./src/scenes/Settings.ts
|
||||||
67 ./src/scenes/HowToPlay.ts
|
67 ./src/scenes/HowToPlay.ts
|
||||||
59 ./src/scenes/Main.ts
|
59 ./src/scenes/Main.ts
|
||||||
353 ./src/scenes/Game.ts
|
352 ./src/scenes/Game.ts
|
||||||
27 ./src/scenes/MissionPicker.ts
|
27 ./src/scenes/MissionPicker.ts
|
||||||
`4536 total`
|
`5130 total`
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
"cost": 125,
|
"cost": 125,
|
||||||
"range": 2.5,
|
"range": 2.5,
|
||||||
"timeToLive": 12,
|
"timeToLive": 12,
|
||||||
"pierce": 30
|
"pierce": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -120,7 +120,7 @@
|
|||||||
"texture": null,
|
"texture": null,
|
||||||
"projectile": "stone",
|
"projectile": "stone",
|
||||||
"projectileTextures": [],
|
"projectileTextures": [],
|
||||||
"projectileTexturesArrayLength": 2,
|
"projectileTexturesArrayLength": 1,
|
||||||
"description": "If you feel a little circular.",
|
"description": "If you feel a little circular.",
|
||||||
"stats": {
|
"stats": {
|
||||||
"damage": 2,
|
"damage": 2,
|
||||||
@ -128,8 +128,8 @@
|
|||||||
"gemSlotsAmount": 3,
|
"gemSlotsAmount": 3,
|
||||||
"cost": 125,
|
"cost": 125,
|
||||||
"range": 2.5,
|
"range": 2.5,
|
||||||
"timeToLive": 12,
|
"timeToLive": 400,
|
||||||
"pierce": 30
|
"pierce": 2
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
@ -7,6 +7,7 @@ export enum WaveManagerEvents {
|
|||||||
export enum CreepEvents {
|
export enum CreepEvents {
|
||||||
Died = 'died',
|
Died = 'died',
|
||||||
TakenDamage = 'takenDamage',
|
TakenDamage = 'takenDamage',
|
||||||
|
GiveEffect = 'giveEffect',
|
||||||
Escaped = 'escaped',
|
Escaped = 'escaped',
|
||||||
Moved = 'moved',
|
Moved = 'moved',
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import GameAssets from '../Assets';
|
|
||||||
import Assets from '../Assets';
|
import Assets from '../Assets';
|
||||||
import { Engine } from '../Bastion';
|
import { Engine } from '../Bastion';
|
||||||
import { CreepResistancesDefinition, CreepStatsDefinition, CreepType, PathDefinition } from '../Definitions';
|
import { CreepResistancesDefinition, CreepStatsDefinition, CreepType, PathDefinition } from '../Definitions';
|
||||||
@ -6,6 +5,21 @@ import GameObject from '../GameObject';
|
|||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
import { CreepEvents } from '../Events';
|
import { CreepEvents } from '../Events';
|
||||||
|
|
||||||
|
export enum CreepEffects {
|
||||||
|
MovingBackwards = 'MovingBackwards',
|
||||||
|
DebuffTowerDebuff = 'DebuffTowerDebuff',
|
||||||
|
}
|
||||||
|
|
||||||
|
class Effect {
|
||||||
|
public effectEnum: CreepEffects;
|
||||||
|
public durationInMS: number;
|
||||||
|
public ticks: number = 0;
|
||||||
|
constructor(effectEnum: CreepEffects, durationInMS: number) {
|
||||||
|
this.effectEnum = effectEnum;
|
||||||
|
this.durationInMS = durationInMS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class Creep extends GameObject {
|
export default class Creep extends GameObject {
|
||||||
public id: number;
|
public id: number;
|
||||||
public creepType: CreepType;
|
public creepType: CreepType;
|
||||||
@ -17,6 +31,7 @@ export default class Creep extends GameObject {
|
|||||||
private direction: number = 1;
|
private direction: number = 1;
|
||||||
private healthBarGraphics: PIXI.Graphics = new PIXI.Graphics();
|
private healthBarGraphics: PIXI.Graphics = new PIXI.Graphics();
|
||||||
private healthBarWidth = 50;
|
private healthBarWidth = 50;
|
||||||
|
private effects: Effect[] = [];
|
||||||
public health: number;
|
public health: number;
|
||||||
public maxHealth: number;
|
public maxHealth: number;
|
||||||
public escaped: boolean = false;
|
public escaped: boolean = false;
|
||||||
@ -56,7 +71,10 @@ export default class Creep extends GameObject {
|
|||||||
CreepEvents.TakenDamage,
|
CreepEvents.TakenDamage,
|
||||||
(creepID, damage, gemResistanceModifications: CreepResistancesDefinition) => {
|
(creepID, damage, gemResistanceModifications: CreepResistancesDefinition) => {
|
||||||
if (creepID != this.id) return;
|
if (creepID != this.id) return;
|
||||||
|
if (this.effects.find((e) => e.effectEnum == CreepEffects.DebuffTowerDebuff)) {
|
||||||
|
damage = damage * 1.5;
|
||||||
|
console.log('multiplying damage, ' + damage);
|
||||||
|
}
|
||||||
// Apply resistances.
|
// Apply resistances.
|
||||||
this.health -= damage + damage * (gemResistanceModifications.physical - this.stats.resistance.physical);
|
this.health -= damage + damage * (gemResistanceModifications.physical - this.stats.resistance.physical);
|
||||||
if (gemResistanceModifications.fire != 0)
|
if (gemResistanceModifications.fire != 0)
|
||||||
@ -76,23 +94,49 @@ export default class Creep extends GameObject {
|
|||||||
this.UpdateHealthbar();
|
this.UpdateHealthbar();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Engine.GameScene.events.on(
|
||||||
|
CreepEvents.GiveEffect,
|
||||||
|
(creepID: number, effect: CreepEffects, durationInMS: number) => {
|
||||||
|
if (creepID != this.id) return;
|
||||||
|
console.log(' I CAUGHT THE EVENT!');
|
||||||
|
if (this.effects.find((e) => e.effectEnum == effect) == undefined)
|
||||||
|
this.effects.push(new Effect(effect, durationInMS));
|
||||||
|
}
|
||||||
|
);
|
||||||
Engine.Grid.container.addChild(this.container);
|
Engine.Grid.container.addChild(this.container);
|
||||||
this.container.addChild(this.healthBarGraphics);
|
this.container.addChild(this.healthBarGraphics);
|
||||||
this.container.addChild(this.sprite);
|
this.container.addChild(this.sprite);
|
||||||
this.UpdateHealthbar();
|
this.UpdateHealthbar();
|
||||||
}
|
}
|
||||||
|
// Used ChatGPT to make this easier to understand.
|
||||||
private UpdateHealthbar() {
|
private UpdateHealthbar() {
|
||||||
this.healthBarGraphics.clear();
|
this.healthBarGraphics.clear();
|
||||||
|
|
||||||
const hp = this.health;
|
const hp = this.health;
|
||||||
const maxHp = this.maxHealth;
|
const maxHp = this.maxHealth;
|
||||||
const percent = hp / maxHp;
|
const percent = Math.max(0, hp / maxHp);
|
||||||
const width = this.healthBarWidth * percent;
|
|
||||||
// ! TODO: MAKE THIS BETTER! It works like this now, but I don't like how its implemented.
|
const barWidth = this.healthBarWidth;
|
||||||
this.healthBarGraphics.rect(-this.healthBarWidth / 2 + 3, -32, this.healthBarWidth + 4, 14);
|
const barHeight = 10; // Height of the health bar
|
||||||
|
const borderPadding = 2; // Border thickness around the health bar
|
||||||
|
const offsetX = -barWidth / 2; // Centering the bar
|
||||||
|
const offsetY = -32; // Position above the entity
|
||||||
|
|
||||||
|
// Border
|
||||||
|
this.healthBarGraphics.rect(
|
||||||
|
offsetX - borderPadding,
|
||||||
|
offsetY - borderPadding,
|
||||||
|
barWidth + borderPadding * 2,
|
||||||
|
barHeight + borderPadding * 2
|
||||||
|
);
|
||||||
this.healthBarGraphics.fill({ color: 0x000000 });
|
this.healthBarGraphics.fill({ color: 0x000000 });
|
||||||
this.healthBarGraphics.rect(-this.healthBarWidth / 2 + 5, -30, width, 10);
|
|
||||||
|
// Health
|
||||||
|
const healthWidth = barWidth * percent;
|
||||||
|
this.healthBarGraphics.rect(offsetX, offsetY, healthWidth, barHeight);
|
||||||
this.healthBarGraphics.fill({ color: 0xff0000 });
|
this.healthBarGraphics.fill({ color: 0xff0000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
public update(elapsedMS: number) {
|
public update(elapsedMS: number) {
|
||||||
if (this.dead) return;
|
if (this.dead) return;
|
||||||
if (this.health <= 0) {
|
if (this.health <= 0) {
|
||||||
@ -110,14 +154,30 @@ export default class Creep extends GameObject {
|
|||||||
this.escaped = true;
|
this.escaped = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentCell = this.path[this.pathIndex];
|
const currentCell = this.path[this.pathIndex];
|
||||||
const targetCell = this.path[this.pathIndex + 1];
|
const targetCell = this.path[this.pathIndex + 1];
|
||||||
|
const previousCell = this.pathIndex - 1 != 0 ? this.path[this.pathIndex - 1] : this.path[0];
|
||||||
|
let isMovingBackwards = false;
|
||||||
|
for (let i = this.effects.length - 1; i >= 0; i--) {
|
||||||
|
let effect = this.effects[i];
|
||||||
|
effect.ticks += elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
|
if (effect.ticks >= effect.durationInMS) this.effects.splice(i, 1);
|
||||||
|
else if (effect.effectEnum == CreepEffects.MovingBackwards) return (isMovingBackwards = true);
|
||||||
|
}
|
||||||
|
|
||||||
// Added + 32 for centering.
|
let targetX, targetY, directionX, directionY;
|
||||||
const targetX = targetCell[0] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
if (!isMovingBackwards) {
|
||||||
const targetY = targetCell[1] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
targetX = targetCell[0] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
const directionX = targetCell[0] - currentCell[0];
|
targetY = targetCell[1] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
const directionY = targetCell[1] - currentCell[1];
|
directionX = targetCell[0] - currentCell[0];
|
||||||
|
directionY = targetCell[1] - currentCell[1];
|
||||||
|
} else {
|
||||||
|
targetX = previousCell[0] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
|
targetY = previousCell[1] * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
|
directionX = currentCell[0] - previousCell[0];
|
||||||
|
directionY = previousCell[1] - currentCell[1];
|
||||||
|
}
|
||||||
if (directionX > 0) {
|
if (directionX > 0) {
|
||||||
// Going right
|
// Going right
|
||||||
if (this.direction != 1) {
|
if (this.direction != 1) {
|
||||||
@ -157,7 +217,9 @@ export default class Creep extends GameObject {
|
|||||||
}
|
}
|
||||||
this.x += deltaX;
|
this.x += deltaX;
|
||||||
this.y += deltaY;
|
this.y += deltaY;
|
||||||
if (increaseIndex) this.pathIndex++;
|
if (increaseIndex) {
|
||||||
|
if (!isMovingBackwards) this.pathIndex++;
|
||||||
|
}
|
||||||
this.container.x = this.x;
|
this.container.x = this.x;
|
||||||
this.container.y = this.y;
|
this.container.y = this.y;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ class Debris {
|
|||||||
this.debris.destroy();
|
this.debris.destroy();
|
||||||
}
|
}
|
||||||
public update(elapsedMS) {
|
public update(elapsedMS) {
|
||||||
console.log(this.debris instanceof GameObject);
|
|
||||||
if (this.debris instanceof GameObject) {
|
if (this.debris instanceof GameObject) {
|
||||||
this.debris.update(elapsedMS);
|
this.debris.update(elapsedMS);
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,17 @@ export class Grid extends GameObject {
|
|||||||
if (d < range + Engine.GridCellSize / 2) return true;
|
if (d < range + Engine.GridCellSize / 2) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
public GetPathCellsInRange(row, col, range) {
|
||||||
|
let result = [];
|
||||||
|
this.cells.forEach((cell) => {
|
||||||
|
if (cell.isPath) {
|
||||||
|
if (this.IsCellInRangeOfOtherCell(row, col, range, cell)) {
|
||||||
|
result.push(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
public toggleGrid(force?: 'hide' | 'show') {
|
public toggleGrid(force?: 'hide' | 'show') {
|
||||||
this.cells.forEach((cell) => {
|
this.cells.forEach((cell) => {
|
||||||
if (force) {
|
if (force) {
|
||||||
|
@ -6,6 +6,7 @@ import { CreepEvents } from '../Events';
|
|||||||
import { distance, Tower } from './Tower';
|
import { distance, Tower } from './Tower';
|
||||||
import { CreepResistancesDefinition } from '../Definitions';
|
import { CreepResistancesDefinition } from '../Definitions';
|
||||||
import GameAssets from '../Assets';
|
import GameAssets from '../Assets';
|
||||||
|
import { RoundMode } from '../../scenes/Game';
|
||||||
|
|
||||||
export function calculateAngleToPoint(x, y, targetX, targetY) {
|
export function calculateAngleToPoint(x, y, targetX, targetY) {
|
||||||
const dx = targetX - x;
|
const dx = targetX - x;
|
||||||
@ -64,7 +65,7 @@ export default class Projectile extends GameObject {
|
|||||||
|
|
||||||
public update(elapsedMS) {
|
public update(elapsedMS) {
|
||||||
if (this.deleteMe) return;
|
if (this.deleteMe) return;
|
||||||
if (this.x > 2000 || this.x < 0 || this.y > 2000 || this.y < 0 || this.pierce <= 0 || this.timeToLive <= 0)
|
if (this.x > 1720 || this.x < 0 || this.y > 2000 || this.y < 0 || this.pierce <= 0 || this.timeToLive <= 0)
|
||||||
return this.destroy();
|
return this.destroy();
|
||||||
this.timeToLive -= Engine.GameScene.gameSpeedMultiplier;
|
this.timeToLive -= Engine.GameScene.gameSpeedMultiplier;
|
||||||
Engine.Grid.creeps.forEach((creep) => {
|
Engine.Grid.creeps.forEach((creep) => {
|
||||||
@ -105,6 +106,111 @@ export default class Projectile extends GameObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class RailProjectile extends Projectile {
|
||||||
|
public visuals: PIXI.Sprite[] = [];
|
||||||
|
public counter: number = 0;
|
||||||
|
constructor(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
textures,
|
||||||
|
angle,
|
||||||
|
damage,
|
||||||
|
tint,
|
||||||
|
timeToLive,
|
||||||
|
pierce,
|
||||||
|
gemResistanceModifications: CreepResistancesDefinition
|
||||||
|
) {
|
||||||
|
super(x, y, textures, angle, damage, tint, timeToLive, pierce, gemResistanceModifications);
|
||||||
|
this.pierce = 1000;
|
||||||
|
this.timeToLive = 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroy(): void {
|
||||||
|
super.destroy();
|
||||||
|
this.visuals.forEach((visual) => visual.destroy());
|
||||||
|
this.visuals = [];
|
||||||
|
}
|
||||||
|
public update(elapsedMS) {
|
||||||
|
super.update(elapsedMS);
|
||||||
|
if (this.counter == 2) {
|
||||||
|
this.counter = 0;
|
||||||
|
let newVisual = new PIXI.Sprite({
|
||||||
|
x: this.x,
|
||||||
|
y: this.y,
|
||||||
|
rotation: this.angle,
|
||||||
|
texture: this.sprite.texture,
|
||||||
|
scale: 0.25,
|
||||||
|
});
|
||||||
|
newVisual.anchor.set(0.5, 0.5);
|
||||||
|
this.visuals.push(newVisual);
|
||||||
|
this.visuals.forEach((visual) => {
|
||||||
|
if (visual.scale == null) return visual.destroy();
|
||||||
|
if (visual.width && visual.height && visual.alpha) {
|
||||||
|
visual.width -= 4;
|
||||||
|
visual.height -= 4;
|
||||||
|
visual.alpha -= 0.1;
|
||||||
|
if (visual.width <= 0 || visual.height <= 0 || visual.alpha <= 0) visual.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Engine.GameScene.stage.addChild(newVisual);
|
||||||
|
} else this.counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TrapProjectile extends Projectile {
|
||||||
|
public visuals: PIXI.Sprite[] = [];
|
||||||
|
public counter: number = 0;
|
||||||
|
private goalX: number;
|
||||||
|
private goalY: number;
|
||||||
|
constructor(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
textures,
|
||||||
|
angle,
|
||||||
|
goalX,
|
||||||
|
goalY,
|
||||||
|
damage,
|
||||||
|
tint,
|
||||||
|
timeToLive,
|
||||||
|
pierce,
|
||||||
|
gemResistanceModifications: CreepResistancesDefinition
|
||||||
|
) {
|
||||||
|
super(x, y, textures, angle, damage, tint, timeToLive, pierce, gemResistanceModifications);
|
||||||
|
this.sprite.scale = 0.5;
|
||||||
|
this.goalX = goalX;
|
||||||
|
this.goalY = goalY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public destroy(): void {
|
||||||
|
super.destroy();
|
||||||
|
this.visuals.forEach((visual) => visual.destroy());
|
||||||
|
this.visuals = [];
|
||||||
|
}
|
||||||
|
public update(elapsedMS) {
|
||||||
|
if (this.deleteMe) return;
|
||||||
|
if (this.x > 1720 || this.x < 0 || this.y > 2000 || this.y < 0 || this.pierce <= 0 || this.timeToLive <= 0)
|
||||||
|
return this.destroy();
|
||||||
|
if (distance(this.x, this.y, this.goalX, this.goalY) < 25) {
|
||||||
|
this.timeToLive -= Engine.GameScene.gameSpeedMultiplier;
|
||||||
|
Engine.Grid.creeps.forEach((creep) => {
|
||||||
|
if (this.pierce <= 0) return;
|
||||||
|
if (creep && creep.container && this.checkCollision(creep)) {
|
||||||
|
this.collidedCreepIDs.push(creep);
|
||||||
|
this.pierce--;
|
||||||
|
this.onCollide(creep, this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.x += Math.cos(this.angle) * this.speed * elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
|
this.y += Math.sin(this.angle) * this.speed * elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
|
|
||||||
|
this.container.x = this.x;
|
||||||
|
this.container.y = this.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class VisualLightning extends GameObject {
|
export class VisualLightning extends GameObject {
|
||||||
public deleteMe: boolean = false;
|
public deleteMe: boolean = false;
|
||||||
private c: Creep;
|
private c: Creep;
|
||||||
|
@ -4,7 +4,7 @@ import GameObject from '../GameObject';
|
|||||||
import { CreepResistancesDefinition, TowerDefinition } from '../Definitions';
|
import { CreepResistancesDefinition, TowerDefinition } from '../Definitions';
|
||||||
import { Cell } from './Grid';
|
import { Cell } from './Grid';
|
||||||
import { TowerBehaviours } from './TowerManager';
|
import { TowerBehaviours } from './TowerManager';
|
||||||
import Projectile from './Projectile';
|
import Projectile, { RailProjectile } from './Projectile';
|
||||||
import Gem from './Gem';
|
import Gem from './Gem';
|
||||||
import {
|
import {
|
||||||
DebuffTowerBehaviour,
|
DebuffTowerBehaviour,
|
||||||
@ -132,18 +132,34 @@ export class Tower extends GameObject {
|
|||||||
}
|
}
|
||||||
combinedTint = color;
|
combinedTint = color;
|
||||||
}
|
}
|
||||||
let proj = new Projectile(
|
|
||||||
x,
|
let proj;
|
||||||
y,
|
if (this.behaviour == TowerBehaviours.RailTowerBehaviour) {
|
||||||
this.definition.projectileTextures,
|
proj = new RailProjectile(
|
||||||
angle,
|
x,
|
||||||
this.computedDamageToDeal,
|
y,
|
||||||
combinedTint,
|
this.definition.projectileTextures,
|
||||||
this.computedTimeToLive,
|
angle,
|
||||||
this.computedPierce,
|
this.computedDamageToDeal,
|
||||||
this.totalGemResistanceModifications
|
combinedTint,
|
||||||
);
|
this.computedTimeToLive,
|
||||||
const time = new Date().toISOString();
|
this.computedPierce,
|
||||||
|
this.totalGemResistanceModifications
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
proj = new Projectile(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
this.definition.projectileTextures,
|
||||||
|
angle,
|
||||||
|
this.computedDamageToDeal,
|
||||||
|
combinedTint,
|
||||||
|
this.computedTimeToLive,
|
||||||
|
this.computedPierce,
|
||||||
|
this.totalGemResistanceModifications
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// const time = new Date().toISOString();
|
||||||
// console.log(`${time} ${this.definition.name} shot at ${angle} degrees`);
|
// console.log(`${time} ${this.definition.name} shot at ${angle} degrees`);
|
||||||
this.projectiles.push(proj);
|
this.projectiles.push(proj);
|
||||||
return proj;
|
return proj;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
import { RoundMode } from '../../scenes/Game';
|
||||||
import GameAssets from '../Assets';
|
import GameAssets from '../Assets';
|
||||||
import { Engine } from '../Bastion';
|
import { Engine } from '../Bastion';
|
||||||
import { TowerType } from '../Definitions';
|
import { TowerType } from '../Definitions';
|
||||||
import { CreepEvents } from '../Events';
|
import { CreepEvents } from '../Events';
|
||||||
import Creep from './Creep';
|
import Creep, { CreepEffects } from './Creep';
|
||||||
import Projectile, { calculateAngleToPoint, VisualLightning } from './Projectile';
|
import Projectile, { calculateAngleToPoint, TrapProjectile, VisualLightning } from './Projectile';
|
||||||
import { distance, Tower } from './Tower';
|
import { distance, Tower } from './Tower';
|
||||||
import * as PIXI from 'pixi.js';
|
import * as PIXI from 'pixi.js';
|
||||||
|
|
||||||
@ -16,17 +17,21 @@ import * as PIXI from 'pixi.js';
|
|||||||
* @param elapsedMS - The elapsed time in milliseconds since the last update.
|
* @param elapsedMS - The elapsed time in milliseconds since the last update.
|
||||||
*/
|
*/
|
||||||
function projectileCheck(tower: Tower, elapsedMS: number) {
|
function projectileCheck(tower: Tower, elapsedMS: number) {
|
||||||
tower.projectiles.forEach((proj) => {
|
for (let i = tower.projectiles.length - 1; i >= 0; i--) {
|
||||||
|
let proj = tower.projectiles[i];
|
||||||
|
|
||||||
if (proj.deleteMe || tower.sold) {
|
if (proj.deleteMe || tower.sold) {
|
||||||
proj.collidedCreepIDs.forEach(() => {
|
proj.collidedCreepIDs.forEach(() => {
|
||||||
tower.damageDealt += tower.computedDamageToDeal;
|
tower.damageDealt += tower.computedDamageToDeal;
|
||||||
});
|
});
|
||||||
proj.collidedCreepIDs = [];
|
proj.collidedCreepIDs = [];
|
||||||
tower.projectiles.splice(tower.projectiles.indexOf(proj), 1);
|
|
||||||
proj.destroy();
|
proj.destroy();
|
||||||
proj = null;
|
tower.projectiles.splice(i, 1);
|
||||||
} else proj.update(elapsedMS);
|
} else {
|
||||||
});
|
proj.update(elapsedMS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,10 +79,10 @@ export function computeGemImprovements(tower: Tower) {
|
|||||||
if (tower.parent.isBuffedBy.length > 0 && tower.definition.name != GameAssets.Towers[TowerType.Buff].name) {
|
if (tower.parent.isBuffedBy.length > 0 && tower.definition.name != GameAssets.Towers[TowerType.Buff].name) {
|
||||||
let buffedBy = tower.parent.isBuffedBy[0];
|
let buffedBy = tower.parent.isBuffedBy[0];
|
||||||
tower.computedDamageToDeal += Number((buffedBy.computedDamageToDeal / 2).toFixed(1));
|
tower.computedDamageToDeal += Number((buffedBy.computedDamageToDeal / 2).toFixed(1));
|
||||||
tower.computedCooldown -= (buffedBy.computedCooldown * 100) / 5 / 100;
|
tower.computedCooldown -= Number((buffedBy.computedCooldown / 5).toFixed(1));
|
||||||
tower.computedRange += Number((buffedBy.computedRange / 10).toFixed(1));
|
tower.computedRange += Number((buffedBy.computedRange / 10).toFixed(1));
|
||||||
tower.computedTimeToLive += (buffedBy.computedTimeToLive * 100) / 5 / 100;
|
tower.computedTimeToLive += Number((buffedBy.computedTimeToLive / 5).toFixed(1));
|
||||||
tower.computedPierce += (buffedBy.computedPierce * 100) / 4 / 100;
|
tower.computedPierce += Number((buffedBy.computedPierce / 4).toFixed(1));
|
||||||
|
|
||||||
tower.totalGemResistanceModifications.physical +=
|
tower.totalGemResistanceModifications.physical +=
|
||||||
(buffedBy.totalGemResistanceModifications.physical * 100) / 2 / 100;
|
(buffedBy.totalGemResistanceModifications.physical * 100) / 2 / 100;
|
||||||
@ -95,10 +100,10 @@ export function BasicTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
projectileCheck(tower, elapsedMS);
|
projectileCheck(tower, elapsedMS);
|
||||||
if (tower.millisecondsUntilNextShot > 0)
|
if (tower.millisecondsUntilNextShot > 0)
|
||||||
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
let creepsInRange = tower.GetCreepsInRange();
|
else {
|
||||||
if (creepsInRange.length > 0) {
|
let creepsInRange = tower.GetCreepsInRange();
|
||||||
let focus = creepsInRange[0];
|
if (creepsInRange.length > 0) {
|
||||||
if (tower.millisecondsUntilNextShot <= 0) {
|
let focus = creepsInRange[0];
|
||||||
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
||||||
@ -112,9 +117,9 @@ export function CircleTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
projectileCheck(tower, elapsedMS);
|
projectileCheck(tower, elapsedMS);
|
||||||
if (tower.millisecondsUntilNextShot > 0)
|
if (tower.millisecondsUntilNextShot > 0)
|
||||||
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
let creepsInRange = tower.GetCreepsInRange();
|
else {
|
||||||
if (creepsInRange.length > 0) {
|
let creepsInRange = tower.GetCreepsInRange();
|
||||||
if (tower.millisecondsUntilNextShot <= 0) {
|
if (creepsInRange.length > 0) {
|
||||||
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
||||||
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
@ -136,12 +141,11 @@ export function ElectricTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
|
|
||||||
if (tower.millisecondsUntilNextShot > 0)
|
if (tower.millisecondsUntilNextShot > 0)
|
||||||
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
|
else {
|
||||||
|
let creepsInRange = tower.GetCreepsInRange();
|
||||||
|
|
||||||
let creepsInRange = tower.GetCreepsInRange();
|
if (creepsInRange.length > 0) {
|
||||||
|
let focus = creepsInRange[0];
|
||||||
if (creepsInRange.length > 0) {
|
|
||||||
let focus = creepsInRange[0];
|
|
||||||
if (tower.millisecondsUntilNextShot <= 0) {
|
|
||||||
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
||||||
@ -149,36 +153,47 @@ export function ElectricTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
proj.onCollide = (creep: Creep, proj: Projectile) => {
|
proj.onCollide = (creep: Creep, proj: Projectile) => {
|
||||||
let chainedCreepIds = [];
|
let chainedCreepIds = [];
|
||||||
proj.pierce = 0;
|
proj.pierce = 0;
|
||||||
function checkNearBy(c) {
|
let recursionCount = 0;
|
||||||
let nearByCreeps = Engine.Grid.creeps.filter((nCreep) => {
|
function checkNearBy(c: Creep) {
|
||||||
|
if (recursionCount >= 50) {
|
||||||
|
Engine.GameScene.PauseGame();
|
||||||
|
Engine.NotificationManager.Notify(
|
||||||
|
'Electric Tower max recursion exceeded! Please tell koneko! (game paused)',
|
||||||
|
'danger'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
recursionCount++;
|
||||||
|
|
||||||
|
Engine.Grid.creeps.forEach((nCreep) => {
|
||||||
if (nCreep.id != creep.id) {
|
if (nCreep.id != creep.id) {
|
||||||
const x = nCreep.x;
|
const x = nCreep.x;
|
||||||
const y = nCreep.y;
|
const y = nCreep.y;
|
||||||
const radius = 1.5 * Engine.GridCellSize;
|
const radius = 1.5 * Engine.GridCellSize;
|
||||||
const d = distance(c.x, c.y, x, y);
|
const d = distance(c.x, c.y, x, y);
|
||||||
return d < radius;
|
if (d < radius) {
|
||||||
|
if (chainedCreepIds.find((crID) => crID == nCreep.id) != undefined) return;
|
||||||
|
chainedCreepIds.push(nCreep.id);
|
||||||
|
new VisualLightning(c, nCreep);
|
||||||
|
Engine.GameScene.events.emit(
|
||||||
|
CreepEvents.TakenDamage,
|
||||||
|
nCreep.id,
|
||||||
|
Math.round(proj.damage / 2),
|
||||||
|
proj.gemResistanceModifications
|
||||||
|
);
|
||||||
|
checkNearBy(nCreep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
nearByCreeps.forEach((nearCreep) => {
|
|
||||||
if (!chainedCreepIds.find((crID) => crID == nearCreep.id)) chainedCreepIds.push(nearCreep.id);
|
|
||||||
else return;
|
|
||||||
checkNearBy(nearCreep);
|
|
||||||
new VisualLightning(c, nearCreep);
|
|
||||||
Engine.GameScene.events.emit(
|
|
||||||
CreepEvents.TakenDamage,
|
|
||||||
nearCreep.id,
|
|
||||||
Math.round(proj.damage / 2),
|
|
||||||
proj.gemResistanceModifications
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
checkNearBy(creep);
|
|
||||||
Engine.GameScene.events.emit(
|
Engine.GameScene.events.emit(
|
||||||
CreepEvents.TakenDamage,
|
CreepEvents.TakenDamage,
|
||||||
creep.id,
|
creep.id,
|
||||||
proj.damage,
|
proj.damage,
|
||||||
proj.gemResistanceModifications
|
proj.gemResistanceModifications
|
||||||
);
|
);
|
||||||
|
chainedCreepIds.push(creep.id);
|
||||||
|
checkNearBy(creep);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,14 +212,23 @@ export function StrongTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
|
|
||||||
if (tower.millisecondsUntilNextShot > 0)
|
if (tower.millisecondsUntilNextShot > 0)
|
||||||
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
let creepsInRange = tower.GetCreepsInRange();
|
else {
|
||||||
if (creepsInRange.length > 0) {
|
let creepsInRange = tower.GetCreepsInRange();
|
||||||
let focus = creepsInRange[0];
|
if (creepsInRange.length > 0) {
|
||||||
if (tower.millisecondsUntilNextShot <= 0) {
|
let focus = creepsInRange[0];
|
||||||
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
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) => {
|
||||||
|
Engine.GameScene.events.emit(CreepEvents.GiveEffect, creep.id, CreepEffects.MovingBackwards, 750);
|
||||||
|
Engine.GameScene.events.emit(
|
||||||
|
CreepEvents.TakenDamage,
|
||||||
|
creep.id,
|
||||||
|
proj.damage / 2,
|
||||||
|
proj.gemResistanceModifications
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,13 +239,14 @@ export function RailTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
|
|
||||||
if (tower.millisecondsUntilNextShot > 0)
|
if (tower.millisecondsUntilNextShot > 0)
|
||||||
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
let creepsInRange = tower.GetCreepsInRange();
|
else {
|
||||||
if (creepsInRange.length > 0) {
|
let creepsInRange = tower.GetCreepsInRange();
|
||||||
let focus = creepsInRange[0];
|
if (creepsInRange.length > 0) {
|
||||||
if (tower.millisecondsUntilNextShot <= 0) {
|
let focus = creepsInRange[0];
|
||||||
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
||||||
|
// Custom logic handled via tower.Shoot
|
||||||
tower.Shoot(calculateAngleToPoint(x, y, focus.x, focus.y));
|
tower.Shoot(calculateAngleToPoint(x, y, focus.x, focus.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,6 +258,42 @@ export function TrapperTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
|
|
||||||
if (tower.millisecondsUntilNextShot > 0)
|
if (tower.millisecondsUntilNextShot > 0)
|
||||||
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
tower.millisecondsUntilNextShot -= elapsedMS * Engine.GameScene.gameSpeedMultiplier;
|
||||||
|
else {
|
||||||
|
if (Engine.GameScene.roundMode != RoundMode.Combat) return;
|
||||||
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
|
let cells = Engine.Grid.GetPathCellsInRange(tower.row, tower.column, tower.computedRange);
|
||||||
|
if (cells.length > 0) {
|
||||||
|
let idx = Math.floor(Math.random() * cells.length);
|
||||||
|
let cell = cells[idx];
|
||||||
|
let cellx = cell.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
|
let celly = cell.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
|
let combinedTint = new PIXI.Color('white');
|
||||||
|
if (tower.slottedGems.length > 0) {
|
||||||
|
let color = new PIXI.Color(tower.slottedGems[0].definition.color);
|
||||||
|
for (let i = 1; i < tower.slottedGems.length; i++) {
|
||||||
|
const element = tower.slottedGems[i];
|
||||||
|
color.multiply(element.definition.color);
|
||||||
|
}
|
||||||
|
combinedTint = color;
|
||||||
|
}
|
||||||
|
let proj = new TrapProjectile(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
tower.definition.projectileTextures,
|
||||||
|
calculateAngleToPoint(x, y, cellx, celly),
|
||||||
|
cellx,
|
||||||
|
celly,
|
||||||
|
tower.computedDamageToDeal,
|
||||||
|
combinedTint,
|
||||||
|
tower.computedTimeToLive,
|
||||||
|
tower.computedPierce,
|
||||||
|
tower.totalGemResistanceModifications
|
||||||
|
);
|
||||||
|
tower.projectiles.push(proj);
|
||||||
|
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DebuffTowerBehaviour(tower: Tower, elapsedMS: number) {
|
export function DebuffTowerBehaviour(tower: Tower, elapsedMS: number) {
|
||||||
@ -248,7 +309,16 @@ export function DebuffTowerBehaviour(tower: Tower, elapsedMS: number) {
|
|||||||
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
|
||||||
tower.millisecondsUntilNextShot = tower.computedCooldown;
|
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) => {
|
||||||
|
Engine.GameScene.events.emit(CreepEvents.GiveEffect, creep.id, CreepEffects.DebuffTowerDebuff, 5000);
|
||||||
|
Engine.GameScene.events.emit(
|
||||||
|
CreepEvents.TakenDamage,
|
||||||
|
creep.id,
|
||||||
|
proj.damage / 1.5,
|
||||||
|
proj.gemResistanceModifications
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import EndGameDialog from '../classes/gui/EndGameDialog';
|
|||||||
import HighScoreDialog, { HighScoreDialogButtons } from '../classes/gui/HighScoreDialog';
|
import HighScoreDialog, { HighScoreDialogButtons } from '../classes/gui/HighScoreDialog';
|
||||||
import GamePausedDialog from '../classes/gui/GamePausedDialog';
|
import GamePausedDialog from '../classes/gui/GamePausedDialog';
|
||||||
|
|
||||||
enum RoundMode {
|
export enum RoundMode {
|
||||||
Purchase = 0,
|
Purchase = 0,
|
||||||
Combat = 1,
|
Combat = 1,
|
||||||
Misc = 2,
|
Misc = 2,
|
||||||
@ -167,7 +167,6 @@ export class GameScene extends Scene {
|
|||||||
|
|
||||||
this.ticker.add(() => {
|
this.ticker.add(() => {
|
||||||
if (this.update) this.update(this.ticker.elapsedMS);
|
if (this.update) this.update(this.ticker.elapsedMS);
|
||||||
// if (this.isFastForwarded) this.update(this.ticker.elapsedMS);
|
|
||||||
});
|
});
|
||||||
this.ticker.start();
|
this.ticker.start();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user