Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FOV #76

Open
JernejHabjan opened this issue May 7, 2023 · 1 comment
Open

FOV #76

JernejHabjan opened this issue May 7, 2023 · 1 comment

Comments

@JernejHabjan
Copy link
Owner

https://blog.ourcade.co/posts/2020/phaser3-mrpas-fov-field-of-view-algorithm-roguelike-dungeon-crawler/

@JernejHabjan
Copy link
Owner Author

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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant