您的位置:首页 > 编程语言 > Java开发

游戏开发中的事件机制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

可能说的比较笼统,大家可以直接看源码体会,源码利用泛型和反射机制,也是不错的示范学习材料。

附上源码:

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: