package com.arretadogames.pilot.entities;
import java.util.HashSet;
import org.jbox2d.collision.Manifold;
import org.jbox2d.collision.WorldManifold;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.Fixture;
import org.jbox2d.dynamics.contacts.Contact;
import com.arretadogames.pilot.R;
import com.arretadogames.pilot.render.PhysicsRect;
import com.arretadogames.pilot.render.AnimationSwitcher;
import com.arretadogames.pilot.render.opengl.GLCanvas;
public class Platform extends Entity{
private Fixture m_platformFixture;
private float width;
private float height;
final private WorldManifold worldManifold = new WorldManifold();
private HashSet<Contact> contactSet;
private PhysicsRect background;
public Platform(float x, float y) {
super(x, y);
PolygonShape shape = new PolygonShape();
width = 4f;
height = 0.7f;
shape.setAsBox(width/2, height/2);
m_platformFixture = body.createFixture(shape, 1f);
body.setType(BodyType.KINEMATIC);
contactSet = new HashSet<Contact>();
physRect = new PhysicsRect(width + 0.1f, height + 0.15f);
background = new PhysicsRect(width - 0.2f, y);
}
public void beginContact(Entity e, Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Fixture platformFixture = null;
Fixture otherFixture = null;
if ( fixtureA == m_platformFixture ) {
platformFixture = fixtureA;
otherFixture = fixtureB;
}
else if ( fixtureB == m_platformFixture ) {
platformFixture = fixtureB;
otherFixture = fixtureA;
}
if ( platformFixture == null || otherFixture.isSensor()){
return;
}
Body platformBody = platformFixture.getBody();
Body otherBody = otherFixture.getBody();
int numPoints = contact.getManifold().pointCount;
contact.getWorldManifold( worldManifold );
for (int i = 0; i < numPoints; i++) {
Vec2 pointVelPlatform = platformBody.getLinearVelocityFromWorldPoint( worldManifold.points[i] );
Vec2 pointVelOther = otherBody.getLinearVelocityFromWorldPoint( worldManifold.points[i] );
Vec2 relativeVel = platformBody.getLocalVector( pointVelOther.add(pointVelPlatform.negate() ) );
if ( relativeVel.y < -1 )
return;
else if ( relativeVel.y < 1 ) {
Vec2 relativePoint = platformBody.getLocalPoint( worldManifold.points[i] );
float platformFaceY = height;//front of platform :(
if ( relativePoint.y > platformFaceY - 0.05 )
return;
}
}
if(numPoints == 0) return;
contact.setEnabled(false);
contactSet.add(contact);
}
public void endContact(Entity e, Contact contact) {
contactSet.remove(contact);
}
@Override
public void preSolve(Entity e, Contact contact, Manifold oldManifold) {
if(contactSet.contains(contact))contact.setEnabled(false);
}
@Override
public void render(GLCanvas canvas, float timeElapsed) {
canvas.saveState();
canvas.translatePhysics(getPosX(), getPosY() / 2);
canvas.drawBitmap(R.drawable.back_platform, background, 1, background.height() / (height * 1.5f));
canvas.restoreState();
canvas.saveState();
canvas.translatePhysics(getPosX(), getPosY());
canvas.drawBitmap(R.drawable.platform, physRect);
canvas.restoreState();
}
@Override
public EntityType getType() {
return EntityType.ONEWAY_WALL;
}
@Override
public void setSprite(AnimationSwitcher sprite) {
}
@Override
public int getLayerPosition() {
return super.getLayerPosition() + 1;
}
}