Good point. Well its far from being a game yet.
[java]
package mygame;
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
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.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.CartoonEdgeFilter;
import com.jme3.post.filters.LightScatteringFilter;
import com.jme3.renderer.Caps;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.shadow.CompareMode;
import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.system.AppSettings;
public class Main extends SimpleApplication implements ActionListener, AnimEventListener {
public static void main(String[] args) {
Main app = new Main();
AppSettings settings = new AppSettings(true);
settings.setFrameRate(60);
settings.setTitle("Turtle Race");
app.setSettings(settings);
app.start();
}
private FilterPostProcessor fpp;
private Spatial gameLevel;
private Spatial player;
private BulletAppState bulletAppState;
private BetterCharacterControl playerControl;
private ChaseCamera chaseCam;
private AnimChannel animChannel;
private AnimControl animControl;
private Vector3f rotate = Vector3f.ZERO;
private boolean left, right, up, down, sprint;
private float rotateSpeed, moveSpeed, sprintSpeed, backMoveSpeed;
private DirectionalLight sun;
private Node playerNode;
private Node terrain;
@Override
public void simpleInitApp() {
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
flyCam.setEnabled(false);
mouseInput.setCursorVisible(false);
initSunLight();
initAmbientLight();
initScene();
initPlayer();
initPlayerPhysics();
initChaseCam();
initControls();
setupFilters();
}
@Override
public void simpleUpdate(float tpf) {
//initCameraCollision();
getTerrainNormal();
moveSpeed = 55f * tpf;
sprintSpeed = 130f * tpf;
rotateSpeed = 35f * tpf;
movePlayer();
rotatePlayer();
if (animChannel.getAnimationName().equals("walk") && !up) {
animChannel.setAnim("idle");
animChannel.setLoopMode(LoopMode.Loop);
}
}
@Override
public void simpleRender(RenderManager rm) {
}
private void initSunLight() {...}
public void setupFilters() {...}
public void makeToonish(Spatial spatial) {...}
private void initAmbientLight() {...}
private void initScene() {
gameLevel = assetManager.loadModel("Scenes/Scene.j3o");
gameLevel.setLocalTranslation(0, -1, 0);
gameLevel.addControl(new RigidBodyControl(0f));
gameLevel.setShadowMode(RenderQueue.ShadowMode.Receive);
terrain = new Node("Terrain");
terrain.attachChild(gameLevel);
rootNode.attachChild(terrain);
bulletAppState.getPhysicsSpace().addAll(gameLevel);
}
private void initPlayer() {
//create player
player = assetManager.loadModel("Models/turtle/TURTLE_body.mesh.j3o");
player.setMaterial(assetManager.loadMaterial("Materials/turtle.j3m"));
player.scale(1f);
player.setShadowMode(ShadowMode.CastAndReceive);
playerNode = new Node();
playerNode.attachChild(player);
animControl = player.getControl(AnimControl.class);
animControl.addListener(this);
animChannel = animControl.createChannel();
animChannel.setAnim("idle");
animChannel.setSpeed(1f);
}
private void initPlayerPhysics() {
//Create Controls
playerControl = new BetterCharacterControl(0.26f, 0.5f, 20f); //contruct character collsion shape and weight
playerNode.addControl(playerControl); //attach Control to playerNode crated above
playerControl.setJumpForce(new Vector3f(0, 20f, 0));
playerControl.warp(new Vector3f(20, -5, 20));
bulletAppState.getPhysicsSpace().add(playerControl);
bulletAppState.getPhysicsSpace().addAll(playerNode);
playerControl.setGravity(new Vector3f(0f, -10f, 0f));
rootNode.attachChild(playerNode);
}
private void movePlayer() {
stopPlayer();
if ((up /*|| down*/) || (up && sprint)) {
animChannel.setSpeed(2f);
Vector3f walkDir = playerControl.getViewDirection().mult(moveSpeed);
walkAnim();
/*if (!up) {
walkDir = playerControl.getViewDirection().mult(backMoveSpeed);
walkDir.negateLocal();
}*/
if (sprint) {
walkDir = playerControl.getViewDirection().mult(sprintSpeed);
animChannel.setSpeed(3f);
}
playerControl.setWalkDirection(walkDir);
System.out.println(walkDir);
}
}
private void rotatePlayer() {
if ((left && up) || (right && up)) {
Quaternion rotQua = new Quaternion().fromAngleAxis(FastMath.DEG_TO_RAD * rotateSpeed, Vector3f.UNIT_Y);
if (!left) {
rotQua.inverseLocal();
}
rotQua = playerNode.getLocalRotation().mult(rotQua);
playerControl.setViewDirection(rotQua.mult(Vector3f.UNIT_Z).normalizeLocal());
}
}
private void stopPlayer() {
playerControl.setWalkDirection(Vector3f.ZERO);
}
private void walkAnim() {
if (!animChannel.getAnimationName().equals("walk") && up) {
animChannel.setAnim("walk");
animChannel.setSpeed(2f);
animChannel.setLoopMode(LoopMode.Loop);
}
}
private void initChaseCam() {
chaseCam = new ChaseCamera(cam, playerNode, inputManager);
chaseCam.setSmoothMotion(true);
chaseCam.setTrailingEnabled(true);
chaseCam.setMinDistance(3f);
chaseCam.setDefaultDistance(15f);
chaseCam.setTrailingSensitivity(10f);
}
private void initCameraCollision() {...}
private void getTerrainNormal(){
//doesn't work (yet)
CollisionResults results = new CollisionResults();
Ray ray = new Ray();
Vector3f pos = new Vector3f(playerNode.getWorldTranslation().add(0f, 1f, 0f));
Vector3f dir = new Vector3f(0f, -1f, 0f);
ray.setOrigin(pos);
ray.setDirection(dir);
terrain.collideWith(ray, results);
Vector3f normals = results.getClosestCollision().getContactNormal();
if ((rotate.x) != (normals.x)){
rotate = normals;
player.rotateUpTo(rotate);
}
}
private void initControls() {
inputManager.addMapping("CharLeft", new KeyTrigger(KeyInput.KEY_A));
inputManager.addMapping("CharRight", new KeyTrigger(KeyInput.KEY_D));
inputManager.addMapping("CharForward", new KeyTrigger(KeyInput.KEY_W));
inputManager.addMapping("CharBackward", new KeyTrigger(KeyInput.KEY_S));
inputManager.addMapping("CharSprint", new KeyTrigger(KeyInput.KEY_LSHIFT));
inputManager.addListener(this, "CharLeft", "CharRight");
inputManager.addListener(this, "CharForward", "CharBackward");
inputManager.addListener(this, "CharSprint");
}
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("CharLeft")) {
left = isPressed;
}
if (name.equals("CharRight")) {
right = isPressed;
}
if (name.equals("CharForward")) {
up = isPressed;
}
if (name.equals("CharBackward")) {
down = isPressed;
}
if (name.equals("CharSprint")) {
sprint = isPressed;
}
}
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {}
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {}
}
[/java]