猫史档案馆


【代码岛三】重写EventEmitter

用户:ray_crazyray_crazy查看:178 回复:3 评论:26 创建时间:2022-03-15T20:46:45


由于岛三没有内置EventEmitter,于是我写了个EventEmitter类,帮助萌新直接使用

class EventEmitter {
    constructor() {
        this.listeners = {};
    }
    addListener(eventName, callback) {
        if (!this.listeners[eventName]) {
            this.listeners[eventName] = [];
        };
        this.listeners[eventName].push(callback);
    };

    emit(eventName, ...args) {
        if (this.listeners[eventName]) {
            this.listeners[eventName].forEach(callBack => {
                callBack(...args);
            })
        }
    };

    on(eventName, callback) {
        this.addListener(eventName, callback);
    };

    off(eventName, callback) {
        if (this.listeners[eventName]) {
            const targetIndex = this.listeners[eventName].findIndex(item => item === callback);
            if (targetIndex !== -1) {
                this.listeners[eventName].splice(targetIndex, 1);
            };
            if (this.listeners[eventName].length === 0) {
                delete this.listeners[eventName];
            };
        };
    };

    offAll(eventName) {
        if (this.listeners[eventName]) {
            delete this.listeners[eventName];
        };
    };

}

直接拿去用,基本常用的方法都实现了,这是个例子

// 创建EventEmitter
const worldEvent = new EventEmitter();
// 将事件对应过去
world.onPlayerJoin(event => {
    worldEvent.emit("onPlayerJoin", event);
});
world.onChat(event => {
    worldEvent.emit("onChat", event);
});
// 注册事件触发器
worldEvent.on("onPlayerJoin", ({ entity }) => {
    console.log("玩家加入:" + entity.player.name);
});
// 用addListener也可以
worldEvent.addListener("onChat", ({ message, entity }) => {
    console.log("玩家 " + entity.player.name + " 说了话: " + message);
});

非常简单好用


回复

上一页第 1 页 / 共 1 页下一页
该账号已停用该账号已停用

EventEmitter是啥子玩意儿

点赞2


评论

nodejs内置类啊,我搞错了吗?

啊这看来我太逊了*(没听说这玩意儿)


星星上的雪花星星上的雪花

多此一举。

正常人写的代码做出的效果,你却用了10倍的代码。除了冗杂就是累赘

点赞0


评论

冷静点

主要我们的方向不同,你是面对过程,我是面对对象,各有各的好处,分道扬镳吧

我这样是为了避免过多的重复,同时事件触发也有执行的顺序

底层实现的在某些时候会跑的更快,虽然岛3基本上不要求时间跑得快() 有的时候,很多东西库里实现的会差点(所以很多题必须手写栈/队列)

我是为了重写onTick事件,顺便把其他事件也弄上了

虽然说写这个的喵作用更大一些(bushi)

喵是什么

喵=装bi(?)

《除了冗杂就是累赘》差点信了

不是为了这个,是为了让其他人看懂,不像官方的代码,一塌糊涂,解释就要10分钟

话说真的可以喵()(),看起来好高级()()

我人机根本做不到()()

高级个锤子)

你学一下面对对象(就是类)一下就懂了,非常简单

developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes

我说我懒得学信不信()()

c/ao

我去学习亿下()()

主要是我c++的结构体没好好学,应该是差不多的()()

c++我就没仔细学()()

怎么可能多此一举,以后写代码你不这样写别人打你

我现在就不这样写

你仙子啊可以不这样写,1.会卡2.以后这样不方便,显得不专业

你直接那样写小心别人打s你


ray_crazyray_crazy

将Entity的事件也注册好了,附赠一个写好的事件控制器和一个使用示例

// Events
class EventEmitter {
    constructor() {
        this.listeners = {};
        this.onceListeners = {};
    }
    addListener(eventName, callback) {
        if (!this.listeners[eventName]) {
            this.listeners[eventName] = [];
        };
        this.listeners[eventName].push(callback);
    };

    emit(eventName, ...args) {
        if (this.listeners[eventName]) {
            this.listeners[eventName].forEach(callBack => {
                callBack(...args);
            });
        };
        if (this.onceListeners[eventName]) {
            this.onceListeners[eventName].forEach((callBack, k) => {
                callBack(...args);
                delete this.onceListeners[eventName][k];
            });
        };
    };

