feat: migrate JavaScript files to TypeScript, enhancing type safety and maintainability across the codebase
This commit is contained in:
parent
3db2bb9160
commit
c582f2004e
107 changed files with 5876 additions and 3588 deletions
107
src/systems/ProjectileSystem.ts
Normal file
107
src/systems/ProjectileSystem.ts
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import { System } from '../core/System.ts';
|
||||
import { Events } from '../core/EventBus.ts';
|
||||
import { Palette } from '../core/Palette.ts';
|
||||
import { SystemName, ComponentType } from '../core/Constants.ts';
|
||||
import type { Entity } from '../core/Entity.ts';
|
||||
import type { Health } from '../components/Health.ts';
|
||||
import type { Position } from '../components/Position.ts';
|
||||
import type { Velocity } from '../components/Velocity.ts';
|
||||
import type { VFXSystem } from './VFXSystem.ts';
|
||||
|
||||
/**
|
||||
* System responsible for managing projectile movement, range limits, lifetimes, and collisions.
|
||||
*/
|
||||
export class ProjectileSystem extends System {
|
||||
constructor() {
|
||||
super(SystemName.PROJECTILE);
|
||||
this.requiredComponents = [ComponentType.POSITION, ComponentType.VELOCITY];
|
||||
this.priority = 18;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process logic for all projectiles, checking for range, lifetime, and target collisions.
|
||||
* @param deltaTime - Time elapsed since last frame in seconds
|
||||
* @param entities - Entities matching system requirements
|
||||
*/
|
||||
process(deltaTime: number, entities: Entity[]): void {
|
||||
entities.forEach((entity) => {
|
||||
const health = entity.getComponent<Health>(ComponentType.HEALTH);
|
||||
if (!health || !health.isProjectile) return;
|
||||
|
||||
const position = entity.getComponent<Position>(ComponentType.POSITION);
|
||||
if (!position) return;
|
||||
|
||||
if (
|
||||
entity.startX !== undefined &&
|
||||
entity.startY !== undefined &&
|
||||
entity.maxRange !== undefined
|
||||
) {
|
||||
const dx = position.x - entity.startX;
|
||||
const dy = position.y - entity.startY;
|
||||
const distanceTraveled = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distanceTraveled >= entity.maxRange) {
|
||||
this.engine.removeEntity(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.lifetime !== undefined) {
|
||||
entity.lifetime -= deltaTime;
|
||||
if (entity.lifetime <= 0) {
|
||||
this.engine.removeEntity(entity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const allEntities = this.engine.getEntities();
|
||||
allEntities.forEach((target) => {
|
||||
if (target.id === entity.owner) return;
|
||||
if (target.id === entity.id) return;
|
||||
if (!target.hasComponent(ComponentType.HEALTH)) return;
|
||||
const targetHealth = target.getComponent<Health>(ComponentType.HEALTH);
|
||||
if (targetHealth && targetHealth.isProjectile) return;
|
||||
|
||||
const targetPos = target.getComponent<Position>(ComponentType.POSITION);
|
||||
if (!targetPos) return;
|
||||
|
||||
const dx = targetPos.x - position.x;
|
||||
const dy = targetPos.y - position.y;
|
||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distance < 8) {
|
||||
const targetHealthComp = target.getComponent<Health>(ComponentType.HEALTH);
|
||||
const damage = entity.damage || 10;
|
||||
if (targetHealthComp) {
|
||||
targetHealthComp.takeDamage(damage);
|
||||
|
||||
const vfxSystem = this.engine.systems.find((s) => s.name === SystemName.VFX) as
|
||||
| VFXSystem
|
||||
| undefined;
|
||||
const velocity = entity.getComponent<Velocity>(ComponentType.VELOCITY);
|
||||
if (vfxSystem) {
|
||||
const angle = velocity ? Math.atan2(velocity.vy, velocity.vx) : null;
|
||||
vfxSystem.createImpact(position.x, position.y, Palette.CYAN, angle);
|
||||
}
|
||||
|
||||
if (targetHealthComp.isDead()) {
|
||||
this.engine.emit(Events.ENTITY_DIED, { entity: target });
|
||||
}
|
||||
}
|
||||
|
||||
this.engine.removeEntity(entity);
|
||||
}
|
||||
});
|
||||
|
||||
const canvas = this.engine.canvas;
|
||||
if (
|
||||
position.x < 0 ||
|
||||
position.x > canvas.width ||
|
||||
position.y < 0 ||
|
||||
position.y > canvas.height
|
||||
) {
|
||||
this.engine.removeEntity(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue