diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index 817f28c..4732b6b 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -5,6 +5,7 @@ file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/Main.java file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/appstate/RunLevel.java + file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/PhysicsControl.java file:/E:/GameProjects/Rabi-Bounce-Bounce-R/src/mygame/control/PlayableCharacter.java diff --git a/src/mygame/appstate/RunLevel.java b/src/mygame/appstate/RunLevel.java index b91a934..80bdaf5 100644 --- a/src/mygame/appstate/RunLevel.java +++ b/src/mygame/appstate/RunLevel.java @@ -18,11 +18,16 @@ import com.jme3.input.InputManager; import com.jme3.input.KeyInput; import com.jme3.input.controls.KeyTrigger; import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; import com.jme3.math.Vector3f; import com.jme3.post.FilterPostProcessor; import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Sphere; +import static com.jme3.shader.Shader.ShaderType.Geometry; import static com.jme3.shader.VarType.Vector3; import com.jme3.shadow.DirectionalLightShadowFilter; import com.jme3.shadow.DirectionalLightShadowRenderer; @@ -30,6 +35,7 @@ import com.jme3.util.SkyFactory; import com.jme3.water.WaterFilter; import mygame.Main; import static mygame.Main.main; +import mygame.control.PhysicsControl; import mygame.control.PlayableCharacter; import mygame.control.PlayablePhysicsCharacter; @@ -76,7 +82,19 @@ public class RunLevel extends BaseAppState playerNode.attachChild(player); playerNode.addControl(new PlayableCharacter()); playerNode.setUserData("Level", world); - playerNode.setUserData("Terrain", main.SearchForTerrain(world)); + + for (int i=0;i<500;i++) { + Node sphereNode = new Node(); + Geometry sphere = new Geometry("PhysicsSphere",new Sphere((int)(Math.random()*10)+3,(int)(Math.random()*10)+3,3f)); + Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + mat.setColor("Color", ColorRGBA.randomColor()); + sphere.setMaterial(mat); + sphere.setLocalTranslation(0.01f,1.5f,0.01f); + sphereNode.attachChild(sphere); + sphereNode.addControl(new PhysicsControl(world,0.0f,-0.2f,3f)); + sphereNode.setLocalTranslation(0.01f+75f*(float)Math.random()-75f*(float)Math.random(),25f+300f*(float)Math.random(),0.01f+75f*(float)Math.random()-75f*(float)Math.random()); + reflectedScene.attachChild(sphereNode); + } ChaseCamera chaseCam = new ChaseCamera(this.app.getCamera(), player, inputManager); diff --git a/src/mygame/control/PhysicsControl.java b/src/mygame/control/PhysicsControl.java new file mode 100644 index 0000000..15ae85d --- /dev/null +++ b/src/mygame/control/PhysicsControl.java @@ -0,0 +1,145 @@ +package mygame.control; + +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.math.Ray; +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; +import com.jme3.scene.control.AbstractControl; +import com.jme3.scene.control.Control; +import java.io.IOException; + +public class PhysicsControl extends AbstractControl implements Savable, Cloneable { + + float jumpSpd = 0.1f; + float vspd = 0.0f; + float gravity = -0.25f; + + float modelHeight = 2.5f; + + Node levelData; + + float walkOffTime = 0.25f; //How long you can jump after becoming airborne. + float airTime = 0.0f; //Amount of time in air. + + public PhysicsControl(Node levelData, float jumpSpd, float gravity, float modelHeight){ + this.levelData=levelData; + this.jumpSpd=jumpSpd; + this.gravity=gravity; + this.modelHeight=modelHeight; + } + + /** This method is called when the control is added to the spatial, + * and when the control is removed from the spatial (setting a null value). + * It can be used for both initialization and cleanup. + */ + @Override + public void setSpatial(Spatial spatial) { + super.setSpatial(spatial); + + spatial.setUserData("Level", levelData); + } + + /** Implement your spatial's behaviour here. + * From here you can modify the scene graph and the spatial + * (transform them, get and set userdata, etc). + * This loop controls the spatial while the Control is enabled. + */ + @Override + protected void controlUpdate(float tpf){ + if (!isOnGround()) { + vspd+=gravity*tpf; + airTime+=tpf; + } else { + vspd=0; + airTime=0; + } + spatial.move(0,vspd,0); + } + + @Override + public Control cloneForSpatial(Spatial spatial){ + final PhysicsControl control = new PhysicsControl((Node)(levelData.clone()),jumpSpd,gravity,modelHeight); + /* Optional: use setters to copy userdata into the cloned control */ + // control.setIndex(i); // example + control.setSpatial(spatial); + return control; + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp){ + /* Optional: rendering manipulation (for advanced users) */ + } + + @Override + public void read(JmeImporter im) throws IOException { + super.read(im); + // im.getCapsule(this).read(...); + } + + @Override + public void write(JmeExporter ex) throws IOException { + super.write(ex); + // ex.getCapsule(this).write(...); + } + + private Node GetLevel() { + return (Node)(spatial.getUserData("Level")); + } + + void jump() { + setVerticalSpeed(jumpSpd); + } + + void setVerticalSpeed(float spd) { + vspd = spd; + } + + void addVerticalSpeed(float spd) { + vspd += spd; + } + + float getVerticalSpeed() { + return vspd; + } + + boolean isOnGround() { + if (vspd>0) { + System.out.println(vspd); + return false; + } + CollisionResults results = new CollisionResults(); + Ray r = new Ray(spatial.getLocalTranslation().add(0,(modelHeight/2)-vspd,0),Vector3f.UNIT_Y.negate()); + GetLevel().updateGeometricState(); + GetLevel().collideWith(r, results); + if (results.size()>0) { + //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()<=(modelHeight/2)+0.1-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 diff --git a/src/mygame/control/PlayableCharacter.java b/src/mygame/control/PlayableCharacter.java index 78e5e88..b98a4b7 100644 --- a/src/mygame/control/PlayableCharacter.java +++ b/src/mygame/control/PlayableCharacter.java @@ -29,16 +29,9 @@ import static mygame.Main.main; public class PlayableCharacter extends AbstractControl implements Savable, Cloneable, ActionListener, AnalogListener, AnimEventListener { 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; @@ -50,6 +43,8 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone AnimChannel channel; //AnimChannel channel_lowerbody; AnimControl control; + + PhysicsControl physics; public PlayableCharacter() { } // empty serialization constructor @@ -64,6 +59,14 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone //control = spatial.getControl(BetterCharacterControl.class); Node myNode = (Node)spatial; + physics = new PhysicsControl( + (Node)spatial.getUserData("Level"), + 0.1f, + -0.25f, + 5f + ); + myNode.addControl(physics); + control = ((Node)spatial).getChild(0).getControl(AnimControl.class); control.addListener(this); channel = control.createChannel(); @@ -131,18 +134,6 @@ public class PlayableCharacter extends AbstractControl implements Savable, Clone } } //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) { @@ -212,12 +203,16 @@ 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; + if (isOnGround() || physics.airTime<=physics.walkOffTime) { + physics.jump(); } }break; } } + + public boolean isOnGround() { + return physics.isOnGround(); + } @Override public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) { @@ -227,42 +222,4 @@ 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