    on(eventName, callback) {
        this.addListener(eventName, callback);
    };

    once(eventName, callback) {
        if (!this.onceListeners[eventName]) {
            this.onceListeners[eventName] = [];
        };
        this.onceListeners[eventName].push(callback);
    }

    off(eventName, callback) {
        if (this.listeners[eventName]) {
            const targetIndex = this.listeners[eventName].findIndex(item => item === callback);
            if (targetIndex !== -1) {
                this.listeners[eventName].splice(targetIndex, 1);
            };
            if (this.listeners[eventName].length === 0) {
                delete this.listeners[eventName];
            };
        };
    };

    offAll(eventName) {
        if (this.listeners[eventName]) {
            delete this.listeners[eventName];
        };
    };

}

class EventManager {
    constructor() {
        this.worldEvent = new EventEmitter();
        this.entityEvent = new EventEmitter();
        this.tick = 0;
        this.prevTick = 0;
        this.skip = false;
        this.elapsedTimeMS = 1 / 喵;

    }
    registerWorldEvent() {
        world.onPlayerJoin(event => {
            this.worldEvent.emit("onPlayerJoin", event);
        });
        world.onPlayerLeave(event => {
            this.worldEvent.emit("onPlayerLeave", event);
        });
        world.onChat(event => {
            this.worldEvent.emit("onChat", event);
        });
        world.onInteract(event => {
            this.worldEvent.emit("onInteract", event);
        });
        world.onPress(event => {
            this.worldEvent.emit("onPress", event);
        });
        world.onClick(event => {
            this.worldEvent.emit("onClick", event);
        });
        world.onRelease(event => {
            this.worldEvent.emit("onRelease", event);
        });
        world.onEntityCreate(event => {
            this.worldEvent.emit("onEntityCreate", event);
        });
        world.onEntityContact(event => {
            this.worldEvent.emit("onEntityContact", event);
        });
        world.onEntityDestroy(event => {
            this.worldEvent.emit("onEntityDestroy", event);
        });
        world.onEntitySeparate(event => {
            this.worldEvent.emit("onEntitySeparate", event);
        });
        world.onDie(event => {
            this.worldEvent.emit("onDie", event);
        });
        world.onRespawn(event => {
            this.worldEvent.emit("onRespawn", event);
        });
        setInterval(() => {
            this.tick += 1;
            this.worldEvent.emit("onTick", new Box3TickEvent(this.tick, this.prevTick, this.skip, this.elapsedTimeMS));
            this.prevTick += 1;
        }, 1 / 喵);
    }
    registerEntityEvent(entity) {
        entity.onClick(event => {
            this.entityEvent.emit("onClick", entity, event);
        });
        entity.onDestroy(event => {
            this.entityEvent.emit("onDestroy", entity, event);
        });
        entity.onDie(event => {
            this.entityEvent.emit("onDie", entity, event);
        });
        entity.onEntityContact(event => {
            this.entityEvent.emit("onEntityContact", entity, event);
        });
        entity.onEntitySeparate(event => {
            this.entityEvent.emit("onEntitySeparate", entity, event);
        });
        entity.onVoxelContact(event => {
            this.entityEvent.emit("onVoxelContact", entity, event);
        });
        entity.onVoxelSeparate(event => {
            this.entityEvent.emit("onVoxelSeparate", entity, event);
        });
        entity.onFluidEnter(event => {
            this.entityEvent.emit("onFluidEnter", entity, event);
        });
        entity.onFluidLeave(event => {
            this.entityEvent.emit("onFluidLeave", entity, event);
        });
    }
}
class WorldEventController extends EventManager {
    static instance;
    static GetInstance() {
        if (!this.instance) this.instance = new WorldEventController();
        return this.instance;
    }

    constructor() { 
        super();
        this.registerWorldEvent();
    }
}
class EntityEventController extends EventManager {
    constructor(entity) {
        super();
        this.registerEntityEvent(entity);
    }
}

// 示例
const worldEventController = WorldEventController.GetInstance();
worldEventController.worldEvent.on("onEntityCreate",({entity})=>{
    entity.eventManager = new EntityEventController(entity);
})

点赞0


评论