package loon.action.scripting; import java.util.HashMap; import java.util.LinkedList; import loon.LTouch; import loon.action.map.AStarFindHeuristic; import loon.action.map.Config; import loon.action.map.Field2D; import loon.action.scripting.pack.PackAnimation; import loon.action.scripting.pack.PackSprite; import loon.action.scripting.pack.PackSprites; import loon.action.scripting.pack.PackTile; import loon.action.scripting.pack.PackTileFactory; import loon.action.scripting.pack.PackTileMap; import loon.action.scripting.pack.PackView; import loon.core.geom.Vector2f; import loon.core.graphics.Screen; import loon.core.graphics.opengl.GLEx; import loon.core.graphics.opengl.LTexturePack; import loon.core.timer.LTimer; import loon.core.timer.LTimerContext; /** * Copyright 2008 - 2011 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loonframework * @author chenpeng * @email:ceponline@yahoo.com.cn * @version 0.1 */ public abstract class ScriptScreen extends Screen { final class Go { LTimer timer = new LTimer(0); float speed = 1.5f; int direction; boolean isComplete; PackSprite sprite; LinkedList<Vector2f> findPath; float startX, startY, endX, endY, moveX, moveY; public boolean isComplete() { return findPath == null || findPath.size() == 0 || isComplete; } public int getWidth() { if (sprite != null) { return sprite.getWidth(); } return 0; } public int getHeight() { if (sprite != null) { return sprite.getHeight(); } return 0; } public void update() { if (sprite != null) { sprite.setLocation(startX, startY); sprite.setDirection(direction); } } } private HashMap<PackSprite, Go> paths; private String packName, mapName; private String scriptFile; private ScriptFactory scripts; private PackSprites packSprites; private Callback callback; private PackView view; private LTexturePack tempPack; private PackTileMap tempMap; private boolean isPack, isMap; private PackTileFactory tileFactory; public ScriptScreen(String res) { if (res == null) { throw new RuntimeException("script name is null !"); } this.scriptFile = res; } @Override public void onCreate(int width, int height) { super.onCreate(width, height); this.isPack = false; this.isMap = false; if (paths != null) { paths.clear(); paths = null; } this.paths = new HashMap<PackSprite, Go>(10); if (packSprites != null) { packSprites.clear(); packSprites = null; } this.packSprites = new PackSprites(); if (scripts != null) { scripts.clear(); scripts = null; } this.scripts = new ScriptFactory(this, scriptFile); } public Callback getCallback() { return callback; } public void setCallback(Callback callback) { this.callback = callback; if (scripts != null) { scripts.setCallback(callback); } } public Callback onCallback() { return null; } @Override public final void onLoad() { if (scripts != null) { scripts.load(); packName = scripts.getPackName(); mapName = scripts.getMapName(); onLoading(); } } public Go getGo(PackSprite sprite) { Go go = paths.get(sprite); if (go != null) { return go; } return null; } public void stopMove(PackSprite sprite) { Go go = paths.get(sprite); if (go != null) { go.isComplete = true; } } public void updateMoveSpeed(PackSprite sprite, float speed) { Go go = paths.get(sprite); if (go != null) { go.speed = speed; } } public void updateMoveDelay(PackSprite sprite, long delay) { Go go = paths.get(sprite); if (go != null) { go.timer.setDelay(delay); } } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, LTouch touch) { toMove(sprite, heuristic, touch.x(), touch.y(), true); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, LTouch touch, boolean flag) { toMove(sprite, heuristic, touch.x(), touch.y(), flag); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, int x, int y) { toMove(sprite, heuristic, x, y, true); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, int x, int y, boolean flag) { toMove(sprite, heuristic, 0, 2f, x, y, flag); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, LTouch touch, float speed) { toMove(sprite, heuristic, 0, speed, touch.x(), touch.y(), true); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, long delay, float speed, LTouch touch) { toMove(sprite, heuristic, delay, speed, touch.x(), touch.y(), true); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, long delay, float speed, LTouch touch, boolean flag) { toMove(sprite, heuristic, delay, speed, touch.x(), touch.y(), flag); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, long delay, float speed, int x, int y) { toMove(sprite, heuristic, delay, speed, x, y, true); } public void toMove(PackSprite sprite, AStarFindHeuristic heuristic, long delay, float speed, int x, int y, boolean flag) { toMove(findAStar(heuristic, sprite.x(), sprite.y(), x, y, flag), sprite, delay, speed); } public void toMove(LinkedList<Vector2f> path, PackSprite sprite, long delay, float speed) { synchronized (ScriptScreen.class) { Go go = paths.get(sprite); if (go == null) { go = new Go(); paths.put(sprite, go); } if (go.findPath != null) { go.findPath.clear(); } go.findPath = path; go.sprite = sprite; go.timer.setDelay(delay); go.speed = speed; } } public LinkedList<Vector2f> findAStar(AStarFindHeuristic heuristic, int x1, int y1, LTouch touch) { PackTileMap map = getMap(mapName); if (map != null) { return map.findAStar(heuristic, x1, y1, touch); } return null; } public LinkedList<Vector2f> findAStar(AStarFindHeuristic heuristic, int x1, int y1, boolean flag, LTouch touch) { PackTileMap map = getMap(mapName); if (map != null) { return map.findAStar(heuristic, x1, y1, flag, touch); } return null; } public LinkedList<Vector2f> findAStar(AStarFindHeuristic heuristic, int x1, int y1, int x2, int y2) { PackTileMap map = getMap(mapName); if (map != null) { return map.findAStar(heuristic, x1, y1, x2, y2); } return null; } public LinkedList<Vector2f> findAStar(AStarFindHeuristic heuristic, int x1, int y1, int x2, int y2, boolean flag) { PackTileMap map = getMap(mapName); if (map != null) { return map.findAStar(heuristic, x1, y1, x2, y2, flag); } return null; } public void setLimit(int[] list) { PackTileMap map = getMap(mapName); if (map != null) { map.limit(list); } } public int[] getLimit() { PackTileMap map = getMap(mapName); if (map != null) { return map.getLimit(); } return null; } public void subMap(int x, int y, int w, int h) { PackTileMap map = getMap(mapName); if (map != null) { map.sub(x, y, w, h); } } public void subMap(int x, int y) { PackTileMap map = getMap(mapName); if (map != null) { map.sub(x, y); } } public void setMapPos(int x, int y) { PackTileMap map = getMap(mapName); if (map != null) { map.setPos(x, y); } } public PackSprite addPackSprite(String name, long delay, float x, float y) { return addPackSprite(name, getAnimation(name), delay, x, y); } public PackSprite addPackSprite(String name, float x, float y) { return addPackSprite(name, getAnimation(name), 150, x, y); } public PackSprite addPackSprite(String name, PackAnimation animation, float x, float y) { return addPackSprite(name, animation, 150, x, y); } public PackSprite addPackSprite(String name, PackAnimation animation, long delay, float x, float y) { if (packSprites != null) { if (animation != null) { PackSprite sprite = new PackSprite(animation); packSprites.add(sprite, x, y); sprite.setName(name); sprite.setDelay(delay); return sprite; } else { return null; } } return null; } public void removePackSprite(PackSprite sprite) { if (packSprites != null) { packSprites.remove(sprite); } } public PackSprite findPackSprite(String name) { return packSprites.find(name); } public void setMapBlockSize(int tileWidth, int tileHeight) { PackTileMap map = getMap(mapName); if (map != null) { map.setBlockSize(tileWidth, tileHeight); } } public int getMapWidth() { PackTileMap map = getMap(mapName); if (map != null) { return map.getWidth(); } return 0; } public int getMapHeight() { PackTileMap map = getMap(mapName); if (map != null) { return map.getHeight(); } return 0; } public PackTile getTile(int x, int y) { PackTileMap map = getMap(mapName); if (map != null) { return map.getTile(x, y); } return null; } public void setTile(int x, int y, PackTile type) { PackTileMap map = getMap(mapName); if (map != null) { map.setTile(x, y, type); } } public boolean collidesWith(PackSprite sprite) { return !canMove(sprite, sprite.getX(), sprite.getY()); } public int count(PackTile element) { PackTileMap map = getMap(mapName); if (map != null) { return map.count(element); } return 0; } public boolean canMove(PackSprite sprite, float x, float y) { PackTileMap map = getMap(mapName); if (map != null) { return map.canMove(sprite, x, y); } return false; } public void touch(PackSprite sprite) { PackTileMap map = getMap(mapName); if (map != null) { map.touch(sprite); } } public int getTileWidth() { PackTileMap map = getMap(mapName); if (map != null) { return map.getTileWidth(); } return 0; } public int getTileHeight() { PackTileMap map = getMap(mapName); if (map != null) { return map.getTileHeight(); } return 0; } public Field2D getField2D() { PackTileMap map = getMap(mapName); if (map != null) { return map.getField2D(); } return null; } public abstract void onLoading(); @Override public final void onLoaded() { if (callback == null) { callback = onCallback(); } if (scripts != null) { scripts.setCallback(callback); } this.setView(null); this.setPackName(packName); this.setMapName(mapName); } public void callScript(String name) { if (scripts != null) { if (packSprites != null) { packSprites.clear(); } scripts.clear(); scripts.call(name); } } public void clearScript() { if (scripts != null) { scripts.clear(); } } public void clearSprite() { if (packSprites != null) { packSprites.clear(); } } public void setView(PackView view) { if (view == null) { view = PackView.EmptyView.getInstance(); } if (packSprites != null) { packSprites.setView(view); } PackTileMap map = scripts.getMap(mapName, tileFactory); if (map != null) { map.setView(view); } this.view = view; } public PackView getView() { return view; } public String getMapName() { return mapName; } public void setMapName(String name) { this.mapName = name; if (name != null && scripts != null) { this.scripts.setMapName(name); this.mapName = name; this.tempMap = scripts.getMap(mapName, tileFactory); if (tempMap != null) { isMap = true; } else { isMap = false; } } } public void setPackName(String name) { if (name != null && scripts != null) { this.scripts.setPackName(name); this.packName = name; this.tempPack = scripts.getPack(packName); if (tempPack != null) { isPack = true; } else { isPack = false; } } } public String getPackName() { return this.packName; } public PackAnimation getAnimation(String name) { return scripts.getAnimation(name); } public LTexturePack getPack(String name) { return scripts.getPack(name); } public PackTileMap getMap() { return scripts.getMap(mapName); } public PackTileMap getMap(String name) { return scripts.getMap(name, tileFactory); } public Script getScript(String name) { return scripts.getScript(name); } private void going() { if (!isMap) { return; } if (paths.size() > 0) { Field2D field2D = getField2D(); if (field2D == null) { return; } synchronized (paths) { for (Go go : paths.values()) { if (go == null || go.findPath == null) { continue; } if (go.isComplete()) { paths.remove(go.sprite); return; } if (go.timer.action(elapsedTime)) { synchronized (go.findPath) { if (go.endX == go.startX && go.endY == go.startY) { if (go.findPath != null) { if (go.findPath.size() > 1) { Vector2f moveStart = go.findPath .get(0); Vector2f moveEnd = go.findPath .get(1); go.startX = field2D .tilesToWidthPixels(moveStart .x()); go.startY = field2D .tilesToHeightPixels(moveStart .y()); go.endX = moveEnd.x() * field2D.getTileWidth(); go.endY = moveEnd.y() * field2D.getTileHeight(); go.moveX = moveEnd.x() - moveStart.x(); go.moveY = moveEnd.y() - moveStart.y(); go.direction = Field2D.getDirection( (int) go.moveX, (int) go.moveY); go.findPath.remove(0); } else { go.findPath.clear(); } } } switch (go.direction) { case Config.TUP: go.startY -= go.speed; if (go.startY < go.endY) { go.startY = go.endY; } break; case Config.TDOWN: go.startY += go.speed; if (go.startY > go.endY) { go.startY = go.endY; } break; case Config.TLEFT: go.startX -= go.speed; if (go.startX < go.endX) { go.startX = go.endX; } break; case Config.TRIGHT: go.startX += go.speed; if (go.startX > go.endX) { go.startX = go.endX; } break; case Config.UP: go.startX += go.speed; go.startY -= go.speed; if (go.startX > go.endX) { go.startX = go.endX; } if (go.startY < go.endY) { go.startY = go.endY; } break; case Config.DOWN: go.startX -= go.speed; go.startY += go.speed; if (go.startX < go.endX) { go.startX = go.endX; } if (go.startY > go.endY) { go.startY = go.endY; } break; case Config.LEFT: go.startX -= go.speed; go.startY -= go.speed; if (go.startX < go.endX) { go.startX = go.endX; } if (go.startY < go.endY) { go.startY = go.endY; } break; case Config.RIGHT: go.startX += go.speed; go.startY += go.speed; if (go.startX > go.endX) { go.startX = go.endX; } if (go.startY > go.endY) { go.startY = go.endY; } break; } go.update(); } } } } } } @Override public final void alter(LTimerContext timer) { if (isOnLoadComplete()) { going(); scripts.update(); update(timer.getTimeSinceLastUpdate()); } } public abstract void update(long elapsedTime); @Override public final void draw(GLEx g) { if (isOnLoadComplete()) { if (isPack) { if (isMap) { if (!tempMap.drawSub(tempPack)) { packSprites.draw(tempPack, elapsedTime); return; } } if (packSprites.size() > 0) { tempPack.glBegin(); packSprites.draw(tempPack, elapsedTime); tempPack.glEnd(); } } paint(g); } } public abstract void paint(GLEx g); public String getScriptFile() { return scriptFile; } public void setScriptFile(String script) { this.scriptFile = script; } public PackTileFactory getTileFactory() { return tileFactory; } public void setTileFactory(PackTileFactory tileFactory) { this.tileFactory = tileFactory; PackTileMap map = getMap(mapName); if (map != null) { PackTileFactory factory = map.getTileFactory(); if (factory != null && !"simple".equals(factory.getName())) { map.setTileFactory(tileFactory); } } } public boolean isMap() { return isMap; } public boolean isPack() { return isPack; } public PackSprites getPackSprites() { return packSprites; } public ScriptFactory getScriptFactory() { return scripts; } @Override public void dispose() { this.isPack = false; this.isMap = false; if (paths != null) { paths.clear(); paths = null; } if (scripts != null) { scripts.dispose(); scripts = null; } if (packSprites != null) { packSprites.clear(); packSprites = null; } if (paths != null) { paths.clear(); paths = null; } } }