游戏开发中的事件机制Java实现
2013-11-22 21:28
573 查看
游戏开发中,游戏逻辑往往很复杂,互相交织在一起,需要开发者进行良好的设计加以维护。因此运用一定的设计模式往往能起到良好的效果。
最近在使用Java开发一款安卓游戏的时候,设计并实现了一套事件处理机制,用以分离游戏逻辑中的关注点,提升游戏的维护性和扩展性。
其实现仅仅为一个Java文件,代码仅150行左右,并不依赖于任何外部库和游戏引擎,只要编程环境为Java,并且你的游戏框架是基于游戏循环机制,就能使用。
该实现非常轻量级,我不保证其效率和设计在任何一个款游戏设计中都能很好的运用,但是至少在我的游戏里它一直工作的很好,也帮助我解决了不少设计问题,所以仅供学习分享。
同时它并不是线程安全的,所以请确保在同一个线程调用方法。如果你需要多线程安全,可以改写它。但根据我的经验,很少需要多线程这种情况。
使用说明:
1、首先需要创建RootEventManager(EventManager的内部类,同时也继承于EventManager)
2、EventManager通过方法setParentEventManager可以组织成树状结构,但是RootEventManager对象必须作为根节点
3、在游戏的循环中调用RootEventManager的onUpdate()方法
4、接下来就可以在各个EventManager里面注册监听器(IEventListener)以及监听规则,可以按Event的类型、事件源、事件源类型、事件标示过滤需要接受的事件。
5、通过EventManager的postEvent方法可以派发事件,子EventManager的事件会派发到父EventManager中。
6、CauseEvent是事件的引发关系,类似异常链,如果不需要的话置为null
可能说的比较笼统,大家可以直接看源码体会,源码利用泛型和反射机制,也是不错的示范学习材料。
附上源码:
最近在使用Java开发一款安卓游戏的时候,设计并实现了一套事件处理机制,用以分离游戏逻辑中的关注点,提升游戏的维护性和扩展性。
其实现仅仅为一个Java文件,代码仅150行左右,并不依赖于任何外部库和游戏引擎,只要编程环境为Java,并且你的游戏框架是基于游戏循环机制,就能使用。
该实现非常轻量级,我不保证其效率和设计在任何一个款游戏设计中都能很好的运用,但是至少在我的游戏里它一直工作的很好,也帮助我解决了不少设计问题,所以仅供学习分享。
同时它并不是线程安全的,所以请确保在同一个线程调用方法。如果你需要多线程安全,可以改写它。但根据我的经验,很少需要多线程这种情况。
使用说明:
1、首先需要创建RootEventManager(EventManager的内部类,同时也继承于EventManager)
2、EventManager通过方法setParentEventManager可以组织成树状结构,但是RootEventManager对象必须作为根节点
3、在游戏的循环中调用RootEventManager的onUpdate()方法
4、接下来就可以在各个EventManager里面注册监听器(IEventListener)以及监听规则,可以按Event的类型、事件源、事件源类型、事件标示过滤需要接受的事件。
5、通过EventManager的postEvent方法可以派发事件,子EventManager的事件会派发到父EventManager中。
6、CauseEvent是事件的引发关系,类似异常链,如果不需要的话置为null
可能说的比较笼统,大家可以直接看源码体会,源码利用泛型和反射机制,也是不错的示范学习材料。
附上源码:
package cn.edu.zucc.util.event; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Queue; import java.util.Set; public class EventManager { static public class RootEventManager extends EventManager { public void onUpdate() { super.onUpdate(); } } private HashMap<IEventListener<?>, Object[]> mEventListenerRegisterMap = new HashMap<IEventListener<?>, Object[]>(); private Queue<IEvent<?, ?>> mEventQueue = new LinkedList<IEvent<?, ?>>(); private List<EventManager> mChildrenEventManager = new ArrayList<EventManager>(); private EventManager mParentEventManager; public void postEvent(final IEvent<?, ?> pEvent){ if(pEvent == null) return; mEventQueue.offer(pEvent); if(mParentEventManager != null) mParentEventManager.postEvent(pEvent); } @SuppressWarnings("unchecked") private void onUpdate() { IEvent<?, ?> event = mEventQueue.poll(); Object source; Class<? extends Object> sourceClass; Class<? extends IEvent<?, ?>> eventClass; int eventFlag; while(event != null){ Map<IEventListener<?>, Object[]> eventListenerRegisterMap = (Map<IEventListener<?>, Object[]>) mEventListenerRegisterMap.clone(); Set<Entry<IEventListener<?>, Object[]>> entrys = eventListenerRegisterMap.entrySet(); for(Entry<IEventListener<?>, Object[]> entry : entrys){ Object[] info = entry.getValue(); IEventListener<IEvent<?, ?>> eventListener = (IEventListener<IEvent<?, ?>>) entry.getKey(); source = info[0]; sourceClass = (Class<? extends Object>) info[1]; eventClass = (Class<? extends IEvent<?, ?>>) info[2]; eventFlag = (Integer) info[3]; if((source == null || event.getSource() == source) && (sourceClass == null || sourceClass.isAssignableFrom(event.getSource().getClass())) && (eventFlag == 0 || event.getEventFlag() == eventFlag) && (eventClass == null || eventClass.isAssignableFrom(event.getClass()))){ eventListener.onAction(event, this); } } event = mEventQueue.poll(); } for(EventManager childEventManager : mChildrenEventManager){ childEventManager.onUpdate(); } } public interface IEventListener<E extends IEvent<?, ?>>{ void onAction(E pEvent, EventManager pEventManager); } public interface IEvent<S, E extends IEvent<?, ?>>{ Object getSource(); int getEventFlag(); E getCauseEvent(); } static abstract public class BaseEvent<S, E extends IEvent<?, ?>> implements IEvent<S, E>{ private S mSource; private int mEventFlag; private E mCauseEvent; public BaseEvent(final S pSource, int pEventFlag, E pCauseEvent){ mSource = pSource; mEventFlag = pEventFlag; mCauseEvent = pCauseEvent; } public BaseEvent(final S pSource, E pCauseEvent){ this(pSource, 0, pCauseEvent); } public BaseEvent(final S pSource, int pEventFlag){ this(pSource, pEventFlag, null); } public BaseEvent(final S pSource){ this(pSource, 0); } @Override public S getSource() { return mSource; } @Override public int getEventFlag() { return mEventFlag; } @Override public E getCauseEvent() { return mCauseEvent; } } public void registerEventListenerByEventClass(final IEventListener<? extends IEvent<?, ?>> pEventListener , final Class<? extends IEvent<?, ?>> pEventClass){ registerEventListener(pEventListener, pEventClass, 0, null, null); } public void registerEventListenerByEventFlag(final IEventListener<IEvent<?, ?>> pEventListener , final int pEventFlag){ registerEventListener(pEventListener, null, pEventFlag, null, null); } public void registerEventListenerBySourceClass(final IEventListener<IEvent<?, ?>> pEventListener , final Class<? extends Object> pSourceClass){ registerEventListener(pEventListener, null, 0, pSourceClass, null); } public void registerEventListenerBySource(final IEventListener<IEvent<?, ?>> pEventListener , final Object pSource){ registerEventListener(pEventListener, null, 0, null, pSource); } public void registerEventListener(final IEventListener<?> pEventListener , final Class<? extends IEvent<?, ?>> pEventClass , final int pEventFlag , final Class<? extends Object> pSourceClass , final Object pSource){ mEventListenerRegisterMap.put(pEventListener, new Object[]{pSource, pSourceClass, pEventClass, pEventFlag}); } public void unregisterEventListener(final IEventListener<?> pEventListener){ mEventListenerRegisterMap.remove(pEventListener); } public void cleanEventListener(){ mEventListenerRegisterMap.clear(); } public void setParentEventManager(EventManager pParentEventManager){ if(mParentEventManager != null) mParentEventManager.mChildrenEventManager.remove(this); if(pParentEventManager != null) pParentEventManager.mChildrenEventManager.add(this); mParentEventManager = pParentEventManager; } }
相关文章推荐
- 【Unity游戏开发】用C#和Lua实现Unity中的事件分发机制EventDispatcher
- (十三)Core Java GUI(图形化界面小程序开发,事件监听机制流程,以及可运行jar包的配置实现,) (109)
- 浅谈用java实现事件驱动机制
- 使用javascript和java模仿实现事件回调机制
- java实现潜艇大战游戏之Java swing图形界面开发游戏项目潜艇大战源码及实现方式详解
- 创建图形用户界面GUI和事件监听机制的简单实现(java)
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
- 利用Java事件处理机制实现录制、回放功能
- Java事件处理机制 - 事件监听器的四种实现方式(转)
- 用Java事件处理机制实现录制回放功能
- 用OC实现一个类似java的事件监听机制
- 用Java事件处理机制实现录制回放功能
- Java事件处理机制- 事件监听器的四种实现方式
- 创建图形用户界面GUI和事件监听机制的简单实现(java)
- 利用Java Swing 实现游戏开发
- Java事件处理机制- 事件监听器的四种实现方式【转】
- 利用Java事件处理机制实现录制、回放功能
- java实现简单的窗体和密码验证(传参,事件机制和事件监听的作用过程)
- 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
- Java事件处理机制- 事件监听器的四种实现方式