Open JernejHabjan opened 1 year ago
Something like this
class VisibilityManager {
constructor(scene, tilemap, actors) {
this.scene = scene;
this.tilemap = tilemap;
this.actors = actors;
this.playerActors = [];
this.enemyActors = [];
// Set up event listeners
this.scene.events.on('actorCreated', this.handleActorCreated, this);
this.scene.events.on('actorRemoved', this.handleActorRemoved, this);
this.scene.events.on('actorMoved', this.handleActorMoved, this);
// Initialize visibility
this.updateVisibility();
}
updateVisibility() {
// Clear all visibility
this.clearVisibility();
// Update visibility based on player and enemy actors
this.updatePlayerVisibility();
this.updateEnemyVisibility();
}
clearVisibility() {
// Hide all tiles and enemy buildings
this.tilemap.forEachTile(tile => {
tile.visible = false;
});
this.actors.forEach(actor => {
if (actor.owner === 'enemy') {
actor.setVisible(false);
}
});
}
updatePlayerVisibility() {
this.playerActors.forEach(actor => {
if (actor.hasVisionComponent) {
const visionRange = actor.visionRange;
this.tilemap.forEachTile(tile => {
if (this.isInVisionRange(actor, tile)) {
tile.visible = true;
}
});
this.actors.forEach(otherActor => {
if (otherActor !== actor && this.isInVisionRange(actor, otherActor)) {
otherActor.setVisible(true);
}
});
}
});
}
updateEnemyVisibility() {
const canSeeEnemy = (enemyActor) => {
return this.playerActors.some(playerActor => this.isInVisionRange(playerActor, enemyActor));
};
this.actors.forEach(actor => {
if (actor.owner === 'enemy') {
actor.setVisible(canSeeEnemy(actor));
}
});
}
isInVisionRange(actor, target) {
const distance = Phaser.Math.Distance.Between(actor.x, actor.y, target.x, target.y);
return distance <= actor.visionRange;
}
handleActorCreated(actor) {
// Add actor to appropriate list and update visibility
if (actor.owner === 'player') {
this.playerActors.push(actor);
} else if (actor.owner === 'enemy') {
this.enemyActors.push(actor);
}
this.updateVisibility();
}
handleActorRemoved(actor) {
// Remove actor from list and update visibility
if (actor.owner === 'player') {
this.playerActors = this.playerActors.filter(a => a !== actor);
} else if (actor.owner === 'enemy') {
this.enemyActors = this.enemyActors.filter(a => a !== actor);
}
this.updateVisibility();
}
handleActorMoved(actor) {
// Update visibility after movement
this.updateVisibility();
}
}
// Usage:
// Assuming `scene`, `tilemap`, and `actors` are already defined
const visibilityManager = new VisibilityManager(scene, tilemap, actors);
https://blog.ourcade.co/posts/2020/phaser3-mrpas-fov-field-of-view-algorithm-roguelike-dungeon-crawler/