package sg.atom2d.tools.map; import java.awt.*; import java.util.*; import java.net.*; import java.io.*; /** * this class was originally meant to simply hold a reference to a map and a * collection of sprites, which it delegated all the work to in the logic and * render methods of these objects...<p> * * so it is reasonably fitting that this class also manage the loading of the * maps and sprites it uses from files or URLs.<p> * * Each scene consists of a Map, and a collection of sprites, as intended, but * may also be loaded or saved. */ public class Scene { int offsetX = 0; int offsetY = 0; float effect_rScale = 1; float effect_gScale = 1; float effect_bScale = 1; float effect_hue = 0; float effect_sat = 1; Map map; ArrayList sprites; GraphicsBank tileset; /** * creates a scene using the given map and sprites. */ public Scene(Map m, ArrayList s, GraphicsBank gfx) { this.map = m; sprites = s; this.tileset = gfx; } /* Create a new empty scene */ public Scene() { map = new Map(10, 10, 32, 32); tileset = new GraphicsBank(); } public GraphicsBank getTileset() { return tileset; } public void setTileset(GraphicsBank gfx) { tileset = gfx; map.setTileset(gfx); } /** * loads a scene from the given URL. takes tiles from the given * GraphicsBank. */ static Scene loadScene(File f) throws IOException { boolean hasColourEffect = false; float r = 1; float g = 1; float b = 1; float h = 0; float s = 1; BufferedReader reader = new BufferedReader(new FileReader(f)); String line = reader.readLine(); StringTokenizer tokens = new StringTokenizer(line); int width = Integer.parseInt(tokens.nextToken()); int height = Integer.parseInt(tokens.nextToken()); String tileset = tokens.nextToken(); GraphicsBank gfx = new GraphicsBank(); System.out.println("Attempt to load tileset " + tileset); System.out.println("Working path is " + f.getParentFile()); File ts = new File(f.getParentFile(), tileset); System.out.println("Attempt to load tileset " + ts.getAbsoluteFile()); gfx.loadTileset(ts); Map map = new Map(width, height); line = reader.readLine(); tokens = new StringTokenizer(line); if (tokens.nextToken().equalsIgnoreCase("colorization")) { hasColourEffect = true; r = Float.parseFloat(tokens.nextToken()); g = Float.parseFloat(tokens.nextToken()); b = Float.parseFloat(tokens.nextToken()); h = Float.parseFloat(tokens.nextToken()); s = Float.parseFloat(tokens.nextToken()); } while (!line.equals(".")) { line = reader.readLine(); } for (int z = 0; z < 3; z++) { line = reader.readLine(); tokens = new StringTokenizer(line); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { String code = tokens.nextToken(); map.setTile(x, y, z, gfx.getTile(Integer.parseInt(code))); } } } reader.close(); Scene scene = new Scene(map, new ArrayList(), gfx); scene.tileset = gfx; if (hasColourEffect) { System.out.println("Calling setEffect on scene recently loaded."); scene.setEffect(r, g, b, h, s, 1f); } return scene; } static Scene loadScene(String filename) throws IOException { Scene scene = loadScene(new File(filename)); return scene; } /** * writes the map only (at the moment) to a file. */ public void saveScene(File file) { if (tileset.isUnsaved()) { throw new RuntimeException("Tileset is unsaved. Cannot save the scene"); } try { PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file))); String line = ""; int width = map.getWidth(); int height = map.getHeight(); File wd = new File(file.getParentFile().getCanonicalFile().toString()); File ts = new File(tileset.getFile().getCanonicalFile().toString()); String relativePath = RelativePath.getRelativePath(wd, ts); line = width + " " + height + " " + relativePath; writer.println(line); line = "colorization " + effect_rScale + " " + effect_gScale + " " + effect_bScale + " " + effect_hue + " " + effect_sat; writer.println(line); System.out.println("Colorization red in save is " + effect_rScale); writer.println("."); for (int z = 0; z < 3; z++) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Tile t = map.getTile(j, i, z); if (t != null) { writer.print(t.getNumber() + " "); } else { writer.print("0 "); } } } writer.println(); } writer.flush(); writer.close(); } catch (IOException e) { throw new RuntimeException("Could not save the level"); } System.err.println("Saved"); } /** * calls each sprites logic method. */ void logic() { for (int i = 0; i < sprites.size(); i++) { Sprite s = (Sprite) sprites.get(i); s.logic(); } } /** * renders the scene to the graphics context. at the moment, sprites appear * above everything else. * * TODO: Fix this up. */ void render(Graphics g) { //System.out.println("Render Scene"); map.render(g, offsetX, offsetY); for (int i = 0; i < sprites.size(); i++) { Sprite s = (Sprite) sprites.get(i); //s.render(g, offsetX, offsetY); } } public void render(Graphics g, int offX, int offY) { map.render(g, offX, offY); } public void render(Graphics g, Camera c) { map.render(g, c); } public void render(Graphics g, Point origin, Dimension size) { map.render(g, origin, size); } public void render(Graphics g, Point origin, Dimension size, int layer) { map.render(g, origin, size, layer); } /** * sets the visible area of the scene. This will probably not be used once * the game is finished. */ void setViewSize(int width, int height) { map.setViewSize(width, height); } /** * sets the screen offset. Screen offset can be anywhere, not just following * a character around. This is good for cut scenes. */ void setOffset(int x, int y) { offsetX = x; offsetY = y; } /** * Apply RGB scalars and hue/sat adjustments to the tiles and characters in * the scene. The hue and sat are always applied first * */ public void setEffect(float r, float g, float b, float h, float s, float z) { System.out.println("Scene setEffect called. will call for the gfx bank...r" + r + " g" + g + " b" + b + " z" + z); effect_rScale = r; effect_gScale = g; effect_bScale = b; effect_hue = h; effect_sat = s; tileset.setEffect(r, g, b, h, s, z); map.setZoom(z); } /** * returns the map. not really any reason to want to do this except for the * level editor. */ public Map getMap() { return map; } }