diff --git a/build/classes/mygame/Main.class b/build/classes/mygame/Main.class index b9a1b04..e13354c 100644 Binary files a/build/classes/mygame/Main.class and b/build/classes/mygame/Main.class differ diff --git a/src/mygame/Main.java b/src/mygame/Main.java index 3095712..8f7db8c 100644 --- a/src/mygame/Main.java +++ b/src/mygame/Main.java @@ -15,6 +15,7 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.shape.Box; import com.jme3.system.AppSettings; +import com.jme3.terrain.geomipmap.TerrainQuad; import com.jme3.util.SkyFactory; import com.jme3.water.SimpleWaterProcessor; import com.jme3.water.WaterFilter; @@ -54,4 +55,16 @@ public class Main extends SimpleApplication { public void simpleRender(RenderManager rm) { //TODO: add render code } + + public static TerrainQuad SearchForTerrain(Node node) { + for (Spatial s : node.getChildren()) { + if (s instanceof TerrainQuad) { + return (TerrainQuad)s; + } else { + Node n = (Node)s; + return SearchForTerrain(n); + } + } + return null; + } } diff --git a/src/mygame/appstate/RunLevel.java b/src/mygame/appstate/RunLevel.java index 3050c48..b91a934 100644 --- a/src/mygame/appstate/RunLevel.java +++ b/src/mygame/appstate/RunLevel.java @@ -29,6 +29,7 @@ import com.jme3.shadow.DirectionalLightShadowRenderer; import com.jme3.util.SkyFactory; import com.jme3.water.WaterFilter; import mygame.Main; +import static mygame.Main.main; import mygame.control.PlayableCharacter; import mygame.control.PlayablePhysicsCharacter; @@ -58,39 +59,45 @@ public class RunLevel extends BaseAppState this.viewPort = this.app.getViewPort(); this.physics = this.stateManager.getState(BulletAppState.class); - BulletAppState bulletAppState = new BulletAppState(); - this.stateManager.attach(bulletAppState); + //BulletAppState bulletAppState = new BulletAppState(); + //this.stateManager.attach(bulletAppState); Node reflectedScene = new Node("Reflected Scene"); rootNode.attachChild(reflectedScene); Spatial TestLevel = assetManager.loadModel("Scenes/TestLevel.j3o"); Node world = (Node)TestLevel; - TestLevel.addControl(new RigidBodyControl(0)); - bulletAppState.getPhysicsSpace().addAll(TestLevel); + //TestLevel.addControl(new RigidBodyControl(0)); + //bulletAppState.getPhysicsSpace().addAll(TestLevel); //System.out.println(world.getLocalLightList().size()); - DirectionalLight sceneLight = (DirectionalLight)world.getLocalLightList().get(0); + //DirectionalLight sceneLight = (DirectionalLight)world.getLocalLightList().get(0); Node player = (Node)assetManager.loadModel("Models/Oto/Oto.mesh.xml"); Node playerNode = new Node(); playerNode.attachChild(player); playerNode.addControl(new PlayableCharacter()); - + playerNode.setUserData("Level", world); + playerNode.setUserData("Terrain", main.SearchForTerrain(world)); ChaseCamera chaseCam = new ChaseCamera(this.app.getCamera(), player, inputManager); //channel.setLoopMode(LoopMode.Cycle); - world.attachChild(playerNode); + //world.attachChild(playerNode); player.move(0,2.5f,0); player.setLocalScale(0.5f); //BetterCharacterControl playerControl = new BetterCharacterControl(1.5f,4f,10f); playerNode.addControl(chaseCam); + playerNode.move(0.01f,3f,0.01f); + + DirectionalLight sceneLight = new DirectionalLight(new Vector3f(-0.57735026f, -0.57735026f, -0.57735026f)); //System.out.println(world.getChildren()); reflectedScene.attachChild(world); reflectedScene.attachChild(TestLevel); + reflectedScene.attachChild(playerNode); + reflectedScene.addLight(sceneLight); reflectedScene.attachChild(SkyFactory.createSky(assetManager,"Textures/Sky/Bright/BrightSky.dds",false)); FilterPostProcessor fpp = new FilterPostProcessor(assetManager); diff --git a/src/mygame/control/PlayableCharacter.java b/src/mygame/control/PlayableCharacter.java index 245a552..78e5e88 100644 --- a/src/mygame/control/PlayableCharacter.java +++ b/src/mygame/control/PlayableCharacter.java @@ -4,17 +4,15 @@ import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimControl; import com.jme3.animation.AnimEventListener; import com.jme3.animation.LoopMode; -import com.jme3.bullet.control.BetterCharacterControl; import com.jme3.collision.CollisionResults; -import template.*; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.export.Savable; -import com.jme3.input.ChaseCamera; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; import com.jme3.input.controls.AnalogListener; import com.jme3.input.controls.KeyTrigger; +import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Ray; import com.jme3.math.Vector3f; @@ -26,14 +24,23 @@ import com.jme3.scene.Spatial; import com.jme3.scene.control.AbstractControl; import com.jme3.scene.control.Control; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import mygame.Main; import static mygame.Main.main; public class PlayableCharacter extends AbstractControl implements Savable, Cloneable, ActionListener, AnalogListener, AnimEventListener { - float speed = 1000.0f; + float speed = 10.0f; + float jumpSpd = 0.1f; + float vspd = 0.0f; + float gravity = -0.25f; + + float walkOffTime = 0.25f; //How long you can jump after becoming airborne. + float airTime = 0.0f; //Amount of time in air. + + float rotation_time = 3f; + float current_time = 0.0f; + Spatial standingOn = null; + + Quaternion prevRot; boolean walkingForward = false; boolean walkingBackward = false; @@ -55,7 +62,7 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone public void setSpatial(Spatial spatial) { super.setSpatial(spatial); //control = spatial.getControl(BetterCharacterControl.class); - + Node myNode = (Node)spatial; control = ((Node)spatial).getChild(0).getControl(AnimControl.class); control.addListener(this); @@ -75,6 +82,7 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone main.getInputManager().addListener(this, "StrafeRight"); main.getInputManager().addListener(this, "StrafeLeft"); main.getInputManager().addListener(this, "Jump"); + } /** Implement your spatial's behaviour here. @@ -84,6 +92,7 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone */ @Override protected void controlUpdate(float tpf){ + //System.out.println(((Geometry)(((Node)((Node)spatial).getChild(0)).getChild(0))).getName()); //Possibility of using geometry node names. if (moving) { if (!channel.getAnimationName().equalsIgnoreCase("Walk")) { channel.setAnim("Walk"); @@ -113,14 +122,37 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone walkDirection.addLocal(camDir.negate()); moving=true; } - + if (moving) { - walkDirection.multLocal(speed).multLocal(tpf); + SmoothMoveWalk(walkDirection, tpf); } else { channel.setAnim("stand"); channel.setLoopMode(LoopMode.DontLoop); } } + //isOnGround(); + if (!isOnGround()) { + vspd+=gravity*tpf; + airTime+=tpf; + } else { + vspd=0; + airTime=0; + } + spatial.move(0,vspd,0); + } + + private Node GetLevel() { + return (Node)(spatial.getUserData("Level")); + } + + private void SmoothMoveWalk(Vector3f walkDirection, float tpf) { + walkDirection.multLocal(speed).multLocal(tpf); + spatial.move(walkDirection); + Quaternion q = new Quaternion().fromAngleAxis((float)FastMath.atan2(walkDirection.x,walkDirection.z),Vector3f.UNIT_Y); + Quaternion q2 = spatial.getLocalRotation(); + q2.slerp(q,Math.min(current_time/rotation_time,1)); + spatial.setLocalRotation(q2); + current_time+=tpf; } @Override @@ -150,18 +182,26 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone public void onAction(String name, boolean isPressed, float tpf) { switch (name) { case "StrafeLeft":{ + current_time = 0.0f; + prevRot = spatial.getLocalRotation(); strafingLeft = isPressed; moving = true; }break; case "StrafeRight":{ + current_time = 0.0f; + prevRot = spatial.getLocalRotation(); strafingRight = isPressed; moving = true; }break; case "WalkBackward":{ + current_time = 0.0f; + prevRot = spatial.getLocalRotation(); walkingBackward = isPressed; moving = true; }break; case "WalkForward":{ + current_time = 0.0f; + prevRot = spatial.getLocalRotation(); walkingForward = isPressed; moving = true; }break; @@ -172,6 +212,9 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone public void onAnalog(String name, float value, float tpf) { switch (name) { case "Jump":{ + if (isOnGround() || airTime<=walkOffTime) { + vspd=jumpSpd; + } }break; } } @@ -184,4 +227,42 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone @Override public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { } + + private boolean isOnGround() { + if (vspd>0) { + System.out.println(vspd); + return false; + } + CollisionResults results = new CollisionResults(); + Ray r = new Ray(spatial.getLocalTranslation().add(0,2.5f-vspd,0),Vector3f.UNIT_Y.negate()); + GetLevel().updateGeometricState(); + GetLevel().collideWith(r, results); + System.out.println("Collisions("+results.size()+"):"); + for (int i=0;i0) { + //System.out.println(results.getCollision(0)); + if (results.getClosestCollision().getContactPoint().x!=0 || + results.getClosestCollision().getContactPoint().y!=0 || + results.getClosestCollision().getContactPoint().z!=0) { + System.out.println(results.getClosestCollision()); + if (results.getClosestCollision().getDistance()<=2.6-vspd) { + spatial.setLocalTranslation(results.getClosestCollision().getContactPoint()); + return true; + } else { + return false; + } + } else { + vspd=jumpSpd; //???Undefined behavior. + } + } + /*if (results.size()>0) { + System.out.println("Distance: "+results.getClosestCollision().getDistance()); + //if (results.getClosestCollision().getDistance()<=5.0f) { + + //} + }*/ + return false; + } } \ No newline at end of file