Implementing fast-forward

This commit is contained in:
Dalibor Čarapić 2025-02-10 17:10:15 +01:00
parent f1148e1d07
commit 5e8b91ed81
6 changed files with 31 additions and 20 deletions

View File

@ -36,7 +36,7 @@ export class Engine {
Engine.NotificationManager.Notify('Loaded testing suite.', 'danger');
Engine.TowerManager.ToggleChoosingTowerLocation('RESET');
Engine.TowerManager.PlaceTower(GameAssets.Towers[1], 6, 10, GameAssets.Towers[1].behaviour, true);
Engine.TowerManager.PlaceTower(GameAssets.Towers[0], 6, 10, GameAssets.Towers[0].behaviour, true);
for (let i = 0; i < 29; i++) {
this.GameScene.MissionStats.giveGem(new Gem(i % 4), true);
}

View File

@ -131,8 +131,8 @@ export default class Creep extends GameObject {
this.sprite.scale.x *= -1;
}
}
let deltaX = this.speed * elapsedMS * directionX;
let deltaY = this.speed * elapsedMS * directionY;
let deltaX = this.speed * elapsedMS * directionX * Engine.GameScene.gameSpeedMultiplier;
let deltaY = this.speed * elapsedMS * directionY * Engine.GameScene.gameSpeedMultiplier;
let increaseIndex = false;
if (deltaX > 0 && this.x + deltaX > targetX) {

View File

@ -39,7 +39,7 @@ export default class Projectile extends GameObject {
super();
this.x = x;
this.y = y;
this.timeToLive = timeToLive;
this.timeToLive = timeToLive * (0.9 / 0.1);
this.pierce = pierce;
this.damage = damage;
this.gemResistanceModifications = gemResistanceModifications;
@ -53,7 +53,7 @@ export default class Projectile extends GameObject {
Engine.GameMaster.currentScene.stage.addChild(this.container);
this.angle = angle;
this.speed = 0.9;
this.speed = 0.1;
}
public destroy(): void {
super.destroy();
@ -64,7 +64,7 @@ export default class Projectile extends GameObject {
if (this.deleteMe) return;
if (this.x > 2000 || this.x < 0 || this.y > 2000 || this.y < 0 || this.pierce <= 0 || this.timeToLive <= 0)
return this.destroy();
this.timeToLive--;
this.timeToLive -= Engine.GameScene.gameSpeedMultiplier;
Engine.Grid.creeps.forEach((creep) => {
if (this.pierce <= 0) return;
if (creep && creep.container && this.checkCollision(creep)) {
@ -77,14 +77,20 @@ export default class Projectile extends GameObject {
}
}
});
this.x += Math.cos(this.angle) * this.speed * elapsedMS;
this.y += Math.sin(this.angle) * this.speed * elapsedMS;
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;
}
public onCollide(creep) {
/*
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);
}

View File

@ -75,14 +75,14 @@ export function computeGemImprovements(tower: Tower) {
export function BasicTowerBehaviour(tower: Tower, elapsedMS: number) {
if (tower.ticksUntilNextShot % 2 == 0) computeGemImprovements(tower);
projectileCheck(tower, elapsedMS);
if (tower.ticksUntilNextShot > 0) tower.ticksUntilNextShot--;
if (tower.ticksUntilNextShot > 0) tower.ticksUntilNextShot -= Engine.GameScene.gameSpeedMultiplier;
let creepsInRange = tower.GetCreepsInRange();
if (creepsInRange.length > 0) {
let focus = creepsInRange[0];
if (tower.ticksUntilNextShot <= 0) {
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
tower.ticksUntilNextShot = tower.computedAttackSpeed;
tower.ticksUntilNextShot = tower.computedAttackSpeed / Engine.GameScene.gameSpeedMultiplier;
tower.Shoot(calculateAngleToPoint(x, y, focus.x, focus.y));
}
}
@ -91,12 +91,12 @@ export function BasicTowerBehaviour(tower: Tower, elapsedMS: number) {
export function CircleTowerBehaviour(tower: Tower, elapsedMS: number) {
if (tower.ticksUntilNextShot % 2 == 0) computeGemImprovements(tower);
projectileCheck(tower, elapsedMS);
if (tower.ticksUntilNextShot > 0) tower.ticksUntilNextShot--;
if (tower.ticksUntilNextShot > 0) tower.ticksUntilNextShot -= Engine.GameScene.gameSpeedMultiplier;
let creepsInRange = tower.GetCreepsInRange();
if (creepsInRange.length > 0) {
let focus = creepsInRange[0];
if (tower.ticksUntilNextShot <= 0) {
tower.ticksUntilNextShot = tower.computedAttackSpeed;
tower.ticksUntilNextShot = tower.computedAttackSpeed / Engine.GameScene.gameSpeedMultiplier;
let x = tower.column * Engine.GridCellSize + Engine.GridCellSize / 2;
let y = tower.row * Engine.GridCellSize + Engine.GridCellSize / 2;
tower.Shoot(calculateAngleToPoint(x, y, x, y + 10)); // Up

View File

@ -60,7 +60,7 @@ export default class WaveManager extends GameObject {
}
public update(elapsedMS: number): void {
if (this.started == false) return;
this.ticks += elapsedMS;
this.ticks += elapsedMS * Engine.GameScene.gameSpeedMultiplier;
this.creeps.forEach((creep) => {
if (!creep.spawned && creep.tickToSpawnAt <= this.ticks) {
creep.spawned = true;

View File

@ -38,7 +38,8 @@ export class GameScene extends Scene {
public tooltip: Tooltip;
public towerPanel: TowerPanel;
public isPaused: boolean = false;
private isFastForwarded: boolean = false;
public gameSpeedMultiplier: number = 1;
private pauseButton: Button;
private visualGems: VisualGemSlot[] = [];
private currentRound: number = 0;
@ -106,14 +107,12 @@ export class GameScene extends Scene {
this.changeRoundButton.onClick = () => {
if (this.playerWon) return this.ReturnToMain();
if (this.roundMode == RoundMode.Combat) {
// TODO: figure out how to actually double speed without causing bugs.
if (this.isFastForwarded) {
this.isFastForwarded = false;
Engine.NotificationManager.Notify('Regular speed.', 'info');
if (this.gameSpeedMultiplier !== 1) {
this.UpdateGameSpeedMultiplier(1);
} else {
this.isFastForwarded = true;
Engine.NotificationManager.Notify('Fast forward activated.', 'info');
this.UpdateGameSpeedMultiplier(2);
}
return;
}
if (this.isGameOver) return Engine.NotificationManager.Notify('No more waves.', 'danger');
if (this.roundMode == RoundMode.Misc) return;
@ -341,4 +340,10 @@ export class GameScene extends Scene {
private ReturnToMain() {
Engine.GameMaster.changeScene(new MissionPickerScene());
}
private UpdateGameSpeedMultiplier(newMultiplier: number) {
this.gameSpeedMultiplier = newMultiplier;
if (newMultiplier === 1) Engine.NotificationManager.Notify('Regular speed.', 'info');
else Engine.NotificationManager.Notify('Fast forward activated.', 'info');
}
}