I have tried changing the ship fixture shape to both (1) a triangle fixture and also (2) two rectangular fixtures put together. Both of these body configurations are causing problems.

Given the change in volume, to make up for the difference in mass I calculated the necessary new densities so that these bodies have the same mass as the original rectangle body. However when launching the ship with the same linear impulse as before, the triangular body and multi-rectangular body both act differently than the original body and shoot forward much faster.

I have tried further tweaking the ship density as well as the linear impulse and also the planet gravity to return the ship to a normal pace of movement, however when doing that the ship starts to act weird and will do things like suddenly switch direction in mid-air even though there's no collision. This collision-looking event does not happen when the density/gravity/linear impulse are all the same as before, however in that situation the ship is moving too fast for my needs.

Basically I don't know why these bodies are acting differently when there is no change in mass or anything besides shape and size. There's no linear damping or collisions happening. I don't know what else could possibly be affecting the ship.

Any help or ideas is greatly appreciated.

Here is some relevant code:

Code: Select all

`public void createShipBody() {`

density = 0.05f; //normal rectangle

//density = 0.06666667f; //density for the two rectangles together

restitution = 1.0f;

bodyDef.type = BodyDef.BodyType.DynamicBody;

setBodyDefPosition(bodyDef);

body = GameCore.world.createBody(bodyDef);

setShipShapeAndFixture();

}

// For with the original rectangle

private void setShipShapeAndFixture() {

PolygonShape shape = new PolygonShape();

shape.setAsBox(Utility.pixelsToMeters(bodyWidth / 2), Utility.pixelsToMeters(bodyHeight / 2));

createFixtureDef(shape);

shape.dispose();

}

// For with triangle fixture

private void setShipShapeAndFixture() {

Vector2[] vertices = new Vector2[3];

vertices[0] = new Vector2(0, 0);

vertices[1] = new Vector2(Utility.pixelsToMeters(bodyWidth), 0);

vertices[2] = new Vector2(Utility.pixelsToMeters(bodyWidth/2), Utility.pixelsToMeters(bodyHeight));

shape.set(vertices);

createFixtureDef(shape);

shape.dispose();

}

// For multi-rectangle body

private void setShipShapeAndFixture() {

PolygonShape shape = new PolygonShape();

shape.setAsBox(Utility.pixelsToMeters(bodyWidth / 2), Utility.pixelsToMeters(bodyHeight / 4));

PolygonShape shape2 = new PolygonShape();

shape2.setAsBox(Utility.pixelsToMeters(bodyWidth / 4), Utility.pixelsToMeters(bodyHeight / 4), new Vector2(0, Utility.pixelsToMeters(bodyHeight/2)), 0);

createShipMultiFixtureDef(shape, shape2);

shape.dispose();

shape2.dispose();

}

private void createFixtureDef(PolygonShape shape) {

FixtureDef polygonFixtureDef = new FixtureDef();

polygonFixtureDef.shape = shape;

polygonFixtureDef.density = density;

polygonFixtureDef.restitution = restitution;

body.createFixture(polygonFixtureDef);

}

private void createShipMultiFixtureDef(PolygonShape shape, PolygonShape shape2) {

FixtureDef polygonFixtureDef = new FixtureDef();

polygonFixtureDef.shape = shape;

polygonFixtureDef.density = density;

polygonFixtureDef.restitution = restitution;

FixtureDef polygonFixtureDef2 = new FixtureDef();

polygonFixtureDef2.shape = shape2;

polygonFixtureDef2.density = density;

polygonFixtureDef2.restitution = restitution;

body.createFixture(polygonFixtureDef);

body.createFixture(polygonFixtureDef2);

}

/**

* This is inside the Ship class

* @param x From world center of release

* @param y From world center of release

* @param distance The capped distance of release from shipCenter, to determine force of impulse

*/

protected void applyLinearImpulse(float x, float y, float distance, float maxDistance) {

float deltaX = x - getXinPixels();

float deltaY = y - getYinPixels();

float scale = 0.8f; // Have tried playing around with this with different bodies

float force = scale * (distance/maxDistance);

float angle = (float) Math.atan2(deltaY, deltaX);

bodyWrapper.body.applyLinearImpulse(new Vector2((float) Math.cos(angle) * force,

(float) Math.sin(angle) * force), getWorldCenter(), true);

}

// This is called on each planet every game update

protected void applyGravity() {

for (SpaceObject spaceObject:spaceObjects) {

float scalar = 2.334f;

if(spaceObject instanceof Ship) {

if (gameCore.shipInMotion) {

scalar = 2f; //Have tried playng with this for different bodies

}

else {

continue; //No gravity to ship until it's launched

}

}

Vector2 objectWorldCenter = spaceObject.getWorldCenter();

Vector2 planetWorldCenter = getWorldCenter();

float planetDiameter = Utility.pixelsToMeters(getWidth());

float distance = Utility.distance(planetWorldCenter.x, planetWorldCenter.y, objectWorldCenter.x, objectWorldCenter.y);

float xDistance = planetWorldCenter.x - objectWorldCenter.x;

float yDistance = planetWorldCenter.y - objectWorldCenter.y;

float x = (float) ((xDistance * planetDiameter * scalar) / (distance*distance));

float y = (float) ((yDistance * planetDiameter * scalar) / (distance*distance));

Vector2 gravity = new Vector2(x, y);

spaceObject.bodyWrapper.body.applyForceToCenter(gravity, true);

}

}