83 lines
2.6 KiB
JavaScript
83 lines
2.6 KiB
JavaScript
import { System } from '../core/System.js';
|
|
|
|
export class ProjectileSystem extends System {
|
|
constructor() {
|
|
super('ProjectileSystem');
|
|
this.requiredComponents = ['Position', 'Velocity'];
|
|
this.priority = 18;
|
|
}
|
|
|
|
process(deltaTime, entities) {
|
|
const playerController = this.engine.systems.find(s => s.name === 'PlayerControllerSystem');
|
|
const _player = playerController ? playerController.getPlayerEntity() : null;
|
|
|
|
entities.forEach(entity => {
|
|
const health = entity.getComponent('Health');
|
|
if (!health || !health.isProjectile) return;
|
|
|
|
const position = entity.getComponent('Position');
|
|
if (!position) return;
|
|
|
|
// Check range - remove if traveled beyond max range
|
|
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;
|
|
}
|
|
}
|
|
|
|
// Check lifetime as backup
|
|
if (entity.lifetime !== undefined) {
|
|
entity.lifetime -= deltaTime;
|
|
if (entity.lifetime <= 0) {
|
|
this.engine.removeEntity(entity);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Check collisions with enemies
|
|
const allEntities = this.engine.getEntities();
|
|
allEntities.forEach(target => {
|
|
if (target.id === entity.owner) return;
|
|
if (target.id === entity.id) return;
|
|
if (!target.hasComponent('Health')) return;
|
|
if (target.getComponent('Health').isProjectile) return;
|
|
|
|
const targetPos = target.getComponent('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 < 20) {
|
|
// Hit!
|
|
const targetHealth = target.getComponent('Health');
|
|
const damage = entity.damage || 10;
|
|
targetHealth.takeDamage(damage);
|
|
|
|
// If target is dead, mark it for immediate removal
|
|
if (targetHealth.isDead()) {
|
|
target.active = false;
|
|
// DeathSystem will handle removal
|
|
}
|
|
|
|
// Remove projectile
|
|
this.engine.removeEntity(entity);
|
|
}
|
|
});
|
|
|
|
// Boundary check
|
|
const canvas = this.engine.canvas;
|
|
if (position.x < 0 || position.x > canvas.width ||
|
|
position.y < 0 || position.y > canvas.height) {
|
|
this.engine.removeEntity(entity);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|