【9】万魂杀服务器开发之特性事件机制

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

java这里实现的事件机制和c++思路比较类似

1.注册关心的事件和处理的handler

2.有一个容器类似于Map管理和维护这个事件

3.触发一个事件的时候,查找容器中的handler,并进行handleEvent

伪代码如下:

/**
 * 游戏事件类伪代码<br />
 * GameObject之间、GameObject的各个功能模块之间以及地图事件都通过游戏事件的方式交互<br />
 *
 * @author
 */
public class GameEvent {
    // ***************************************************
    // *事件源标识*
    // ***************************************************
    public final static byte SOURCE_SELF = 1; // 01
    public final static byte SOURCE_NEIGHBOR = 2;// 10
    public final static byte SOURCE_BOTH = 3;// 11
    // ***************************************************
    // *事件标识*
    // ***************************************************
    public final static short EVENT_NO_DEFINE = 0x0000;// 没有定义
    // 地图相关0x00
    public final static short EVENT_LEAVE_ROOM = 0x0001;// 离开场景
    public final static short EVENT_ENTER_ROOM = 0x0002;// 进入场景
    public final static short EVENT_MOVE = 0x0003;// 移动
    public final static short EVENT_CHANGE_WEATHER = 0x0004;// 改变天气
    public final static short EVENT_FLASH_MOVE = 0x0005;// 瞬移
    public final static short EVENT_DIRECTION = 0x0006;// 转向
    public final static short EVENT_CHANGE_BLOCK = 0x0007;
    public final static short EVENT_PLAYER_MOVE = 0x0008;// 玩家自己移动
    public final static short EVENT_ADD_SPEMONSTOR = 0x0010; // 增加特殊怪
}
//注册事件和回调
player.registerHandler(GameEvent.EVENT_LIFESKILL_BEGINFISH, GameEvent.SOURCE_BOTH, this);
    //map维护
    /**
     * 注册事件实现
     *
     * @param type
     * @param handler
     * @param eventHandlerMap
     */
    private void registerHandler(short type, GameEventHandler handler, TShortObjectHashMap<Collection<GameEventHandler>> eventHandlerMap) {
        Collection<GameEventHandler> hlist = eventHandlerMap.get(type);
        // gust 20101201 防止同步错误
        if (hlist == null) {// 从未注册过
            // 只有使用copyonwrite来防止同步问题,性能较低
            hlist = new CopyOnWriteArraySet<>();// CopyOnWriteArrayList
            hlist.add(handler);
            eventHandlerMap.put(type, hlist);
        } else if (!hlist.contains(handler)) {// 有可能再来
            hlist.add(handler);
        }
        addCount++;
    }
//这里需要注意多线程问题
//触发事件
GameEvent event = new GameEvent(GameEvent.EVENT_LIFESKILL_BEGINFISH, player, (byte) 0);
player.handleAndNotifyEvent(event);
   //在注册的handler中实现接口handleEvent进行事件处理
   @Override
    public void handleEvent(GameEvent event) {
        switch (event.getType()) {
            case GameEvent.EVENT_LIFESKILL_BEGINFISH:
                GameObject src = event.getSource();
                byte type = (Byte) event.getParameter(0);
                if (src != player) {
                    CmdPkg pkg = new CmdPkg(WXProtocol.S_LIFESKILL_FISH);
                    pkg.writeLong(src.getId());// 发技能者
                    pkg.writeByte((Byte) event.getParameter(0));
                    player.send(pkg);
                }
                break;
}

在该项目中事件机制值得借鉴的地方:

1.事件机制支持配置的方式。即很多事件除了代码定义还运行通过配置进行新增。当事件触发后(策划配置事件触发时机,这里需要先了解condition和trigger) 可以响应对应的触发器

    ps:在触发器中有一个叫着事件触发器。策划配置后,当条件满足,该触发器会被调用,触发器内部会触发之前配置好ID的事件,同时如果在eventConfig.xml中配置了该事件的关注者,则内部触发器又会被触发。这样带来的灵活性很大,对于程序而言,基本上把流程控制的工作全部交给了策划。这对策划的逻辑严密有很高的要求。避免出现死循环。

在该项目中事件机制需要避免的地方:

事件必须绑定到某一个gameobj上,同时必须清楚的知道事件的作用范围是self 还是neighbors。其实没必要这么处理。

 

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看