📄 mediator.java
字号:
/** * Title: 吃豆子<p> * Description: 小游戏<p> * Copyright: Copyright (c) Nothing<p> * Company: Raindrop<p> * @author Nothing * @version 1.0 */package eatbean;import java.awt.*;import java.util.Vector;//import eatbean.util.*;import eatbean.conf.*;import eatbean.event.*;/** 处理类之间的关系 */public class Mediator { private Map map = null; private OffScreen offScreen = null; /** Fairy容器 */ private Vector fairyV = new Vector(); /** Sprite容器 */ private Vector spriteV = new Vector(); private static boolean paused = true; private static int doneCount = 0; private static int actorCount = 0; private static boolean locked = false; private GameListener gameListener = null; private ScreenListener screenListener = null; private Object syncGameLstn = new Object(); // 同步add/remove GameListener public Mediator() { } public void createMap(int[][] ii, int x, int y) throws Exception { map = new Map(this, ii, x, y); map.paint(); } /** 创建一Fairy对象 */ public boolean createFairy() { boolean result = false; Fairy fairy = new Fairy(this); if(fairy != null) if(fairyV.size() < SysParam.MAX_NUM_FAIRY) { fairy.paint(); fairyV.add(fairy); fairy.act(); actorCount++; result = true; } return result; } /** 创建一Sprite对象 */ public boolean createSprite() { boolean result = false; Sprite sprite = new Sprite(this); if(sprite != null) if(spriteV.size() < SysParam.MAX_NUM_SPRITE) { sprite.paint(); spriteV.add(sprite); sprite.act(); actorCount++; result = true; } return result; } /** 创建OffScreen对象 */ public boolean createOffScreen(Container c) { offScreen = OffScreen.getInstance(c); return true; } public OffScreen getOffScreen() { return offScreen; } /** 返回Actor当前位置(Map索引) */ public Pos getCurrMapPos(Pos[] pos, Rect rect) { //rect 的重心 Pos center = new Pos(rect.x + rect.width/2, rect.y + rect.height/2); Pos result = null; for(int i = 0; i < pos.length; i++) { MapElement e = map.getElement(pos[i]); if(e.getRect().contains(center)) { result = pos[i]; break; } } return result; } /** 重绘背景 */ public void repaintBg(Actor actor, Pos[] pos) { for(int i = 0; i < pos.length; i++) { MapElement e = map.getElement(pos[i]); e.draw(offScreen); } } /** 返回被Actor覆盖的MapElement的位置 */ public Pos[] getCoveredElementsMapPos(Actor actor) { // 当前Map索引 Pos actorMapPos = actor.getMapPos(); Rect rect = actor.getRect(); MapElement e = null; Pos elementPos = (Pos)actorMapPos.clone(); Vector v = new Vector(); Pos[] result = null; v.add(elementPos.clone()); // 因保持Actor.rect<MapElement.rect,且Actor居中,故只需取观察上下或左右两个方向的元素 v.add(elementPos.clone()); search(v, (Pos)elementPos.clone(), rect, actor.getDirection()); //正方向 search(v, (Pos)elementPos.clone(), rect, actor.getReverse()); //反方向 if(v.size() > 0) { result = new Pos[v.size()]; for(int i = 0; i < v.size(); i++) result[i] = (Pos)v.elementAt(i); } return result; } private void search(Vector v, Pos initPos, Rect r, int dir) { while(true) { if(dir == Actor.DIR_NORTH) //UP initPos.y--; else if(dir == Actor.DIR_SOUTH) //DOWN initPos.y++; else if(dir == Actor.DIR_WEST) //LEFT initPos.x--; else if(dir == Actor.DIR_EAST) //RIGHT initPos.x++; else //did you see a ghost hohohoho break; MapElement e = null; if(((e = map.getElement(initPos)) != null) && r.intersects(e.getRect())) v.add(initPos.clone()); else break; }// end while } /** 按Actor的实际类型,返回Actor当前的Rect是否合法 */ public boolean acceptable(Actor actor) { boolean result = true; Pos[] p = actor.getCurrCoveredPos(); if((actor instanceof Fairy) || (actor instanceof Sprite)) { if(p != null) { for(int i = 0; i < p.length; i++) if( !((map.getElement(p[i]) instanceof Room) || (map.getElement(p[i]) instanceof Door)) ) { result = false; break; } } } return result; } /** 由Actor调用,返回p的下一个元素是否合法 */ public boolean acceptable(Pos p, int dir) { boolean result = false; Pos tmp = (Pos)p.clone(); MapElement e = null; switch(dir) { case Actor.DIR_WEST : p.x = p.x - 1; break; case Actor.DIR_EAST : p.x = p.x + 1; break; case Actor.DIR_NORTH : p.y = p.y - 1; break; case Actor.DIR_SOUTH : p.y = p.y + 1; break; default : return false; } if((e = map.getElement(p)) != null) if((e instanceof Room) || (e instanceof Door)) result = true; p = tmp; return result; } /** 同步方法,当最后一个Actor调用此方法时执行offScreen.flush(),否则阻塞Actor */ public synchronized void flushScreen(Actor actor) { if(!fairyV.contains(actor) && !spriteV.contains(actor)) return; doneCount++; if(doneCount < actorCount) { //try { wait(); } catch(Exception ex) { System.out.println("error: " + ex); }; try { //wait(); wait(RtParam.sleepTime*2); //设置等待时间,防止某一Actor被杀时其他所有Actor都挂在这里 } catch(Exception ex) { System.out.println("error: " + ex); }; } else { try { Thread.currentThread().sleep(RtParam.sleepTime); } catch(InterruptedException ex) { System.out.println("error: " + ex); } doneCount = 0; paintAllActor(); offScreen.flush(); notifyAll(); } } /** 检查是否存在与Fairy相交的Sprite */ public void checkSpriteIntersect(Fairy fairy) { Sprite sprite = null; for(int i = 0; i < spriteV.size(); i++) { if(((Sprite)spriteV.elementAt(i)).getRect().intersects(fairy.getRect())) { sprite = (Sprite)spriteV.elementAt(i); break; } } if(sprite != null) doIntersect(fairy, sprite); } /** 永远返回false.此方法可决定Sprite相互是否可以重叠 */ public boolean hasIntersectSprite(Sprite sprite) { boolean result = false; /* for(int i = 0; i < spriteV.size(); i++) { if(((Sprite)spriteV.elementAt(i)).getRect().intersects(sprite.getRect())) { result = true; break; } } */ return result; } /** Fairy与Sprite相遇时调用此方法,触发MSG_ACTOR_EAT事件 */ public void doIntersect(Fairy fairy, Sprite sprite) { setPaused(true); GameEvent ge = null; if(fairy.getLevel() > sprite.getLevel()) { //sprite被杀 ge = new GameEvent(sprite, GameEvent.MSG_ACTOR_EAT); sprite.clear(); sprite.die(); spriteV.removeElement(sprite); setPaused(false); } else { //fairy被杀 ge = new GameEvent(fairy, GameEvent.MSG_ACTOR_EAT); fairy.clear(); fairy.die(); fairyV.removeElement(fairy); } actorCount--; System.out.println("doIntersect(...)"); if(gameListener != null) gameListener.postMsg(ge); } private void paintAllActor() { for(int i = 0; i < spriteV.size(); i++) ((Sprite)spriteV.elementAt(i)).paint(); for(int i = 0; i < fairyV.size(); i++) ((Fairy)fairyV.elementAt(i)).paint(); } public void eatBean(Fairy fairy) { MapElement e = getElement(fairy.getMapPos()); if((e != null) && (e instanceof Room)) { if( !((Room)e).isEmpty() ) { ((Room)e).setEmpty(); map.decBeanNum(); if(gameListener != null) { gameListener.postMsg(new GameEvent(e, GameEvent.MSG_OBJECT_EAT)); //if(Debug.ON) Debug.println("beanNum: " + Integer.toString(map.getBeanNum())); if(map.getBeanNum() == 0) gameListener.postMsg(new GameEvent(e, GameEvent.MSG_STATION_DONE)); } } } } /** 将所有东东置空(包括map) */ public void killAll() { /* locked = true; paused = true; try { while(doneCount != 0) { try { Thread.currentThread().sleep(10); } catch(Exception ex) {} } for(int i = 0; i < spriteV.size(); i++) ((Sprite)spriteV.elementAt(i)).die(); for(int i = 0; i < fairyV.size(); i++) ((Fairy)fairyV.elementAt(i)).die(); spriteV.clear(); fairyV.clear(); actorCount = 0; doneCount = 0; map = null; } finally { locked = false; } System.gc(); */ resetAllActor(); map = null; } public void resetAllActor() { locked = true; paused = true; try { /* while(doneCount != 0) { try { Thread.currentThread().sleep(10); } catch(Exception ex) {} } */ for(int i = 0; i < spriteV.size(); i++) { Sprite sprite = (Sprite)spriteV.elementAt(i); sprite.clear(); sprite.die(); } for(int i = 0; i < fairyV.size(); i++) { Fairy fairy = (Fairy)fairyV.elementAt(i); fairy.clear(); fairy.die(); } spriteV.clear(); fairyV.clear(); actorCount = 0; doneCount = 0; } finally { locked = false; } System.gc(); } public void fairySetNextDirection(int dir) { if(dir == Fairy.DIR_EAST || dir == Fairy.DIR_NORTH || dir == Fairy.DIR_SOUTH || dir == Fairy.DIR_WEST) { if(!fairyV.isEmpty()) { Fairy fairy = (Fairy)fairyV.firstElement(); fairy.setNextDirection(dir); } } } public void fairyResetNextDirection() { if(fairyV.isEmpty()) return; Fairy fairy = (Fairy)fairyV.firstElement(); fairy.setNextDirection(fairy.getDirection()); } public void addGameListener(GameListener l) { synchronized(syncGameLstn) { if(l == null || gameListener != null) return; gameListener = l; } } public void removeGameListener() { synchronized(syncGameLstn) { if(gameListener != null) { gameListener.free(); gameListener = null; } } } public void addScreenListener(ScreenListener l) { offScreen.addScreenListener(l); } public ScreenListener removeScreenListener() { return offScreen.removeScreenListener(); } public void beep() { Toolkit.getDefaultToolkit().beep(); } public Pos getFairyBornPos() { if(map == null) return null; return map.getFairyBornPos(); } public Pos getSpriteBornPos() { if(map == null) return null; return map.getSpriteBornPos(); } public MapElement getElement(Pos pos) { if(map == null) return null; return map.getElement(pos); } public void repaintBg() { if(map == null) return; map.paint(); } public boolean getPaused() { return paused; } public int getMapWidth() { if(map == null) return -1; return map.getWidth(); } public int getMapHeight() { if(map == null) return -1; return map.getHeight(); } public int[][] getMapIntElements() { return map.getMapIntElements(); } public int getOffScreenWidth() { if(offScreen == null) return -1; return offScreen.getWidth(); } public int getOffScreenHeight() { if(offScreen == null) return -1; return offScreen.getHeight(); } public Pos getFairyMapPos() { Pos result = null; Fairy fairy = null; try { fairy = (Fairy)fairyV.firstElement(); } catch(Exception ex) {} if(fairy != null) result = fairy.getMapPos(); return result; } public void setPaused(boolean p) { if(!locked) paused = p; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -