package loon.particle; import java.io.IOException; import loon.LSystem; import loon.canvas.LColor; import loon.geom.Vector2f; import loon.particle.SimpleConfigurableEmitter.LinearInterpolator; import loon.particle.SimpleConfigurableEmitter.RandomValue; import loon.particle.SimpleConfigurableEmitter.SimpleValue; import loon.utils.StringUtils; import loon.utils.TArray; import loon.utils.xml.XMLDocument; import loon.utils.xml.XMLElement; import loon.utils.xml.XMLParser; public class SimpleParticleConfig { public interface ConfigurableEmitterFactory { public SimpleConfigurableEmitter createEmitter(String name); } public static SimpleParticleSystem loadConfiguredSystem(String path, LColor mask) throws IOException { return loadConfiguredSystem(path, null, null, mask); } public static SimpleParticleSystem loadConfiguredSystem(String path) throws IOException { return loadConfiguredSystem(path, null, null, null); } public static SimpleParticleSystem loadConfiguredSystem(String path, ConfigurableEmitterFactory factory) throws IOException { return loadConfiguredSystem(path, factory, null, null); } public static SimpleParticleSystem loadConfiguredSystem(String path, ConfigurableEmitterFactory factory, SimpleParticleSystem system, LColor mask) throws IOException { if (factory == null) { factory = new ConfigurableEmitterFactory() { public SimpleConfigurableEmitter createEmitter(String name) { return new SimpleConfigurableEmitter(name); } }; } try { XMLDocument doc = XMLParser.parse(path); XMLElement docElement = doc.getRoot(); if (!docElement.getName().equals("system")) { throw new IOException("Not a particle system file"); } if (system == null) { system = new SimpleParticleSystem(LSystem.FRAMEWORK_IMG_NAME + "par.png", 2000, mask); } boolean additive = docElement.getBoolAttribute("additive", false); if (additive) { system.setBlendingState(LSystem.MODE_ADD); } else { system.setBlendingState(LSystem.MODE_ALPHA_ONE); } boolean points = docElement.getBoolAttribute("points", false); system.setUsePoints(points); TArray<XMLElement> list = docElement.list(); for (int i = 0; i < list.size; i++) { XMLElement em = list.get(i); SimpleConfigurableEmitter emitter = factory .createEmitter("new"); elementToEmitter(em, emitter); system.addEmitter(emitter); } system.setRemoveCompletedEmitters(false); return system; } catch (IOException e) { throw e; } catch (Exception e) { e.printStackTrace(); throw new IOException("Unable to load particle system config"); } } public static SimpleConfigurableEmitter loadEmitter(String path) throws IOException { return loadEmitter(path, null); } public static SimpleConfigurableEmitter loadEmitter(String path, ConfigurableEmitterFactory factory) throws IOException { if (factory == null) { factory = new ConfigurableEmitterFactory() { public SimpleConfigurableEmitter createEmitter(String name) { return new SimpleConfigurableEmitter(name); } }; } try { XMLDocument doc = XMLParser.parse(path); XMLElement docElement = doc.getRoot(); if (!docElement.getName().equals("emitter")) { throw new IOException("Not a particle emitter file"); } SimpleConfigurableEmitter emitter = factory.createEmitter("new"); elementToEmitter(docElement, emitter); return emitter; } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("Unable to load emitter"); } } private static XMLElement getFirstNamedElement(XMLElement element, String name) { TArray<XMLElement> list = element.list(name); if (list.size == 0) { return null; } return list.get(0); } private static void elementToEmitter(XMLElement element, SimpleConfigurableEmitter emitter) { emitter.name = element.getAttribute("name", ""); emitter.setImageName(element.getAttribute("imageName", "")); String renderType = element.getAttribute("renderType", ""); emitter.usePoints = SimpleParticle.INHERIT_POINTS; if (renderType.equals("quads")) { emitter.usePoints = SimpleParticle.USE_QUADS; } if (renderType.equals("points")) { emitter.usePoints = SimpleParticle.USE_POINTS; } emitter.useOriented = element.getBoolAttribute("useOriented", false); emitter.useAdditive = element.getBoolAttribute("useAdditive", false); parseRangeElement(getFirstNamedElement(element, "spawnInterval"), emitter.spawnInterval); parseRangeElement(getFirstNamedElement(element, "spawnCount"), emitter.spawnCount); parseRangeElement(getFirstNamedElement(element, "initialLife"), emitter.initialLife); parseRangeElement(getFirstNamedElement(element, "initialSize"), emitter.initialSize); parseRangeElement(getFirstNamedElement(element, "xOffset"), emitter.xOffset); parseRangeElement(getFirstNamedElement(element, "yOffset"), emitter.yOffset); parseRangeElement(getFirstNamedElement(element, "initialDistance"), emitter.initialDistance); parseRangeElement(getFirstNamedElement(element, "speed"), emitter.speed); parseRangeElement(getFirstNamedElement(element, "length"), emitter.length); parseRangeElement(getFirstNamedElement(element, "emitCount"), emitter.emitCount); parseValueElement(getFirstNamedElement(element, "spread"), emitter.spread); parseValueElement(getFirstNamedElement(element, "angularOffset"), emitter.angularOffset); parseValueElement(getFirstNamedElement(element, "growthFactor"), emitter.growthFactor); parseValueElement(getFirstNamedElement(element, "gravityFactor"), emitter.gravityFactor); parseValueElement(getFirstNamedElement(element, "windFactor"), emitter.windFactor); parseValueElement(getFirstNamedElement(element, "startAlpha"), emitter.startAlpha); parseValueElement(getFirstNamedElement(element, "endAlpha"), emitter.endAlpha); parseValueElement(getFirstNamedElement(element, "alpha"), emitter.alpha); parseValueElement(getFirstNamedElement(element, "size"), emitter.size); parseValueElement(getFirstNamedElement(element, "velocity"), emitter.velocity); parseValueElement(getFirstNamedElement(element, "scaleY"), emitter.scaleY); XMLElement color = getFirstNamedElement(element, "color"); emitter.colors.clear(); if (color != null) { TArray<XMLElement> steps = color.list(); for (int i = 0; i < steps.size; i++) { XMLElement step = steps.get(i); float offset = step.getFloatAttribute("offset", 0); float r = step.getFloatAttribute("r", 0); float g = step.getFloatAttribute("g", 0); float b = step.getFloatAttribute("b", 0); emitter.addColorPoint(offset, new LColor(r, g, b, 1)); } } emitter.replay(); } private static void parseRangeElement(XMLElement element, SimpleConfigurableEmitter.Range range) { if (element == null) { return; } range.setMin(element.getFloatAttribute("min", 0)); range.setMax(element.getFloatAttribute("max", 0)); range.setEnabled(element.getBoolAttribute("enabled", false)); } private static void parseValueElement(XMLElement element, SimpleConfigurableEmitter.Value value) { if (element == null) { return; } String type = element.getAttribute("type", null); String v = element.getAttribute("value", null); if (type == null || type.length() == 0) { if (value instanceof SimpleValue) { ((SimpleValue) value).setValue(Float.parseFloat(v)); } else if (value instanceof RandomValue) { ((RandomValue) value).setValue(Float.parseFloat(v)); } } else { if (type.equals("simple")) { ((SimpleValue) value).setValue(Float.parseFloat(v)); } else if (type.equals("random")) { ((RandomValue) value).setValue(Float.parseFloat(v)); } else if (type.equals("linear")) { String min = element.getAttribute("min", null); String max = element.getAttribute("max", null); String active = element.getAttribute("active", null); TArray<XMLElement> points = element.list("point"); TArray<Vector2f> curve = new TArray<Vector2f>(points.size); for (int i = 0; i < points.size; i++) { XMLElement point = (XMLElement) points.get(i); float x = point.getFloatAttribute("x", 0); float y = point.getFloatAttribute("y", 0); curve.add(new Vector2f(x, y)); } ((LinearInterpolator) value).setCurve(curve); ((LinearInterpolator) value).setMin(Integer.parseInt(min)); ((LinearInterpolator) value).setMax(Integer.parseInt(max)); ((LinearInterpolator) value).setActive(StringUtils.toBoolean(active)); } } } }