Using AppState and controls, we can use the built-in Physics Engine in jMonkeyEngine.

The floor is a Box mesh of 25 square meter dimensions.

// *** 1. Start (Create Floor)
Box b = new Box(5,1,5);
Geometry floor = new Geometry("floor", b);
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/ShowNormals.j3md");
floor.setMaterial(mat);
rootNode.attachChild(floor);
// *** 1. End
We have to start the BulletAppState to use Bullet physics.

// *** 2. Start (Physics - 3rd line debug)
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().enableDebug(assetManager);
// *** 2. End
We set a RigidBodyControl object to the floor, so it is immovable.

// *** 3. Start (floor is rigid)
scenePhy = new RigidBodyControl(0f);
floor.addControl(scenePhy);
bulletAppState.getPhysicsSpace().add(floor);
// *** 3. End
The player is a BetterCharacterControl object to use the Physics.

// *** 4. Start (invisible player)
playerNode = new Node("the player");
playerNode.setLocalTranslation(
new Vector3f(0, 1, 0));
rootNode.attachChild(playerNode);
playerControl = new BetterCharacterControl(
1.5f, 4, 30f);
playerControl.setJumpForce(new Vector3f(0, 300, 0));
playerControl.setGravity(new Vector3f(0, -10, 0));
playerNode.addControl(playerControl);
bulletAppState.getPhysicsSpace().add(playerControl);
// *** 4. End
A camera is created, fixed to our player.

// *** 5. Start (Camera attached to Player)
camNode = new CameraNode("CamNode", cam);
camNode.setControlDir(CameraControl.
ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 4, -6));
Quaternion quat = new Quaternion();
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
playerNode.attachChild(camNode);
camNode.setEnabled(true);
flyCam.setEnabled(false);
// *** 5. End
The four arrow keys are registered.

// *** 6. Start (Arrow Keys)
inputManager.addMapping("Forward",
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Back",
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Left",
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Right",
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addListener(this, "Left",
"Right","Forward", "Back");
// *** 6. End
In simpleUpdate(), the booleans are checked to update player position, and the attached camera.

// *** 7. Start (Walk character)
@Override
public void simpleUpdate(float tpf) {
Vector3f ForwardDir = Vector3f.UNIT_Z;
Vector3f LeftDir = Vector3f.UNIT_X;
walkDirection.set(0, 0, 0);
if (forward) {
walkDirection = walkDirection.add(ForwardDir);
} else if (backward) {
walkDirection = walkDirection.subtract(ForwardDir);
}
if (Left) {
walkDirection = walkDirection.add(LeftDir);
} else if (Right) {
walkDirection = walkDirection.subtract(LeftDir);
}
playerControl.setWalkDirection(walkDirection);
vy = playerControl.getVelocity().y;
if (vy<-10f) {
System.out.println("Game over");
}
}
// *** 7. End
When an action, arrow key press or release, occurs, the booleans will be set true or false.

// *** 8. Start (Which key pressed)
public void onAction(String binding, boolean isPressed, float tpf) {
if (binding.equals("Left")) {
Left = isPressed;
}
else if (binding.equals("Right")) {
Right = isPressed;
}
else if (binding.equals("Forward")) {
forward = isPressed;
}
else if (binding.equals("Back")) {
backward = isPressed;
}
}
// *** 8. End
// JMonkey44.java
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.BetterCharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.control.CameraControl;
import com.jme3.scene.shape.Box;
public class JMonkey44 extends SimpleApplication
implements ActionListener {
public static void main(String[] args) {
JMonkey44 app = new JMonkey44();
app.start();
}
private BulletAppState bulletAppState; // physics
private RigidBodyControl scenePhy; // rigid floor
private Node playerNode;
private BetterCharacterControl playerControl; // player
private CameraNode camNode; // physics camera
// Walking vars
private Vector3f walkDirection = new Vector3f(0,0,0);
private boolean Left = false, Right = false,
forward = false, backward = false;
private float vy; // Player downwad velocity
@Override
public void simpleInitApp() {
viewPort.setBackgroundColor(ColorRGBA.White);
setDisplayFps(false);
setDisplayStatView(false);
// *** 1. Start (Create Floor)
Box b = new Box(5,1,5);
Geometry floor = new Geometry("floor", b);
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/ShowNormals.j3md");
floor.setMaterial(mat);
rootNode.attachChild(floor);
// *** 1. End
// *** 2. Start (Physics - 3rd line debug)
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().enableDebug(assetManager);
// *** 2. End
// *** 3. Start (floor is rigid)
scenePhy = new RigidBodyControl(0f);
floor.addControl(scenePhy);
bulletAppState.getPhysicsSpace().add(floor);
// *** 3. End
// *** 4. Start (invisible player)
playerNode = new Node("the player");
playerNode.setLocalTranslation(
new Vector3f(0, 1, 0));
rootNode.attachChild(playerNode);
playerControl = new BetterCharacterControl(
1.5f, 4, 30f);
playerControl.setJumpForce(new Vector3f(0, 300, 0));
playerControl.setGravity(new Vector3f(0, -10, 0));
playerNode.addControl(playerControl);
bulletAppState.getPhysicsSpace().add(playerControl);
// *** 4. End
// *** 5. Start (Camera attached to Player)
camNode = new CameraNode("CamNode", cam);
camNode.setControlDir(CameraControl.
ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 4, -6));
Quaternion quat = new Quaternion();
quat.lookAt(Vector3f.UNIT_Z, Vector3f.UNIT_Y);
camNode.setLocalRotation(quat);
playerNode.attachChild(camNode);
camNode.setEnabled(true);
flyCam.setEnabled(false);
// *** 5. End
// *** 6. Start (Arrow Keys)
inputManager.addMapping("Forward",
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("Back",
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addMapping("Left",
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("Right",
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addListener(this, "Left",
"Right","Forward", "Back");
// *** 6. End
}
// *** 7. Start (Walk character)
@Override
public void simpleUpdate(float tpf) {
Vector3f ForwardDir = Vector3f.UNIT_Z;
Vector3f LeftDir = Vector3f.UNIT_X;
walkDirection.set(0, 0, 0);
if (forward) {
walkDirection = walkDirection.add(ForwardDir);
} else if (backward) {
walkDirection = walkDirection.subtract(ForwardDir);
}
if (Left) {
walkDirection = walkDirection.add(LeftDir);
} else if (Right) {
walkDirection = walkDirection.subtract(LeftDir);
}
playerControl.setWalkDirection(walkDirection);
vy = playerControl.getVelocity().y;
if (vy<-10f) {
System.out.println("Game over");
}
}
// *** 7. End
@Override
public void simpleRender(RenderManager rm) {
}
// *** 8. Start (Which key pressed)
public void onAction(String binding, boolean isPressed, float tpf) {
if (binding.equals("Left")) {
Left = isPressed;
}
else if (binding.equals("Right")) {
Right = isPressed;
}
else if (binding.equals("Forward")) {
forward = isPressed;
}
else if (binding.equals("Back")) {
backward = isPressed;
}
}
// *** 8. End
}
Output:
No comments:
Post a Comment