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