Completely stumped. Posting everything I’ve written so far… It’s sorta a beast 8O
One other funny thing I noticed. Why is it sometimes when the player is under the box I have planted in the air, if the player jumps and basically “headbutts” the box, it’s as if the player sticks to it and floats down slowly rather than bonking it and bouncing back to the ground. Seems to happen most often when jumping directly upwards with no forward/backward motion.
PhysicsPlayground.java
[java]
public class PhysicsPlayground extends SimpleBulletApplication {
private static PhysicsPlayground application;
private static AppSettings settings;
private static PhysicsSpace mainPS;
private PhysicsPlayer player;
public static void main(String[] args) {
application = new PhysicsPlayground();
settings = new AppSettings(true);
settings.setFrameRate(120);
settings.setTitle(“Physics Playground (10/1/2010)”);
application.setSettings(settings);
application.start();
}
public static PhysicsPlayground getApplication() {
return application;
}
public static PhysicsSpace getMainPS() {
return mainPS;
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(50);
mainPS = getPhysicsSpace();
initWorld();
initPlayer();
initKeys();
getPhysicsSpace().setAccuracy(1f/120f);
}
private void initKeys() {
inputManager.addMapping(“forward”, new KeyTrigger(KeyInput.KEY_I));
inputManager.addMapping(“backpedal”, new KeyTrigger(KeyInput.KEY_K));
inputManager.addMapping(“turnleft”, new KeyTrigger(KeyInput.KEY_J));
inputManager.addMapping(“turnright”, new KeyTrigger(KeyInput.KEY_L));
inputManager.addMapping(“jump”, new KeyTrigger(KeyInput.KEY_M));
inputManager.addMapping(“croutch”, new KeyTrigger(KeyInput.KEY_O));
inputManager.addMapping(“run”, new KeyTrigger(KeyInput.KEY_LSHIFT));
inputManager.addListener(playerMovementListener, new String[]{“forward”, “backpedal”, “turnleft”, “turnright”});
inputManager.addListener(playerActionListener, new String[]{“jump”, “croutch”, “run”});
}
private AnalogListener playerMovementListener = new AnalogListener() {
public void onAnalog(String action, float value, float tpf) {
if(action.equals(“forward”)) {
player.forward();
}
else if(action.equals(“backpedal”)) {
player.backpedal();
}
else if(action.equals(“turnleft”)) {
player.turn(tpf, 1);
}
else if(action.equals(“turnright”)) {
player.turn(tpf, -1);
}
}
};
private ActionListener playerActionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if(name.equals(“jump”) && keyPressed) {
player.jump();
Sphere s = new Sphere(16, 16, .2f);
Geometry sg = new Geometry(“Jumped!”, s);
Material sm = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);
sm.setColor(“m_Color”, ColorRGBA.Red);
sg.setMaterial(sm);
sg.setLocalTranslation(new Vector3f(player.getLocalTranslation()));
rootNode.attachChild(sg);
}
if(name.equals(“croutch”) && keyPressed) {
player.croutch();
}
if(name.equals(“run”)) {
if(keyPressed) {
player.setRunning(true);
}
else if(!keyPressed) {
player.setRunning(false);
}
}
}
};
private void initWorld() {
Box worldMesh = new Box(Vector3f.ZERO, 100f, 1, 100f);
Geometry worldModel = new Geometry(“The World”, worldMesh);
Material worldMat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);
worldMat.setColor(“m_Color”, ColorRGBA.Yellow);
worldModel.setMaterial(worldMat);
PhysicsNode worldPN = new PhysicsNode(new BoxCollisionShape(new Vector3f(100f, 1, 100f)), 0);
worldPN.attachChild(worldModel);
worldPN.setLocalTranslation(new Vector3f(0, -5, 0));
worldPN.setName(“Floor”);
Material wireMat = new Material(assetManager, “Common/MatDefs/Misc/WireColor.j3md”);
wireMat.setColor(“m_Color”, ColorRGBA.Blue);
worldPN.attachDebugShape(wireMat);
rootNode.attachChild(worldPN);
rootNode.updateGeometricState();
getPhysicsSpace().add(worldPN);
Box obstacleMesh = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry obstacleModel = new Geometry(“Obstacle”, obstacleMesh);
Material obstacleMat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);
obstacleMat.setColor(“m_Color”, ColorRGBA.Red);
obstacleModel.setMaterial(obstacleMat);
PhysicsNode obstaclePN = new PhysicsNode(new BoxCollisionShape(new Vector3f(1, 1, 1)), 0);
obstaclePN.attachChild(obstacleModel);
obstaclePN.setLocalTranslation(new Vector3f(-2, -3.5f, 0));
obstaclePN.attachDebugShape(wireMat);
rootNode.attachChild(obstaclePN);
rootNode.updateGeometricState();
getPhysicsSpace().add(obstaclePN);
Box ceilingMesh = new Box(Vector3f.ZERO, 3, 0.5f, 3);
Geometry ceilingModel = new Geometry(“Obstacle”, ceilingMesh);
Material ceilingMat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);
ceilingMat.setColor(“m_Color”, ColorRGBA.Red);
ceilingModel.setMaterial(ceilingMat);
PhysicsNode ceilingPN = new PhysicsNode(new BoxCollisionShape(new Vector3f(3, 0.5f, 3)), 0);
ceilingPN.attachChild(ceilingModel);
ceilingPN.setLocalTranslation(new Vector3f(6, -2f, 6));
ceilingPN.attachDebugShape(wireMat);
rootNode.attachChild(ceilingPN);
rootNode.updateGeometricState();
getPhysicsSpace().add(ceilingPN);
}
private void initPlayer() {
Box playerMesh = new Box(Vector3f.ZERO, 0.5f, 0.25f, 0.5f);
Geometry playerModel = new Geometry(“Player Geometry”, playerMesh);
Material playerMat = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);
playerMat.setColor(“m_Color”, ColorRGBA.Green);
playerModel.setMaterial(playerMat);
playerModel.setLocalTranslation(0, -0.25f, 0);
SphereCollisionShape c = new SphereCollisionShape(playerMesh.xExtent);
player = new PhysicsPlayer(playerModel, c);
rootNode.attachChild(player);
rootNode.updateGeometricState();
getPhysicsSpace().add(player);
}
}
[/java]
And the Player - PlayerPhysics.java
[java]
public class PhysicsPlayer extends PhysicsCharacterNode {
Geometry debugSphere;
public static enum PlayerState {
IDLE, WALKING, BACKPEDALING, RUNNING, CROUTCHED, CRAWLING, CRAWLINGBACKWARDS, JUMPING, FALLING
}
/** Geometry /
private Geometry playerModel;
/ Movement Parameters (Initialized to Zero) /
private Vector3f move = new Vector3f(0, 0, 0);
private Quaternion rotation = new Quaternion();
private boolean croutched = false;
private boolean running = false;
private PlayerState playerState;
/ Movement Characteristics (Defaults) **/
private float velocity = 0;
private float acceleration = .025f; // Decel too?
private float maxForewardWalkVelocity = .25f;
private float maxForewardRunVelocity = .4f;
private float maxBackpedalVelocity = .125f;
private float runningFalloff = 0;
public PhysicsPlayer(Geometry model, SphereCollisionShape collisionShape) {
super(collisionShape, 0.5f);
this.playerModel = model;
this.attachChild(playerModel);
Material wireMat = new Material(PhysicsPlayground.getApplication().getAssetManager(),
“Common/MatDefs/Misc/WireColor.j3md”);
wireMat.setColor(“m_Color”, ColorRGBA.Blue);
this.attachDebugShape(wireMat);
setFallSpeed(10);
setGravity(10);
setJumpSpeed(5);
playerState = PlayerState.IDLE;
Sphere sphere = new Sphere(16, 16, .25f);
debugSphere = new Geometry(“Blah”, sphere);
Material smat = new Material(PhysicsPlayground.getApplication().getAssetManager(),
“Common/MatDefs/Misc/SolidColor.j3md”);
smat.setColor(“m_Color”, ColorRGBA.Orange);
debugSphere.setMaterial(smat);
attachChild(debugSphere);
}
public void forward() {
if(onGround()) {
velocity += acceleration;
if(isRunning()) {
runningFalloff = velocity;
}
if(isCroutched()) { // Different V for croutched speed?
if(velocity > maxForewardWalkVelocity /2f) {
velocity = maxForewardWalkVelocity /2f;
}
}
else {
if(!isRunning()) {
if(runningFalloff > maxForewardWalkVelocity) {
velocity = runningFalloff;
}
else if(velocity > maxForewardWalkVelocity) {
velocity = maxForewardWalkVelocity;
}
}
else if(isRunning() && velocity > maxForewardRunVelocity) {
velocity = maxForewardRunVelocity;
}
}
}
}
public void backpedal() {
if(onGround()) { // Always half of foreward? Also, reverse croutch speed?
velocity -= acceleration /2f;
if(velocity < -maxBackpedalVelocity) {
velocity = -maxBackpedalVelocity;
}
}
}
public void turn(float tpf, int direction) {
if(onGround()) {
rotation.multLocal(new Quaternion().fromAngles(0, direction * 2.2f * tpf, 0));
rotation.normalize();
playerModel.setLocalRotation(rotation);
}
}
public void croutch() {
if(onGround() && velocity < maxForewardWalkVelocity / 1.25f) { // TODO : Should it check V? Only croutch/decroutch at V < amount
// if(onGround()) {
// Vector3f preCroutchLoc = new Vector3f(this.getLocalTranslation());
// Check ceiling distance/clearance
// TODO: MAKE IT A METHOD THAT RETURNS A BOOOOOOOOOL
Ray clearanceRay = new Ray(this.getLocalTranslation(), Vector3f.UNIT_Y);
CollisionResults cr = new CollisionResults();
// PhysicsPlayground.getApplication()…getParent().updateGeometricState();
PhysicsPlayground.getApplication().getRootNode().collideWith(clearanceRay, cr);
Vector3f dist = new Vector3f(Vector3f.ZERO);
if(cr.size() > 0) {
dist = cr.getFarthestCollision().getContactPoint();
System.out.println(cr.getFarthestCollision().getGeometry().getName());
}
System.out.println("Dist: " + dist);
System.out.println("LT : " + this.getLocalTranslation());
SphereCollisionShape c = (SphereCollisionShape) this.getCollisionShape();
PhysicsPlayground.getApplication().getRootNode().detachChild(this);
PhysicsPlayground.getMainPS().remove(this);
if(!isCroutched()) { // Croutching
setCroutched(true);
c = new SphereCollisionShape(c.getRadius() * .5f);
}
else { // De-Croutching/Un-Croutching (lawl!)
setCroutched(false);
c = new SphereCollisionShape(c.getRadius() / .5f);
}
this.setCollisionShape©;
PhysicsPlayground.getApplication().getRootNode().attachChild(this);
// rootNode.updateGeometricState(); // Something with the rayTest needs this? Oh because it needs WorldTransform…
PhysicsPlayground.getMainPS().add(this);
// this.setLocalTranslation(preCroutchLoc);
Material wireMat = new Material(PhysicsPlayground.getApplication().getAssetManager(),
“Common/MatDefs/Misc/WireColor.j3md”);
wireMat.setColor(“m_Color”, ColorRGBA.Blue);
this.attachDebugShape(wireMat);
}
}
// .75 is like weight
// .3 is like forward air drag
public void drift(float tpf) {
float drifty = .75f * tpf;
if(!onGround()) {
drifty = .75f * .3f * tpf;
}
if(velocity < -FastMath.FLT_EPSILON) {
velocity += drifty;
if(velocity > 0) {
velocity = 0;
}
}
else if(velocity > FastMath.FLT_EPSILON) {
if(runningFalloff > maxForewardWalkVelocity) {
runningFalloff -= drifty;
}
velocity -= drifty;
if(velocity < 0) {
velocity = 0;
}
}
}
public boolean isCroutched() {
return croutched;
}
public void setCroutched(boolean croutched) {
this.croutched = croutched;
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
public PlayerState getPlayerState() {
return playerState;
}
@Override
public void updateLogicalState(float tpf) {
super.updateLogicalState(tpf);
drift(tpf);
move = rotation.getRotationColumn(2).mult(velocity);
// System.out.println("Magnitude/V : " + velocity + " Rotate : " + rotation.toString());
// System.out.println("RunningFall : " + runningFalloff);
setWalkDirection(move);
move = Vector3f.ZERO;
if(velocity == 0) {
if(!isCroutched()) playerState = PlayerState.IDLE;
else playerState = PlayerState.CROUTCHED;
}
else {
if(!isCroutched()) {
if(velocity > 0) {
if(velocity > maxForewardWalkVelocity) playerState = PlayerState.RUNNING;
if(velocity < maxForewardWalkVelocity) playerState = PlayerState.WALKING;
}
else {
playerState = PlayerState.BACKPEDALING;
}
}
else {
if(velocity > 0) playerState = PlayerState.CRAWLING;
if(velocity < 0) playerState = PlayerState.CRAWLINGBACKWARDS;
}
}
// System.out.println("State : " + playerState);
System.out.println(this.getLocalTranslation());
// System.out.println(this.getLocalTranslation().addLocal(0, -100, 0));
Vector3f temp = new Vector3f(this.getLocalTranslation());
temp.y -= 100;
Vector3f tempS = new Vector3f(this.getLocalTranslation());
tempS.y -= .5f;
// PhysicsPlayground.getApplication().getRootNode().attachChild(debugSphere);
// debugSphere.setLocalTranslation(this.getLocalTranslation());
// debugSphere.getLocalTranslation().y = -2;
PhysicsPlayground.getMainPS().rayTest(this.getLocalTranslation(), temp, rayListener);
}
PhysicsRayResultListener rayListener = new PhysicsRayResultListener() {
public void rayCollision(PhysicsCollisionObject arg0, Vector3f arg1,
float arg2, boolean arg3) {
// if(debugSphere.getParent() != null) {
// debugSphere.getParent().detachChildNamed(“Blah”);
// }
// attachChild(debugSphere);
debugSphere.setLocalTranslation(arg1.negate());
System.out.println(arg0);
System.out.println(arg1);
System.out.println(arg2);
System.out.println(arg3);
}
};
}
[/java]