Here is some code. Not exactly were I want to go with this, but it might be nice to look at to get a general idea…maybe spark something in someone.
package net.phys2d.raw.test;
import net.phys2d.math.Vector2f;
import net.phys2d.raw.Body;
import net.phys2d.raw.SpringJoint;
import net.phys2d.raw.StaticBody;
import net.phys2d.raw.World;
import net.phys2d.raw.shapes.Box;
/**
* Another Demo for the spring joint.
* This should demonstrate how a non-rigid body could be simulated.
* There are some special keys for moving the body around.
* w - up
* s - down
* a - left
* d - right
* space - jump (just press it and let go, or else it will continue to jump!!! maybe thats kinda fun though)
*
* @author Shaun Sheppard
*/
public class Demo21_Extension extends AbstractDemo {
float RADIUS = 100f;
float DIAMETER = RADIUS * 2;
Vector2f tmpForce = new Vector2f();
float MOVE_FORCE = 15000f;
/** Ensure this is nicely divisible by 2 (even). This is the number of bodies created around the center body. */
int OUTER_BODY_COUNT = 12;
Body ground = new StaticBody("ground", new Box(500.0f, 20.0f));
Body centerBody = new Body("centerBody", new Box(10.0f, 10.0f), 10.0f);
/**
* Create the demo
*/
public Demo21_Extension() {
super("Demo 21_Extension: A Non-Rigid Body (using SpringJoints)");
}
/**
* @see net.phys2d.raw.test.AbstractDemo#init(net.phys2d.raw.World)
*/
protected void init(World world) {
ground.setPosition(250.0f, 450);
world.add(ground);
centerBody.setPosition(250f, 100f);
world.add(centerBody);
double radiansBetweenOuterBodies = Math.PI * 2 / OUTER_BODY_COUNT;
double currentRadians = 0;
Body[] outerBodies = new Body[OUTER_BODY_COUNT];
int i;
float distanceBetweenOuterBodies = 0f;
for (i = 0; i < OUTER_BODY_COUNT; ++i) {
// First create the body
outerBodies[i] = new Body("outerBody-" + i, new Box(20f, 20f), 50f);
outerBodies[i].setFriction(1f); // high friction to have them grip the ground like a tire.
double x = Math.sin(currentRadians) * RADIUS;
double y = Math.cos(currentRadians) * -RADIUS;
outerBodies[i].setPosition((float)x + centerBody.getPosition().getX(), (float)y + centerBody.getPosition().getY());
world.add(outerBodies[i]);
// Then add the spring joint back to the centerBody
SpringJoint jointToCenter = new SpringJoint(outerBodies[i], centerBody, outerBodies[i].getPosition(), centerBody.getPosition());
jointToCenter.setBrokenSpringConst(1);
jointToCenter.setCompressedSpringConst(0f);
jointToCenter.setStretchedSpringConst(0f);
jointToCenter.setSpringSize(RADIUS);
jointToCenter.setMinSpringSize(RADIUS * 0.99f);
jointToCenter.setMaxSpringSize(RADIUS * 1.01f);
world.add(jointToCenter);
if (i > 0) {
// Then add the joint to hold the outer bodies together to hold some form
SpringJoint jointToPreviousOuterBody = new SpringJoint(outerBodies[i], outerBodies[i - 1], outerBodies[i].getPosition(), outerBodies[i - 1].getPosition());
jointToPreviousOuterBody.setBrokenSpringConst(1);
jointToPreviousOuterBody.setCompressedSpringConst(0f);
jointToPreviousOuterBody.setStretchedSpringConst(0f);
if (distanceBetweenOuterBodies == 0f) { // Only do this calculation once...
float sideA = outerBodies[i].getPosition().getX() - outerBodies[i - 1].getPosition().getX();
float sideB = outerBodies[i].getPosition().getY() - outerBodies[i - 1].getPosition().getY();
distanceBetweenOuterBodies = (float)Math.sqrt((sideA * sideA) + (sideB * sideB));
}
jointToPreviousOuterBody.setSpringSize(distanceBetweenOuterBodies);
jointToPreviousOuterBody.setMinSpringSize(distanceBetweenOuterBodies * 0.9f);
jointToPreviousOuterBody.setMaxSpringSize(distanceBetweenOuterBodies * 1.1f);
world.add(jointToPreviousOuterBody);
}
currentRadians += radiansBetweenOuterBodies;
}
// Dont forget, the way we did this requires to add this one last joint
--i;
SpringJoint jointToPreviousOuterBody = new SpringJoint(outerBodies[i], outerBodies[0], outerBodies[i].getPosition(), outerBodies[0].getPosition());
jointToPreviousOuterBody.setBrokenSpringConst(1);
jointToPreviousOuterBody.setCompressedSpringConst(0f);
jointToPreviousOuterBody.setStretchedSpringConst(0f);
jointToPreviousOuterBody.setSpringSize(distanceBetweenOuterBodies);
jointToPreviousOuterBody.setMinSpringSize(distanceBetweenOuterBodies * 0.9f);
jointToPreviousOuterBody.setMaxSpringSize(distanceBetweenOuterBodies * 1.1f);
world.add(jointToPreviousOuterBody);
}
/*
* (non-Javadoc)
* @see net.phys2d.raw.test.AbstractDemo#keyHit(char)
*/
protected void keyHit(char c) {
super.keyHit(c);
if (c == 'w') {
tmpForce.set(0, -MOVE_FORCE);
centerBody.addForce(tmpForce);
} else if (c == 's') {
tmpForce.set(0, MOVE_FORCE);
centerBody.addForce(tmpForce);
}
if (c == 'a') {
tmpForce.set(-MOVE_FORCE, 0);
centerBody.addForce(tmpForce);
} else if (c == 'd') {
tmpForce.set(MOVE_FORCE, 0);
centerBody.addForce(tmpForce);
}
if (c == ' ') {
tmpForce.set(0, -MOVE_FORCE * 100);
centerBody.addForce(tmpForce);
}
}
/**
* Entry point for tetsing
*
* @param argv The arguments to the test
*/
public static void main(String[] argv) {
Demo21_Extension demo = new Demo21_Extension();
demo.start();
}
}