All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ng.gdxutils.b2d.BodyEditorLoader Maven / Gradle / Ivy

The newest version!
package com.ng.gdxutils.b2d;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;

import java.util.HashMap;
import java.util.Map;

public class BodyEditorLoader {
	private final Model model;

	// Reusable stuff
	private final Array vectorPool = new Array();
	private final PolygonShape polygonShape = new PolygonShape();
	private final CircleShape circleShape = new CircleShape();
	private final Vector2 vec = new Vector2();

	// -------------------------------------------------------------------------
	// Ctors
	// -------------------------------------------------------------------------

	public BodyEditorLoader(FileHandle file) {
		if (file == null) throw new NullPointerException("file is null");
		model = readJson(file.readString());
	}

	public BodyEditorLoader(String str) {
		if (str == null) throw new NullPointerException("str is null");
		model = readJson(str);
	}

	// -------------------------------------------------------------------------
	// Public API
	// -------------------------------------------------------------------------

	/**
	 * Creates and applies the fixtures defined in the editor. The name
	 * parameter is used to retrieve the right fixture from the loaded file.
	 * 

* * The body reference point (the red cross in the tool) is by default * located at the bottom left corner of the image. This reference point * will be put right over the BodyDef position point. Therefore, you should * place this reference point carefully to let you place your body in your * world easily with its BodyDef.position point. Note that to draw an image * at the position of your body, you will need to know this reference point * (see {@link #getOrigin(String, float)}. *

* * Also, saved shapes are normalized. As shown in the tool, the width of * the image is considered to be always 1 meter. Thus, you need to provide * a scale factor so the polygons get resized according to your needs (not * every body is 1 meter large in your game, I guess). * * @param body The Box2d body you want to attach the fixture to. * @param name The name of the fixture you want to load. * @param fd The fixture parameters to apply to the created body fixture. * @param scale The desired scale of the body. The default width is 1. */ public void attachFixture(Body body, String name, FixtureDef fd, float scale) { RigidBodyModel rbModel = model.rigidBodies.get(name); if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found."); Vector2 origin = vec.set(rbModel.origin).scl(scale); for (int i=0, n=rbModel.polygons.size; i
* * The body reference point (the red cross in the tool) is by default * located at the bottom left corner of the image. This reference point * will be put right over the BodyDef position point. Therefore, you should * place this reference point carefully to let you place your body in your * world easily with its BodyDef.position point. Note that to draw an image * at the position of your body, you will need to know this reference point * (see {@link #getOrigin(String, float)}. *

* * Also, saved shapes are normalized. As shown in the tool, the width of * the image is considered to be always 1 meter. Thus, you need to provide * a scale factor so the polygons get resized according to your needs (not * every body is 1 meter large in your game, I guess). * * @param body The Box2d body you want to attach the fixture to. * @param name The name of the fixture you want to load. * @param scale The desired scale of the body. The default width is 1. */ public void attachFixture(Body body, String name, float scale) { RigidBodyModel rbModel = model.rigidBodies.get(name); if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found."); Vector2 origin = vec.set(rbModel.origin).scl(scale); for (int i=0, n=rbModel.polygons.size; iFor advanced users only. Lets you access the internal model of * this loader and modify it. Be aware that any modification is permanent * and that you should really know what you are doing. */ public Model getInternalModel() { return model; } // ------------------------------------------------------------------------- // Json Models // ------------------------------------------------------------------------- public static class Model { public final Map rigidBodies = new HashMap(); } public static class RigidBodyModel { public String name; public String imagePath; public final Vector2 origin = new Vector2(); public final Array polygons = new Array(); public final Array circles = new Array(); } public static class PolygonModel { public final Array vertices = new Array(); private Vector2[] buffer; // used to avoid allocation in attachFixture() } public static class CircleModel { public final Vector2 center = new Vector2(); public float radius; } // ------------------------------------------------------------------------- // Json reading process // ------------------------------------------------------------------------- private Model readJson(String str) { Model m = new Model(); JsonValue map = new JsonReader().parse(str); JsonValue bodyElem = map.getChild("rigidBodies"); for (; bodyElem != null; bodyElem = bodyElem.next()) { RigidBodyModel rbModel = readRigidBody(bodyElem); m.rigidBodies.put(rbModel.name, rbModel); } return m; } private RigidBodyModel readRigidBody(JsonValue bodyElem) { RigidBodyModel rbModel = new RigidBodyModel(); rbModel.name = bodyElem.getString("name"); rbModel.imagePath = bodyElem.getString("imagePath"); JsonValue originElem = bodyElem.get("origin"); rbModel.origin.x = originElem.getFloat("x"); rbModel.origin.y = originElem.getFloat("y"); // polygons JsonValue polygonsElem = bodyElem.getChild("polygons"); for (; polygonsElem != null ;polygonsElem = polygonsElem.next()){ PolygonModel polygon = new PolygonModel(); rbModel.polygons.add(polygon); JsonValue vertexElem = polygonsElem.child(); for (; vertexElem != null; vertexElem = vertexElem.next()) { float x = vertexElem.getFloat("x"); float y = vertexElem.getFloat("y"); polygon.vertices.add(new Vector2(x, y)); } polygon.buffer = new Vector2[polygon.vertices.size]; } // circles JsonValue circleElem = bodyElem.getChild("circles"); for (; circleElem != null; circleElem = circleElem.next()) { CircleModel circle = new CircleModel(); rbModel.circles.add(circle); circle.center.x = circleElem.getFloat("cx"); circle.center.y = circleElem.getFloat("cy"); circle.radius = circleElem.getFloat("r"); } return rbModel; } // ------------------------------------------------------------------------- // Helpers // ------------------------------------------------------------------------- private Vector2 newVec() { return vectorPool.size == 0 ? new Vector2() : vectorPool.removeIndex(0); } private void free(Vector2 v) { vectorPool.add(v); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy