Auto-targeting
Files
FileDirectory
  • Directorysrc[+]
    • DirectoryExcalibur[+]
      • DirectoryComponent[+]
        • FileBaseComponent.ts
          • FileChasesTargetComponent.ts
            • FileHasTargetComponent.ts
              • FileSearchesTargetComponent.ts
              • DirectoryScene[+]
                • FileAutoTargetingScene.ts
            • Fileindex.html
              • Fileindex.tsentry
                • Filepackage.json
                  • Filesandbox.config.json
                    • Filestyles.css
                      • Filetsconfig.json
                        import {AutoTargetingScene} from "@avalon/Excalibur/Scene/AutoTargetingScene";
                        import {Engine} from "excalibur";
                        
                        const canvasElement = document.createElement('canvas');
                        document.body.appendChild(canvasElement);
                        
                        const engine = new Engine({
                            canvasElement,
                            scenes: {
                                example: new AutoTargetingScene(),
                            }
                        });
                        
                        engine
                            .start('example')
                            .then(() => console.log('✅ Engine started!'));
                        
                        

                        src/registry/Excalibur/Component/SearchesTargetComponent.ts
                        1
                        import {BaseComponent} from @avalon/Excalibur/Component/BaseComponent;
                        2
                        import {HasTargetComponent} from @avalon/Excalibur/Component/HasTargetComponent;
                        3
                        import {Actor, PreUpdateEvent, TagQuery} from "excalibur";
                        4
                        5
                        export class SearchesTargetComponent extends BaseComponent {
                        6
                        private readonly queryTags: string[];
                        7
                        private readonly maxDistance?: number;
                        8
                        private query!: TagQuery<string>;
                        9
                        private nextCheck: number = 0;
                        10
                        11
                        constructor({queryTags, maxDistance}: { queryTags: string[], maxDistance?: number }) {
                        12
                        super();
                        13
                        14
                        this.queryTags = queryTags;
                        15
                        this.maxDistance = maxDistance;
                        16
                        this.on('preupdate', this.onPreUpdate.bind(this));
                        17
                        }
                        18
                        19
                        onPreUpdate({engine, delta}: PreUpdateEvent): void {
                        20
                        const owner = this.owner;
                        21
                        if (!owner) {
                        22
                        return;
                        23
                        }
                        24
                        25
                        this.nextCheck -= delta;
                        26
                        if (owner.has(HasTargetComponent) && this.nextCheck > 0) {
                        27
                        return;
                        28
                        }
                        29
                        30
                        if (!this.query) {
                        31
                        this.query = engine.currentScene.world.queryTags(this.queryTags);
                        32
                        }
                        33
                        34
                        let minDistance: number = Infinity;
                        35
                        let closestTarget: Actor | undefined;
                        36
                        37
                        for (const target of this.query?.entities ?? []) {
                        38
                        if (!(target instanceof Actor)) {
                        39
                        continue;
                        40
                        }
                        41
                        42
                        const distance = owner.pos.distance(target.pos);
                        43
                        if (this.maxDistance && distance > this.maxDistance) {
                        44
                        continue;
                        45
                        }
                        46
                        47
                        if (distance >= minDistance) {
                        48
                        continue;
                        49
                        }
                        50
                        51
                        minDistance = distance;
                        52
                        closestTarget = target;
                        53
                        }
                        54
                        55
                        this.nextCheck = 1000;
                        56
                        57
                        if (!closestTarget || owner.get(HasTargetComponent)?.target === closestTarget) {
                        58
                        return;
                        59
                        }
                        60
                        61
                        owner.addComponent(new HasTargetComponent(closestTarget), true);
                        62
                        }
                        63
                        }