Java tutorial
/******************************************************************************* * Copyright (c) 2013 Philip Collin. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Philip Collin - initial API and implementation ******************************************************************************/ package com.lyeeedar.Roguelike3D.Game.Level.XML; import java.util.ArrayList; import java.util.Random; import java.util.SortedMap; import java.util.TreeMap; import org.w3c.dom.Node; import com.badlogic.gdx.graphics.Color; import com.lyeeedar.Roguelike3D.Game.Level.AbstractObject; import com.lyeeedar.Roguelike3D.Game.Level.AbstractRoom; import com.lyeeedar.Roguelike3D.Game.Level.DungeonRoom.RoomType; public class RoomReader extends XMLReader { public static final String ROOM_DEFINITIONS = "room_definitions"; public static final String GLOBAL = "GLOBAL"; public static final String WIDTH = "width"; public static final String HEIGHT = "height"; public static final String DEPTH_MIN = "depth_min"; public static final String DEPTH_MAX = "depth_max"; public static final String START = "START"; public static final String END = "END"; public static final String MAIN = "MAIN"; public static final String SPECIAL = "SPECIAL"; public static final String OTHER = "OTHER"; public static final String DEFINITIONS = "definitions"; public static final String SYMBOL = "symbol"; public static final String CHAR = "char"; public static final String TYPE = "type"; public static final String VISIBLE = "visible"; public static final String SHORT_DESCRIPTION = "short_description"; public static final String LONG_DESCRIPTION = "long_description"; public static final String MODEL = "model"; public static final String MODEL_TYPE = "type"; public static final String MODEL_NAME = "name"; public static final String MODEL_SCALE = "scale"; public static final String DIMENSIONS = "dimensions"; public static final String DIMENSIONS_NUMBER = "number"; public static final String DIMENSIONS_D = "d"; public static final String TEXTURE = "texture"; public static final String COLOUR = "colour"; public static final String RED = "red"; public static final String GREEN = "green"; public static final String BLUE = "blue"; public static final String ROOM = "room"; public static final String ROW = "row"; public static final String META = "meta"; public static final String DATA = "data"; public static final String NAME = "name"; public static final String CONTENTS = "contents"; Node biome; int depth; public RoomReader(String biome, int depth) { super("data/xml/" + biome + ".data"); this.depth = depth; this.biome = getNode(ROOM_DEFINITIONS, root_node.getChildNodes()); } public AbstractRoom getRoom(RoomType rtype, int width, int height, boolean flippable) { Node roomType = getRoomNode(rtype); SortedMap<Integer, ArrayList<Node>> valid = new TreeMap<Integer, ArrayList<Node>>(); for (int i = 0; i < roomType.getChildNodes().getLength(); i++) { Node n = roomType.getChildNodes().item(i); if (n.getNodeType() == Node.TEXT_NODE) continue; int w = Integer.parseInt(getNodeValue(WIDTH, n.getChildNodes())); int h = Integer.parseInt(getNodeValue(HEIGHT, n.getChildNodes())); if (w <= width) { if (h <= height) { int priority = (width - w) + (height - h); if (valid.containsKey(priority)) { valid.get(priority).add(n); } else { ArrayList<Node> ns = new ArrayList<Node>(); ns.add(n); valid.put(priority, ns); } } } else if (h <= width) { if (w <= height) { int depth_offset = 0; int room_depth_min = Integer.parseInt(getNodeValue(DEPTH_MIN, n.getChildNodes())); int room_depth_max = Integer.parseInt(getNodeValue(DEPTH_MAX, n.getChildNodes())); if (room_depth_max < depth) depth_offset = depth - room_depth_max; else if (room_depth_min > depth) depth_offset = room_depth_min - depth; int priority = (width - h) + (height - w) + (depth_offset * 2); if (valid.containsKey(priority)) { valid.get(priority).add(n); } else { ArrayList<Node> ns = new ArrayList<Node>(); ns.add(n); valid.put(priority, ns); } } } } if (valid.size() == 0) { return null; } int pos = 0; Random ran = new Random(); while (true) { if (pos == valid.size()) { pos--; break; } if (ran.nextInt(100) < 50) { pos++; } else { break; } } ArrayList<Node> ns = valid.get(valid.keySet().toArray()[pos]); Node chosen = ns.get(ran.nextInt(ns.size())); int rheight = Integer.parseInt(getNodeValue(WIDTH, chosen.getChildNodes())); int rwidth = Integer.parseInt(getNodeValue(HEIGHT, chosen.getChildNodes())); AbstractRoom room = null; if (rwidth <= width && rheight <= height) room = new AbstractRoom(rwidth, rheight, false, flippable); else room = new AbstractRoom(rwidth, rheight, true, flippable); Node roomGraphics = getNode(ROOM, chosen.getChildNodes()); int roomIndex = 0; for (int i = 0; i < roomGraphics.getChildNodes().getLength(); i++) { Node n = roomGraphics.getChildNodes().item(i); if (!n.getNodeName().equalsIgnoreCase(ROW)) continue; room.setRow(roomIndex, n.getTextContent().toCharArray()); roomIndex++; } room.finaliseContents(); Node define = getNode(DEFINITIONS, chosen.getChildNodes()); if (define != null) { for (int i = 0; i < define.getChildNodes().getLength(); i++) { Node symbol = define.getChildNodes().item(i); if (!symbol.getNodeName().equalsIgnoreCase(SYMBOL)) continue; char character = getNodeValue(CHAR, symbol.getChildNodes()).charAt(0); String type = getNodeValue(TYPE, symbol.getChildNodes()); boolean visible = Boolean.parseBoolean(getNodeValue(VISIBLE, symbol.getChildNodes())); String shortDesc = getNodeValue(SHORT_DESCRIPTION, symbol.getChildNodes()); if (shortDesc == null) { System.out.println(character + " " + type); shortDesc = " "; } String longDesc = getNodeValue(LONG_DESCRIPTION, symbol.getChildNodes()); if (longDesc == null) longDesc = " "; AbstractObject ao = new AbstractObject(character, type, visible, shortDesc, longDesc); Node meta = getNode(META, symbol.getChildNodes()); if (meta != null) { for (int j = 0; j < meta.getChildNodes().getLength(); j++) { Node n = meta.getChildNodes().item(j); if (!n.getNodeName().equalsIgnoreCase(DATA)) continue; ao.addMeta(getNodeValue(NAME, n.getChildNodes()), getNodeValue(CONTENTS, n.getChildNodes())); } } if (visible) { Node model = getNode(MODEL, symbol.getChildNodes()); String modelType = getNodeValue(MODEL_TYPE, model.getChildNodes()); String modelName = getNodeValue(MODEL_NAME, model.getChildNodes()); String ms = getNodeValue(MODEL_SCALE, model.getChildNodes()); float modelScale = 1.0f; if (ms != null && ms.length() > 0) modelScale = Float.parseFloat(ms); Node dimensions = getNode(DIMENSIONS, model.getChildNodes()); int number = 0; if (dimensions != null) number = Integer.parseInt(getNodeValue(DIMENSIONS_NUMBER, dimensions.getChildNodes())); float[] dim = new float[number]; for (int j = 1; j < number + 1; j++) { dim[j - 1] = Float.parseFloat(getNodeValue(DIMENSIONS_D + j, dimensions.getChildNodes())); } String texture = getNodeValue(TEXTURE, symbol.getChildNodes()); Node colour = getNode(COLOUR, symbol.getChildNodes()); float red = Float.parseFloat(getNodeValue(RED, colour.getChildNodes())); float green = Float.parseFloat(getNodeValue(GREEN, colour.getChildNodes())); float blue = Float.parseFloat(getNodeValue(BLUE, colour.getChildNodes())); Color col = new Color(red, green, blue, 1.0f); ao.setModel(modelType, modelName, modelScale, texture, col, dim); } room.addObject(ao); } } Node global = getNode(GLOBAL, biome.getChildNodes()); for (int i = 0; i < global.getChildNodes().getLength(); i++) { Node symbol = global.getChildNodes().item(i); if (!symbol.getNodeName().equalsIgnoreCase(SYMBOL)) continue; char character = getNodeValue(CHAR, symbol.getChildNodes()).charAt(0); String type = getNodeValue(TYPE, symbol.getChildNodes()); boolean visible = Boolean.parseBoolean(getNodeValue(VISIBLE, symbol.getChildNodes())); String shortDesc = getNodeValue(SHORT_DESCRIPTION, symbol.getChildNodes()); String longDesc = getNodeValue(LONG_DESCRIPTION, symbol.getChildNodes()); AbstractObject ao = new AbstractObject(character, type, visible, shortDesc, longDesc); Node meta = getNode(META, symbol.getChildNodes()); if (meta != null) { for (int j = 0; j < meta.getChildNodes().getLength(); j++) { Node n = meta.getChildNodes().item(j); if (!n.getNodeName().equalsIgnoreCase(DATA)) continue; ao.addMeta(getNodeValue(NAME, n.getChildNodes()), getNodeValue(CONTENTS, n.getChildNodes())); } } if (visible) { Node model = getNode(MODEL, symbol.getChildNodes()); String modelType = getNodeValue(MODEL_TYPE, model.getChildNodes()); String modelName = getNodeValue(MODEL_NAME, model.getChildNodes()); String ms = getNodeValue(MODEL_SCALE, model.getChildNodes()); float modelScale = 1.0f; if (ms != null && ms.length() > 0) modelScale = Float.parseFloat(ms); Node dimensions = getNode(DIMENSIONS, model.getChildNodes()); int number = Integer.parseInt(getNodeValue(DIMENSIONS_NUMBER, dimensions.getChildNodes())); float[] dim = new float[number]; for (int j = 1; j < number + 1; j++) { dim[j - 1] = Float.parseFloat(getNodeValue(DIMENSIONS_D + j, dimensions.getChildNodes())); } String texture = getNodeValue(TEXTURE, symbol.getChildNodes()); Node colour = getNode(COLOUR, symbol.getChildNodes()); float red = Float.parseFloat(getNodeValue(RED, colour.getChildNodes())); float green = Float.parseFloat(getNodeValue(GREEN, colour.getChildNodes())); float blue = Float.parseFloat(getNodeValue(BLUE, colour.getChildNodes())); Color col = new Color(red, green, blue, 1.0f); ao.setModel(modelType, modelName, modelScale, texture, col, dim); } room.addObject(ao); } Node meta = getNode(META, chosen.getChildNodes()); if (meta != null) { for (int j = 0; j < meta.getChildNodes().getLength(); j++) { Node n = meta.getChildNodes().item(j); if (!n.getNodeName().equalsIgnoreCase(DATA)) continue; room.addMeta(getNodeValue(NAME, n.getChildNodes()), getNodeValue(CONTENTS, n.getChildNodes())); } } return room; } private Node getRoomNode(RoomType rtype) { String rname = null; if (rtype == RoomType.START) { rname = START; } else if (rtype == RoomType.END) { rname = END; } else if (rtype == RoomType.MAIN) { rname = MAIN; } else if (rtype == RoomType.SPECIAL) { rname = SPECIAL; } else if (rtype == RoomType.OTHER) { rname = OTHER; } return getNode(rname, biome.getChildNodes()); } }