From 59210eca75058eb477e4f1977eb46e56b0d6be7c Mon Sep 17 00:00:00 2001 From: Dejvino Date: Wed, 4 Jan 2017 01:03:13 +0100 Subject: [PATCH] Added enter / leave vehicle by Enter. Refactoring. --- assets/Scenes/TestMap.j3o | Bin 19469503 -> 19469320 bytes src/roadtrip/RoadTrip.java | 230 ++++++++++++++---------------- src/roadtrip/VehicleInstance.java | 65 +++++++++ src/roadtrip/VehicleNode.java | 34 +++++ 4 files changed, 205 insertions(+), 124 deletions(-) create mode 100644 src/roadtrip/VehicleInstance.java create mode 100644 src/roadtrip/VehicleNode.java diff --git a/assets/Scenes/TestMap.j3o b/assets/Scenes/TestMap.j3o index f4d60441a5d388ed96c5f47b7578e39444307cc1..c20cb54fb6679e3295f94a023b74f184a90982bf 100644 GIT binary patch delta 24425 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%0DT8Cfv7=LCC%BgjH p{#feIa<$He5;>=89e%a|+nKeFKMzd{!XfAWcbNIG-^$I~{tt@lq5S{= diff --git a/src/roadtrip/RoadTrip.java b/src/roadtrip/RoadTrip.java index 799f983..26578bb 100644 --- a/src/roadtrip/RoadTrip.java +++ b/src/roadtrip/RoadTrip.java @@ -15,10 +15,11 @@ import com.jme3.bullet.control.VehicleControl; import com.jme3.input.KeyInput; import com.jme3.input.controls.ActionListener; 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.FastMath; -import com.jme3.math.Matrix3f; +import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.Node; @@ -39,92 +40,22 @@ public class RoadTrip extends SimpleApplication implements ActionListener { public static boolean DEBUG = false;//true; private BulletAppState bulletAppState; - - private VehicleNode playerVehicleNode; - + + Spatial map; private List vehicles = new LinkedList<>(); - private static class WeakVehicle extends VehicleInstance - { - WeakVehicle() - { - super(WEAK, 200.0f, 100.0f); - } - } - - private static class TruckVehicle extends VehicleInstance - { - TruckVehicle() - { - super(TRUCK, 1400.0f, 200.0f); - } - } - - private static class SportVehicle extends VehicleInstance - { - SportVehicle() - { - super(SPORT, 20000.0f, 200.0f); - } - } - - private static class VehicleInstance - { - final static int WEAK = 1; - final static int TRUCK = 2; - final static int SPORT = 3; - final static int FOOT = 4; - - int carType; - float accelerationForce = 200.0f; - float brakeForce = 100.0f; - float steeringValue = 0; - float accelerationValue = 0; - float accelerationSmooth = 0; - - VehicleInstance(int carType, float accelerationForce, float brakeForce) - { - this.carType = carType; - this.accelerationForce = accelerationForce; - this.brakeForce = brakeForce; - } - } - - private static class VehicleNode extends Node - { - VehicleInstance vehicleInstance; - - VehicleControl vehicleControl; - - Spatial vehicleModel; - - AudioNode engineAudio; - AudioNode wheelsAudio; - AudioNode wheelSlipAudio; - - public VehicleNode(String name, VehicleInstance vehicleInstance, - VehicleControl vehicleControl, Spatial vehicleModel) - { - super(name); - this.vehicleInstance = vehicleInstance; - this.vehicleControl = vehicleControl; - this.vehicleModel = vehicleModel; - } - } - private Node playerNode; private BetterCharacterControl playerPersonControl; private Vector3f jumpForce = new Vector3f(0, 3000, 0); private Vector3f walkDir = new Vector3f(); - + private VehicleNode playerVehicleNode; + public static void main(String[] args) { RoadTrip app = new RoadTrip(); app.start(); } - - Spatial map; - + @Override public void simpleInitApp() { bulletAppState = new BulletAppState(); @@ -138,6 +69,11 @@ public class RoadTrip extends SimpleApplication implements ActionListener { addMap(); + DirectionalLight dl = new DirectionalLight(); + dl.setColor(ColorRGBA.White); + dl.setDirection(new Vector3f(1, -1, 1)); + rootNode.addLight(dl); + addPlayer(); addCar(); @@ -178,39 +114,12 @@ public class RoadTrip extends SimpleApplication implements ActionListener { private void addCar() { Node vehicleModel = new Node("VehicleModel"); - VehicleInstance vehicleInstance = new WeakVehicle(); + VehicleInstance vehicleInstance = VehicleInstance.createVehicle(vehicles.size() % VehicleInstance.getVehicleTypesCount()); Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); mat.getAdditionalRenderState().setWireframe(true); mat.setColor("Color", ColorRGBA.Black); - //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0 - //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0 - CompoundCollisionShape compoundShape = new CompoundCollisionShape(); - BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.4f, 0.5f, 3.6f)); - compoundShape.addChildShape(box, new Vector3f(0, 1, 0)); - - if (vehicleInstance.carType == VehicleInstance.TRUCK) { - BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.4f, 0.8f, 1.0f)); - compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, 2f)); - } else if (vehicleInstance.carType == VehicleInstance.SPORT) { - BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.2f, 0.6f, 2.0f)); - compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, -1f)); - } - - VehicleControl vehicleControl = new VehicleControl(compoundShape, 500); - vehicleModel.addControl(vehicleControl); - - //setting suspension values for wheels, this can be a bit tricky - //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en - float stiffness = 30.0f;//200=f1 car - float compValue = .1f; //(should be lower than damp) - float dampValue = .2f; - vehicleControl.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); - vehicleControl.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); - vehicleControl.setSuspensionStiffness(stiffness); - vehicleControl.setMaxSuspensionForce(10000.0f); - //Create four wheels and add them at their locations Vector3f wheelDirection = new Vector3f(0, -1, 0); // was 0, -1, 0 Vector3f wheelAxle = new Vector3f(-1, 0, 0); // was -1, 0, 0 @@ -221,10 +130,48 @@ public class RoadTrip extends SimpleApplication implements ActionListener { float zOff = 2f; Geometry carBody = new Geometry("car body", new Box(new Vector3f(0.0f, 1f, 0.0f), 1.4f, 0.5f, 3.6f)); - Material matBody = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - matBody.setColor("Color", ColorRGBA.Red); + Material matBody = new Material(getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); + matBody.setFloat("Shininess", 32f); + matBody.setBoolean("UseMaterialColors", true); + matBody.setColor("Ambient", ColorRGBA.Black); + matBody.setColor("Diffuse", ColorRGBA.Red); + matBody.setColor("Specular", ColorRGBA.White); carBody.setMaterial(matBody); vehicleModel.attachChild(carBody); + + //create a compound shape and attach the BoxCollisionShape for the car body at 0,1,0 + //this shifts the effective center of mass of the BoxCollisionShape to 0,-1,0 + CompoundCollisionShape compoundShape = new CompoundCollisionShape(); + BoxCollisionShape box = new BoxCollisionShape(new Vector3f(1.4f, 0.5f, 3.6f)); + compoundShape.addChildShape(box, new Vector3f(0, 1, 0)); + + if (vehicleInstance.carType == VehicleInstance.TRUCK) { + BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.4f, 0.8f, 1.0f)); + compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, 2f)); + + Geometry carCabin = new Geometry("car cabin", new Box(new Vector3f(0, 2, 2f), 1.4f, 0.8f, 1.0f)); + carCabin.setMaterial(matBody); + vehicleModel.attachChild(carCabin); + } else if (vehicleInstance.carType == VehicleInstance.SPORT) { + BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.2f, 0.6f, 2.0f)); + compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, -1f)); + + Geometry carCabin = new Geometry("car cabin", new Box(new Vector3f(0, 2, -1f), 1.2f, 0.6f, 2.0f)); + carCabin.setMaterial(matBody); + vehicleModel.attachChild(carCabin); + } + + VehicleControl vehicleControl = new VehicleControl(compoundShape, 500); + + //setting suspension values for wheels, this can be a bit tricky + //see also https://docs.google.com/Doc?docid=0AXVUZ5xw6XpKZGNuZG56a3FfMzU0Z2NyZnF4Zmo&hl=en + float stiffness = 30.0f;//200=f1 car + float compValue = .1f; //(should be lower than damp) + float dampValue = .2f; + vehicleControl.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); + vehicleControl.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); + vehicleControl.setSuspensionStiffness(stiffness); + vehicleControl.setMaxSuspensionForce(10000.0f); Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.2f, true); @@ -286,11 +233,6 @@ public class RoadTrip extends SimpleApplication implements ActionListener { vehicleModel.attachChild(node6); } - rootNode.attachChild(vehicleModel); - - getPhysicsSpace().add(vehicleControl); - vehicleControl.setPhysicsLocation(new Vector3f(5f, 30f, 5f)); - vehicleControl.getWheel(0).setFrictionSlip(0.8f); vehicleControl.getWheel(1).setFrictionSlip(0.8f); vehicleControl.getWheel(2).setFrictionSlip(0.6f); @@ -304,21 +246,22 @@ public class RoadTrip extends SimpleApplication implements ActionListener { VehicleNode vehicle = new VehicleNode("VehicleNode", vehicleInstance, vehicleControl, vehicleModel); + vehicle.attachChild(vehicleModel); vehicle.engineAudio = new AudioNode(assetManager, "Sounds/engine.ogg", false); vehicle.engineAudio.setPositional(true); vehicle.engineAudio.setLooping(true); vehicle.engineAudio.setReverbEnabled(true); - vehicle.engineAudio.setRefDistance(10); - vehicle.engineAudio.setMaxDistance(100000000); + vehicle.engineAudio.setRefDistance(5); + vehicle.engineAudio.setMaxDistance(1000000); vehicle.attachChild(vehicle.engineAudio); vehicle.wheelsAudio = new AudioNode(assetManager, "Sounds/wheels.ogg", false); vehicle.wheelsAudio.setPositional(true); vehicle.wheelsAudio.setLooping(true); //wheelsAudio.setReverbEnabled(true); - vehicle.wheelsAudio.setRefDistance(10); - vehicle.wheelsAudio.setMaxDistance(100000000); + vehicle.wheelsAudio.setRefDistance(1f); + vehicle.wheelsAudio.setMaxDistance(1000000f); vehicle.wheelsAudio.play(); vehicle.attachChild(vehicle.wheelsAudio); @@ -326,19 +269,22 @@ public class RoadTrip extends SimpleApplication implements ActionListener { vehicle.wheelSlipAudio.setPositional(true); vehicle.wheelSlipAudio.setLooping(true); //wheelsAudio.setReverbEnabled(true); - vehicle.wheelSlipAudio.setRefDistance(10); - vehicle.wheelSlipAudio.setMaxDistance(100000000); + vehicle.wheelSlipAudio.setRefDistance(5); + vehicle.wheelSlipAudio.setMaxDistance(1000000); vehicle.wheelSlipAudio.play(); vehicle.attachChild(vehicle.wheelSlipAudio); - vehicle.setLocalTranslation(new Vector3f(10f + (float)Math.random() * 20f, 30f, 12f + (float)Math.random() * 20f)); + vehicle.addControl(vehicleControl); + getPhysicsSpace().add(vehicleControl); + vehicleControl.setPhysicsLocation(new Vector3f(10f + (float)Math.random() * 20f, 30f, 12f + (float)Math.random() * 20f)); vehicles.add(vehicle); + rootNode.attachChild(vehicle); } @Override public void simpleUpdate(float tpf) { - Vector3f playerLocation = playerNode.getLocalTranslation(); + Vector3f playerLocation = playerNode.getWorldTranslation(); Vector3f newLocation = new Vector3f(playerLocation).add(new Vector3f(-1f, 1.5f, 2.4f).mult(20f)); cam.setLocation(new Vector3f(cam.getLocation()).interpolate(newLocation, Math.min(tpf, 1f))); cam.lookAt(playerLocation, Vector3f.UNIT_Y); @@ -358,11 +304,17 @@ public class RoadTrip extends SimpleApplication implements ActionListener { } vehicle.wheelsAudio.updateGeometricState(); - float wheelRot = Math.abs(vehicle.vehicleControl.getWheel(0).getDeltaRotation() + vehicle.vehicleControl.getWheel(1).getDeltaRotation()) / tpf / 40f; + float wheelRot = Math.abs(vehicle.vehicleControl.getWheel(0).getDeltaRotation() + vehicle.vehicleControl.getWheel(1).getDeltaRotation()) / tpf / 100f; // TODO: pitch //System.out.println("wheel rot: " + wheelRot); //wheelsAudio.setPitch(Math.max(0.5f, Math.min(wheelRot * 4f, 2.0f))); vehicle.wheelsAudio.setVolume(Math.max(0.0001f, Math.min(wheelRot, 1.0f)) - 0.0001f); + if ((vehicle.engineAudio.getStatus() == Status.Playing) && wheelRot < 10f) { + vehicle.engineAudio.stop(); + } + if ((vehicle.engineAudio.getStatus() != Status.Playing) && wheelRot > 10f) { + vehicle.engineAudio.play(); + } vehicle.wheelSlipAudio.updateGeometricState(); float slipAll = 0f; @@ -407,6 +359,28 @@ public class RoadTrip extends SimpleApplication implements ActionListener { } else { walkDir.z -= walkSpeed; } + } else if (binding.equals("Reset")) { + if (value) { + System.out.println("Reset - to car"); + Vector3f playerPos = playerNode.getWorldTranslation(); + for (VehicleNode vehicle : vehicles) { + Vector3f vehiclePos = vehicle.getWorldTranslation(); + float dist = playerPos.distance(vehiclePos); + System.out.println(" .. dist: " + dist); + if (dist < 5f) { + playerVehicleNode = vehicle; + playerNode.removeFromParent(); + playerNode.setLocalTranslation(0f, 0f, 0f); + playerNode.setLocalRotation(Quaternion.DIRECTION_Z); + playerNode.removeControl(playerPersonControl); + playerVehicleNode.attachChild(playerNode); + playerVehicleNode.vehicleInstance.accelerationValue = 0; + playerVehicleNode.vehicleInstance.steeringValue = 0; + walkDir = new Vector3f(); + break; + } + } + } } playerPersonControl.setWalkDirection(walkDir); playerPersonControl.setViewDirection(walkDir); @@ -468,12 +442,18 @@ public class RoadTrip extends SimpleApplication implements ActionListener { } } else if (binding.equals("Reset")) { if (value) { - System.out.println("Reset"); - playerVehicleNode.vehicleControl.setPhysicsLocation(Vector3f.ZERO); + System.out.println("Reset - from car"); + playerNode.removeFromParent(); + playerNode.addControl(playerPersonControl); + playerPersonControl.warp(playerVehicleNode.getLocalTranslation()); + rootNode.attachChild(playerNode); + playerVehicleNode = null; + walkDir = new Vector3f(); + /*playerVehicleNode.vehicleControl.setPhysicsLocation(Vector3f.ZERO); playerVehicleNode.vehicleControl.setPhysicsRotation(new Matrix3f()); playerVehicleNode.vehicleControl.setLinearVelocity(Vector3f.ZERO); playerVehicleNode.vehicleControl.setAngularVelocity(Vector3f.ZERO); - playerVehicleNode.vehicleControl.resetSuspension(); + playerVehicleNode.vehicleControl.resetSuspension();*/ } else { } } @@ -494,8 +474,9 @@ public class RoadTrip extends SimpleApplication implements ActionListener { personControl.warp(new Vector3f(10f + (float)Math.random() * 20f, 30f, 12f + (float)Math.random() * 20f));/**/ //personControl.setPhysicsLocation(new Vector3f(10f, 30f, 12f)); getPhysicsSpace().add(personControl); - getPhysicsSpace().addAll(person); + //getPhysicsSpace().addAll(person); rootNode.attachChild(person); + Vector3f dir = new Vector3f((float)Math.random() * 2f - 1f, 0f, (float)Math.random() * 2f - 1f); personControl.setViewDirection(dir); personControl.setWalkDirection(dir); @@ -515,3 +496,4 @@ public class RoadTrip extends SimpleApplication implements ActionListener { getPhysicsSpace().addAll(map); } } + diff --git a/src/roadtrip/VehicleInstance.java b/src/roadtrip/VehicleInstance.java new file mode 100644 index 0000000..00be99e --- /dev/null +++ b/src/roadtrip/VehicleInstance.java @@ -0,0 +1,65 @@ +/* + */ +package roadtrip; + +/** + * + * @author dejvino + */ +public class VehicleInstance +{ + final static int WEAK = 1; + final static int TRUCK = 2; + final static int SPORT = 3; + + static int getVehicleTypesCount() { + return SPORT; + } + + int carType; + float accelerationForce = 200.0f; + float brakeForce = 100.0f; + float steeringValue = 0; + float accelerationValue = 0; + float accelerationSmooth = 0; + + VehicleInstance(int carType, float accelerationForce, float brakeForce) + { + this.carType = carType; + this.accelerationForce = accelerationForce; + this.brakeForce = brakeForce; + } + + public static class WeakVehicle extends VehicleInstance + { + WeakVehicle() + { + super(WEAK, 200.0f, 100.0f); + } + } + + public static class TruckVehicle extends VehicleInstance + { + TruckVehicle() + { + super(TRUCK, 1400.0f, 200.0f); + } + } + + public static class SportVehicle extends VehicleInstance + { + SportVehicle() + { + super(SPORT, 20000.0f, 200.0f); + } + } + + static VehicleInstance createVehicle(int i) { + switch (i + 1) { + case WEAK: return new WeakVehicle(); + case TRUCK: return new TruckVehicle(); + case SPORT: return new SportVehicle(); + default: throw new RuntimeException("Unknown vehicle type " + i); + } + } +} \ No newline at end of file diff --git a/src/roadtrip/VehicleNode.java b/src/roadtrip/VehicleNode.java new file mode 100644 index 0000000..643acc9 --- /dev/null +++ b/src/roadtrip/VehicleNode.java @@ -0,0 +1,34 @@ +/* + */ +package roadtrip; + +import com.jme3.audio.AudioNode; +import com.jme3.bullet.control.VehicleControl; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +/** + * + * @author dejvino + */ +public class VehicleNode extends Node +{ + VehicleInstance vehicleInstance; + + VehicleControl vehicleControl; + + Spatial vehicleModel; + + AudioNode engineAudio; + AudioNode wheelsAudio; + AudioNode wheelSlipAudio; + + public VehicleNode(String name, VehicleInstance vehicleInstance, + VehicleControl vehicleControl, Spatial vehicleModel) + { + super(name); + this.vehicleInstance = vehicleInstance; + this.vehicleControl = vehicleControl; + this.vehicleModel = vehicleModel; + } +} \ No newline at end of file