@@ -1,7 +1,12 @@ | |||
# backups | |||
*.*~ | |||
# binary / temporary | |||
*.class | |||
# Mobile Tools for Java (J2ME) | |||
.mtj.tmp/ | |||
build/ | |||
dist/ | |||
nbproject/private/ | |||
# Package Files # | |||
*.jar | |||
@@ -1,2 +1,12 @@ | |||
# roadtrip | |||
Driving game | |||
# RoadTrip | |||
A game about a journey involving vehicles and obstacles. | |||
## Status | |||
### DONE | |||
* Physics-based vehicle | |||
* Hilly ground | |||
### TODO | |||
* Orbit camera | |||
* Rigid objects (fences, houses) | |||
* People |
@@ -0,0 +1,20 @@ | |||
Material MyMaterial : Common/MatDefs/Terrain/TerrainLighting.j3md { | |||
MaterialParameters { | |||
DiffuseMap_0_scale : 16.0625 | |||
WardIso : true | |||
DiffuseMap : Flip Repeat /Textures/dirt.jpg | |||
AlphaMap : /Textures/terrain-alpha/TestMap-terrain-TestMap-alphablend0.png | |||
Shininess : 0.01 | |||
} | |||
AdditionalRenderState { | |||
FaceCull Back | |||
Wireframe Off | |||
DepthWrite On | |||
PolyOffset 0.0 0.0 | |||
AlphaTestFalloff 0.0 | |||
Blend Off | |||
PointSprite Off | |||
ColorWrite On | |||
DepthTest On | |||
} | |||
} |
@@ -0,0 +1,3 @@ | |||
# | |||
#Thu Dec 29 22:27:37 CET 2016 | |||
ORIGINAL_PATH=TestMap.j3o |
@@ -0,0 +1,74 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- You may freely edit this file. See commented blocks below for --> | |||
<!-- some examples of how to customize the build. --> | |||
<!-- (If you delete it and reopen the project it will be recreated.) --> | |||
<!-- By default, only the Clean and Build commands use this build script. --> | |||
<!-- Commands such as Run, Debug, and Test only use this build script if --> | |||
<!-- the Compile on Save feature is turned off for the project. --> | |||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting --> | |||
<!-- in the project's Project Properties dialog box.--> | |||
<project name="RoadTrip" default="default" basedir="."> | |||
<description>Builds, tests, and runs the project RoadTrip.</description> | |||
<import file="nbproject/build-impl.xml"/> | |||
<!-- | |||
There exist several targets which are by default empty and which can be | |||
used for execution of your tasks. These targets are usually executed | |||
before and after some main targets. They are: | |||
-pre-init: called before initialization of project properties | |||
-post-init: called after initialization of project properties | |||
-pre-compile: called before javac compilation | |||
-post-compile: called after javac compilation | |||
-pre-compile-single: called before javac compilation of single file | |||
-post-compile-single: called after javac compilation of single file | |||
-pre-compile-test: called before javac compilation of JUnit tests | |||
-post-compile-test: called after javac compilation of JUnit tests | |||
-pre-compile-test-single: called before javac compilation of single JUnit test | |||
-post-compile-test-single: called after javac compilation of single JUunit test | |||
-pre-jar: called before JAR building | |||
-post-jar: called after JAR building | |||
-post-clean: called after cleaning build products | |||
(Targets beginning with '-' are not intended to be called on their own.) | |||
Example of inserting an obfuscator after compilation could look like this: | |||
<target name="-post-compile"> | |||
<obfuscate> | |||
<fileset dir="${build.classes.dir}"/> | |||
</obfuscate> | |||
</target> | |||
For list of available properties check the imported | |||
nbproject/build-impl.xml file. | |||
Another way to customize the build is by overriding existing main targets. | |||
The targets of interest are: | |||
-init-macrodef-javac: defines macro for javac compilation | |||
-init-macrodef-junit: defines macro for junit execution | |||
-init-macrodef-debug: defines macro for class debugging | |||
-init-macrodef-java: defines macro for class execution | |||
-do-jar-with-manifest: JAR building (if you are using a manifest) | |||
-do-jar-without-manifest: JAR building (if you are not using a manifest) | |||
run: execution of project | |||
-javadoc-build: Javadoc generation | |||
test-report: JUnit report generation | |||
An example of overriding the target for project execution could look like this: | |||
<target name="run" depends="RoadTrip-impl.jar"> | |||
<exec dir="bin" executable="launcher.exe"> | |||
<arg file="${dist.jar}"/> | |||
</exec> | |||
</target> | |||
Notice that the overridden target depends on the jar target and not only on | |||
the compile target as the regular run target does. Again, for a list of available | |||
properties which you can use, check the target you are overriding in the | |||
nbproject/build-impl.xml file. | |||
--> | |||
</project> |
@@ -0,0 +1,3 @@ | |||
Manifest-Version: 1.0 | |||
X-COMMENT: Main-Class will be added automatically by build | |||
@@ -0,0 +1,15 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!--assets-impl.xml v1.0--> | |||
<project name="assets-impl" basedir=".."> | |||
<target name="-init-assets"> | |||
<jar jarfile="${build.dir}/${assets.jar.name}" excludes="${assets.excludes}" basedir="${assets.folder.name}" compress="${assets.compress}"/> | |||
<property location="${assets.folder.name}" name="assets.dir.resolved"/> | |||
<property location="${build.dir}/${assets.jar.name}" name="assets.jar.resolved"/> | |||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/> | |||
<pathconvert property="run.classpath.without.build.classes.dir"> | |||
<path path="${run.classpath}"/> | |||
<map from="${build.classes.dir.resolved}" to=""/> | |||
<map from="${assets.dir.resolved}" to="${assets.jar.resolved}"/> | |||
</pathconvert> | |||
</target> | |||
</project> |
@@ -0,0 +1,8 @@ | |||
build.xml.data.CRC32=ffdc6a51 | |||
build.xml.script.CRC32=972047c8 | |||
build.xml.stylesheet.CRC32=28e38971@1.56.1.46 | |||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. | |||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. | |||
nbproject/build-impl.xml.data.CRC32=ffdc6a51 | |||
nbproject/build-impl.xml.script.CRC32=60ad5220 | |||
nbproject/build-impl.xml.stylesheet.CRC32=c6d2a60f@1.56.1.46 |
@@ -0,0 +1,89 @@ | |||
annotation.processing.enabled=true | |||
annotation.processing.enabled.in.editor=false | |||
annotation.processing.processors.list= | |||
annotation.processing.run.all.processors=true | |||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output | |||
application.title=RoadTrip | |||
application.vendor=dejvino | |||
assets.compress=true | |||
assets.excludes=**/*.j3odata,**/*.mesh,**/*.skeleton,**/*.mesh.xml,**/*.skeleton.xml,**/*.scene,**/*.material,**/*.obj,**/*.mtl,**/*.3ds,**/*.dae,**/*.blend,**/*.blend*[0-9] | |||
assets.folder.name=assets | |||
assets.jar.name=assets.jar | |||
build.classes.dir=${build.dir}/classes | |||
build.classes.excludes=**/*.java,**/*.form | |||
# This directory is removed when the project is cleaned: | |||
build.dir=build | |||
build.generated.dir=${build.dir}/generated | |||
build.generated.sources.dir=${build.dir}/generated-sources | |||
# Only compile against the classpath explicitly listed here: | |||
build.sysclasspath=ignore | |||
build.test.classes.dir=${build.dir}/test/classes | |||
build.test.results.dir=${build.dir}/test/results | |||
# Uncomment to specify the preferred debugger connection transport: | |||
#debug.transport=dt_socket | |||
debug.classpath=\ | |||
${run.classpath} | |||
debug.test.classpath=\ | |||
${run.test.classpath} | |||
# This directory is removed when the project is cleaned: | |||
dist.dir=dist | |||
dist.jar=${dist.dir}/RoadTrip.jar | |||
dist.javadoc.dir=${dist.dir}/javadoc | |||
endorsed.classpath= | |||
excludes= | |||
file.reference.RoadTrip-assets=assets | |||
includes=** | |||
jar.compress=false | |||
javac.classpath=\ | |||
${libs.jme3.classpath}:\ | |||
${libs.jme3-libraries-physics.classpath}:\ | |||
${libs.jme3-libraries-physics-native.classpath}:\ | |||
${libs.jme3-test-data.classpath} | |||
# Space-separated list of extra javac options | |||
javac.compilerargs= | |||
javac.deprecation=false | |||
javac.processorpath=\ | |||
${javac.classpath} | |||
javac.source=1.7 | |||
javac.target=1.7 | |||
javac.test.classpath=\ | |||
${javac.classpath}:\ | |||
${build.classes.dir} | |||
javac.test.processorpath=\ | |||
${javac.test.classpath} | |||
javadoc.additionalparam= | |||
javadoc.author=false | |||
javadoc.encoding=${source.encoding} | |||
javadoc.noindex=false | |||
javadoc.nonavbar=false | |||
javadoc.notree=false | |||
javadoc.private=false | |||
javadoc.splitindex=true | |||
javadoc.use=true | |||
javadoc.version=false | |||
javadoc.windowtitle= | |||
main.class=roadtrip.RoadTrip | |||
manifest.file=manifest.mf | |||
meta.inf.dir=${src.dir}/META-INF | |||
mkdist.disabled=false | |||
obfuscate.options=-keep public class * extends com.jme3.app.Application{public *;}\n-keep public class * extends com.jme3.system.JmeSystemDelegate{public *;}\n-keep public class * implements com.jme3.renderer.Renderer{public *;}\n-keep public class * implements com.jme3.asset.AssetLoader{public *;}\n-keep public class * implements com.jme3.asset.AssetLocator{public *;}\n-keep public class * implements de.lessvoid.nifty.screen.ScreenController{public *;}\n-dontwarn\n-dontnote\n | |||
platform.active=default_platform | |||
run.classpath=\ | |||
${javac.classpath}:\ | |||
${build.classes.dir}:\ | |||
${libs.jme3.classpath}:\ | |||
${libs.jme3-libraries.classpath}:\ | |||
${libs.jme3-test-data.classpath}:\ | |||
${libs.jme3-libraries-physics.classpath}:\ | |||
${libs.jme3-libraries-physics-native.classpath}:\ | |||
${file.reference.RoadTrip-assets} | |||
# Space-separated list of JVM arguments used when running the project. | |||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. | |||
# To set system properties for unit tests define test-sys-prop.name=value: | |||
run.jvmargs= | |||
run.test.classpath=\ | |||
${javac.test.classpath}:\ | |||
${build.test.classes.dir} | |||
source.encoding=UTF-8 | |||
src.dir=src | |||
test.src.dir=test |
@@ -0,0 +1,20 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://www.netbeans.org/ns/project/1"> | |||
<type>org.netbeans.modules.java.j2seproject</type> | |||
<configuration> | |||
<buildExtensions xmlns="http://www.netbeans.org/ns/ant-build-extender/1"> | |||
<extension file="assets-impl.xml" id="assets"> | |||
<dependency dependsOn="-init-assets" target="-do-init"/> | |||
</extension> | |||
</buildExtensions> | |||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3"> | |||
<name>RoadTrip</name> | |||
<source-roots> | |||
<root id="src.dir"/> | |||
</source-roots> | |||
<test-roots> | |||
<root id="test.src.dir"/> | |||
</test-roots> | |||
</data> | |||
</configuration> | |||
</project> |
@@ -0,0 +1,242 @@ | |||
/* | |||
* Copyright (c) 2009-2012 jMonkeyEngine | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
* modification, are permitted provided that the following conditions are | |||
* met: | |||
* | |||
* * Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* | |||
* * Redistributions in binary form must reproduce the above copyright | |||
* notice, this list of conditions and the following disclaimer in the | |||
* documentation and/or other materials provided with the distribution. | |||
* | |||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors | |||
* may be used to endorse or promote products derived from this software | |||
* without specific prior written permission. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
package roadtrip; | |||
import com.jme3.app.Application; | |||
import com.jme3.asset.AssetManager; | |||
import com.jme3.asset.TextureKey; | |||
import com.jme3.bullet.PhysicsSpace; | |||
import com.jme3.bullet.collision.shapes.CollisionShape; | |||
import com.jme3.bullet.collision.shapes.MeshCollisionShape; | |||
import com.jme3.bullet.control.RigidBodyControl; | |||
import com.jme3.input.MouseInput; | |||
import com.jme3.input.controls.ActionListener; | |||
import com.jme3.input.controls.MouseButtonTrigger; | |||
import com.jme3.light.AmbientLight; | |||
import com.jme3.material.Material; | |||
import com.jme3.math.ColorRGBA; | |||
import com.jme3.renderer.queue.RenderQueue.ShadowMode; | |||
import com.jme3.scene.Geometry; | |||
import com.jme3.scene.Node; | |||
import com.jme3.scene.shape.Box; | |||
import com.jme3.scene.shape.Sphere; | |||
import com.jme3.scene.shape.Sphere.TextureMode; | |||
import com.jme3.texture.Texture; | |||
/** | |||
* | |||
* @author normenhansen | |||
*/ | |||
public class PhysicsTestHelper { | |||
/** | |||
* creates a simple physics test world with a floor, an obstacle and some test boxes | |||
* @param rootNode | |||
* @param assetManager | |||
* @param space | |||
*/ | |||
public static void createPhysicsTestWorld(Node rootNode, AssetManager assetManager, PhysicsSpace space) { | |||
AmbientLight light = new AmbientLight(); | |||
light.setColor(ColorRGBA.LightGray); | |||
rootNode.addLight(light); | |||
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | |||
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); | |||
Box floorBox = new Box(140, 0.25f, 140); | |||
Geometry floorGeometry = new Geometry("Floor", floorBox); | |||
floorGeometry.setMaterial(material); | |||
floorGeometry.setLocalTranslation(0, -5, 0); | |||
// Plane plane = new Plane(); | |||
// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y); | |||
// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0)); | |||
floorGeometry.addControl(new RigidBodyControl(0)); | |||
rootNode.attachChild(floorGeometry); | |||
space.add(floorGeometry); | |||
//movable boxes | |||
for (int i = 0; i < 12; i++) { | |||
Box box = new Box(0.25f, 0.25f, 0.25f); | |||
Geometry boxGeometry = new Geometry("Box", box); | |||
boxGeometry.setMaterial(material); | |||
boxGeometry.setLocalTranslation(i, 5, -3); | |||
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh | |||
boxGeometry.addControl(new RigidBodyControl(2)); | |||
rootNode.attachChild(boxGeometry); | |||
space.add(boxGeometry); | |||
} | |||
//immovable sphere with mesh collision shape | |||
Sphere sphere = new Sphere(8, 8, 1); | |||
Geometry sphereGeometry = new Geometry("Sphere", sphere); | |||
sphereGeometry.setMaterial(material); | |||
sphereGeometry.setLocalTranslation(4, -4, 2); | |||
sphereGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(sphere), 0)); | |||
rootNode.attachChild(sphereGeometry); | |||
space.add(sphereGeometry); | |||
} | |||
public static void createPhysicsTestWorldSoccer(Node rootNode, AssetManager assetManager, PhysicsSpace space) { | |||
AmbientLight light = new AmbientLight(); | |||
light.setColor(ColorRGBA.LightGray); | |||
rootNode.addLight(light); | |||
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | |||
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); | |||
Box floorBox = new Box(20, 0.25f, 20); | |||
Geometry floorGeometry = new Geometry("Floor", floorBox); | |||
floorGeometry.setMaterial(material); | |||
floorGeometry.setLocalTranslation(0, -0.25f, 0); | |||
// Plane plane = new Plane(); | |||
// plane.setOriginNormal(new Vector3f(0, 0.25f, 0), Vector3f.UNIT_Y); | |||
// floorGeometry.addControl(new RigidBodyControl(new PlaneCollisionShape(plane), 0)); | |||
floorGeometry.addControl(new RigidBodyControl(0)); | |||
rootNode.attachChild(floorGeometry); | |||
space.add(floorGeometry); | |||
//movable spheres | |||
for (int i = 0; i < 5; i++) { | |||
Sphere sphere = new Sphere(16, 16, .5f); | |||
Geometry ballGeometry = new Geometry("Soccer ball", sphere); | |||
ballGeometry.setMaterial(material); | |||
ballGeometry.setLocalTranslation(i, 2, -3); | |||
//RigidBodyControl automatically uses Sphere collision shapes when attached to single geometry with sphere mesh | |||
ballGeometry.addControl(new RigidBodyControl(.001f)); | |||
ballGeometry.getControl(RigidBodyControl.class).setRestitution(1); | |||
rootNode.attachChild(ballGeometry); | |||
space.add(ballGeometry); | |||
} | |||
{ | |||
//immovable Box with mesh collision shape | |||
Box box = new Box(1, 1, 1); | |||
Geometry boxGeometry = new Geometry("Box", box); | |||
boxGeometry.setMaterial(material); | |||
boxGeometry.setLocalTranslation(4, 1, 2); | |||
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0)); | |||
rootNode.attachChild(boxGeometry); | |||
space.add(boxGeometry); | |||
} | |||
{ | |||
//immovable Box with mesh collision shape | |||
Box box = new Box(1, 1, 1); | |||
Geometry boxGeometry = new Geometry("Box", box); | |||
boxGeometry.setMaterial(material); | |||
boxGeometry.setLocalTranslation(4, 3, 4); | |||
boxGeometry.addControl(new RigidBodyControl(new MeshCollisionShape(box), 0)); | |||
rootNode.attachChild(boxGeometry); | |||
space.add(boxGeometry); | |||
} | |||
} | |||
/** | |||
* creates a box geometry with a RigidBodyControl | |||
* @param assetManager | |||
* @return | |||
*/ | |||
public static Geometry createPhysicsTestBox(AssetManager assetManager) { | |||
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | |||
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); | |||
Box box = new Box(0.25f, 0.25f, 0.25f); | |||
Geometry boxGeometry = new Geometry("Box", box); | |||
boxGeometry.setMaterial(material); | |||
//RigidBodyControl automatically uses box collision shapes when attached to single geometry with box mesh | |||
boxGeometry.addControl(new RigidBodyControl(2)); | |||
return boxGeometry; | |||
} | |||
/** | |||
* creates a sphere geometry with a RigidBodyControl | |||
* @param assetManager | |||
* @return | |||
*/ | |||
public static Geometry createPhysicsTestSphere(AssetManager assetManager) { | |||
Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | |||
material.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg")); | |||
Sphere sphere = new Sphere(8, 8, 0.25f); | |||
Geometry boxGeometry = new Geometry("Sphere", sphere); | |||
boxGeometry.setMaterial(material); | |||
//RigidBodyControl automatically uses sphere collision shapes when attached to single geometry with sphere mesh | |||
boxGeometry.addControl(new RigidBodyControl(2)); | |||
return boxGeometry; | |||
} | |||
/** | |||
* creates an empty node with a RigidBodyControl | |||
* @param manager | |||
* @param shape | |||
* @param mass | |||
* @return | |||
*/ | |||
public static Node createPhysicsTestNode(AssetManager manager, CollisionShape shape, float mass) { | |||
Node node = new Node("PhysicsNode"); | |||
RigidBodyControl control = new RigidBodyControl(shape, mass); | |||
node.addControl(control); | |||
return node; | |||
} | |||
/** | |||
* creates the necessary inputlistener and action to shoot balls from teh camera | |||
* @param app | |||
* @param rootNode | |||
* @param space | |||
*/ | |||
public static void createBallShooter(final Application app, final Node rootNode, final PhysicsSpace space) { | |||
ActionListener actionListener = new ActionListener() { | |||
public void onAction(String name, boolean keyPressed, float tpf) { | |||
Sphere bullet = new Sphere(32, 32, 0.4f, true, false); | |||
bullet.setTextureMode(TextureMode.Projected); | |||
Material mat2 = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); | |||
TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG"); | |||
key2.setGenerateMips(true); | |||
Texture tex2 = app.getAssetManager().loadTexture(key2); | |||
mat2.setTexture("ColorMap", tex2); | |||
if (name.equals("shoot") && !keyPressed) { | |||
Geometry bulletg = new Geometry("bullet", bullet); | |||
bulletg.setMaterial(mat2); | |||
bulletg.setShadowMode(ShadowMode.CastAndReceive); | |||
bulletg.setLocalTranslation(app.getCamera().getLocation()); | |||
RigidBodyControl bulletControl = new RigidBodyControl(10); | |||
bulletg.addControl(bulletControl); | |||
bulletControl.setLinearVelocity(app.getCamera().getDirection().mult(25)); | |||
bulletg.addControl(bulletControl); | |||
rootNode.attachChild(bulletg); | |||
space.add(bulletControl); | |||
} | |||
} | |||
}; | |||
app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT)); | |||
app.getInputManager().addListener(actionListener, "shoot"); | |||
} | |||
} |
@@ -0,0 +1,272 @@ | |||
package roadtrip; | |||
import com.jme3.app.SimpleApplication; | |||
import com.jme3.bullet.BulletAppState; | |||
import com.jme3.bullet.PhysicsSpace; | |||
import com.jme3.bullet.collision.shapes.BoxCollisionShape; | |||
import com.jme3.bullet.collision.shapes.CompoundCollisionShape; | |||
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.material.Material; | |||
import com.jme3.math.ColorRGBA; | |||
import com.jme3.math.FastMath; | |||
import com.jme3.math.Matrix3f; | |||
import com.jme3.math.Vector3f; | |||
import com.jme3.scene.Geometry; | |||
import com.jme3.scene.Node; | |||
import com.jme3.scene.Spatial; | |||
import com.jme3.scene.shape.Cylinder; | |||
/** | |||
* | |||
* @author dejvino | |||
*/ | |||
public class RoadTrip extends SimpleApplication implements ActionListener { | |||
final int WEAK = 1; | |||
final int TRUCK = 2; | |||
final int SPORT = 3; | |||
final int carType = SPORT; | |||
private BulletAppState bulletAppState; | |||
private VehicleControl vehicle; | |||
private float accelerationForce = 200.0f; | |||
private float brakeForce = 100.0f; | |||
private float steeringValue = 0; | |||
private float accelerationValue = 0; | |||
private Vector3f jumpForce = new Vector3f(0, 3000, 0); | |||
public static void main(String[] args) { | |||
RoadTrip app = new RoadTrip(); | |||
app.start(); | |||
} | |||
Spatial map; | |||
Spatial car; | |||
@Override | |||
public void simpleInitApp() { | |||
bulletAppState = new BulletAppState(); | |||
stateManager.attach(bulletAppState); | |||
bulletAppState.getPhysicsSpace().enableDebug(assetManager); | |||
PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace()); | |||
setupKeys(); | |||
buildPlayer(); | |||
map = assetManager.loadModel("Scenes/TestMap.j3o"); | |||
rootNode.attachChild(map); | |||
getPhysicsSpace().addAll(map); | |||
vehicle.setPhysicsLocation(new Vector3f(5f, 30f, 5f)); | |||
} | |||
private PhysicsSpace getPhysicsSpace(){ | |||
return bulletAppState.getPhysicsSpace(); | |||
} | |||
private void setupKeys() { | |||
inputManager.addMapping("Lefts", new KeyTrigger(KeyInput.KEY_H)); | |||
inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_K)); | |||
inputManager.addMapping("Ups", new KeyTrigger(KeyInput.KEY_U)); | |||
inputManager.addMapping("Downs", new KeyTrigger(KeyInput.KEY_J)); | |||
inputManager.addMapping("Space", new KeyTrigger(KeyInput.KEY_SPACE)); | |||
inputManager.addMapping("Reset", new KeyTrigger(KeyInput.KEY_RETURN)); | |||
inputManager.addListener(this, "Lefts"); | |||
inputManager.addListener(this, "Rights"); | |||
inputManager.addListener(this, "Ups"); | |||
inputManager.addListener(this, "Downs"); | |||
inputManager.addListener(this, "Space"); | |||
inputManager.addListener(this, "Reset"); | |||
} | |||
private void buildPlayer() { | |||
Material mat = new Material(getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); | |||
mat.getAdditionalRenderState().setWireframe(true); | |||
mat.setColor("Color", ColorRGBA.Red); | |||
//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 (carType == TRUCK) { | |||
BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.4f, 0.8f, 1.0f)); | |||
compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, 2f)); | |||
} else if (carType == SPORT) { | |||
BoxCollisionShape boxCabin = new BoxCollisionShape(new Vector3f(1.2f, 0.6f, 2.0f)); | |||
compoundShape.addChildShape(boxCabin, new Vector3f(0, 2, -1f)); | |||
} | |||
//create vehicle node | |||
Node vehicleNode=new Node("vehicleNode"); | |||
vehicle = new VehicleControl(compoundShape, 500); | |||
vehicleNode.addControl(vehicle); | |||
//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; | |||
vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness)); | |||
vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness)); | |||
vehicle.setSuspensionStiffness(stiffness); | |||
vehicle.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 | |||
float radius = 1.0f; | |||
float restLength = 0.3f; | |||
float yOff = 0.5f; | |||
float xOff = 1.6f; | |||
float zOff = 2f; | |||
Cylinder wheelMesh = new Cylinder(16, 16, radius, radius * 0.2f, true); | |||
Node node1 = new Node("wheel 1 node"); | |||
Geometry wheels1 = new Geometry("wheel 1", wheelMesh); | |||
node1.attachChild(wheels1); | |||
wheels1.rotate(0, FastMath.HALF_PI, 0); | |||
wheels1.setMaterial(mat); | |||
vehicle.addWheel(node1, new Vector3f(-xOff, yOff, zOff), | |||
wheelDirection, wheelAxle, restLength, radius, true); | |||
Node node2 = new Node("wheel 2 node"); | |||
Geometry wheels2 = new Geometry("wheel 2", wheelMesh); | |||
node2.attachChild(wheels2); | |||
wheels2.rotate(0, FastMath.HALF_PI, 0); | |||
wheels2.setMaterial(mat); | |||
vehicle.addWheel(node2, new Vector3f(xOff, yOff, zOff), | |||
wheelDirection, wheelAxle, restLength, radius, true); | |||
Node node3 = new Node("wheel 3 node"); | |||
Geometry wheels3 = new Geometry("wheel 3", wheelMesh); | |||
node3.attachChild(wheels3); | |||
wheels3.rotate(0, FastMath.HALF_PI, 0); | |||
wheels3.setMaterial(mat); | |||
vehicle.addWheel(node3, new Vector3f(-xOff, yOff, -zOff), | |||
wheelDirection, wheelAxle, restLength, radius, false); | |||
Node node4 = new Node("wheel 4 node"); | |||
Geometry wheels4 = new Geometry("wheel 4", wheelMesh); | |||
node4.attachChild(wheels4); | |||
wheels4.rotate(0, FastMath.HALF_PI, 0); | |||
wheels4.setMaterial(mat); | |||
vehicle.addWheel(node4, new Vector3f(xOff, yOff, -zOff), | |||
wheelDirection, wheelAxle, restLength, radius, false); | |||
vehicleNode.attachChild(node1); | |||
vehicleNode.attachChild(node2); | |||
vehicleNode.attachChild(node3); | |||
vehicleNode.attachChild(node4); | |||
if (carType == TRUCK) { | |||
Node node5 = new Node("wheel 5 node"); | |||
Geometry wheels5 = new Geometry("wheel 5", wheelMesh); | |||
node5.attachChild(wheels5); | |||
wheels5.rotate(0, FastMath.HALF_PI, 0); | |||
wheels5.setMaterial(mat); | |||
vehicle.addWheel(node5, new Vector3f(-xOff, yOff, 2.1f* -zOff), | |||
wheelDirection, wheelAxle, restLength, radius, false); | |||
Node node6 = new Node("wheel 6 node"); | |||
Geometry wheels6 = new Geometry("wheel 6", wheelMesh); | |||
node6.attachChild(wheels6); | |||
wheels6.rotate(0, FastMath.HALF_PI, 0); | |||
wheels6.setMaterial(mat); | |||
vehicle.addWheel(node6, new Vector3f(xOff, yOff, 2.1f* -zOff), | |||
wheelDirection, wheelAxle, restLength, radius, false); | |||
vehicleNode.attachChild(node5); | |||
vehicleNode.attachChild(node6); | |||
} | |||
rootNode.attachChild(vehicleNode); | |||
getPhysicsSpace().add(vehicle); | |||
vehicle.setPhysicsLocation(new Vector3f(5f, 30f, 5f)); | |||
vehicle.getWheel(0).setFrictionSlip(0.8f); | |||
vehicle.getWheel(1).setFrictionSlip(0.8f); | |||
vehicle.getWheel(2).setFrictionSlip(0.6f); | |||
vehicle.getWheel(3).setFrictionSlip(0.6f); | |||
if (carType == TRUCK) { | |||
vehicle.getWheel(4).setFrictionSlip(0.6f); | |||
vehicle.getWheel(5).setFrictionSlip(0.6f); | |||
accelerationForce = 1400f; | |||
brakeForce = 200f; | |||
} else if (carType == SPORT) { | |||
accelerationForce = 20000f; | |||
brakeForce = 200f; | |||
} | |||
} | |||
@Override | |||
public void simpleUpdate(float tpf) { | |||
cam.setLocation(new Vector3f(-10f, 35f, -10f)); | |||
cam.lookAt(vehicle.getPhysicsLocation(), Vector3f.UNIT_Y); | |||
} | |||
public void onAction(String binding, boolean value, float tpf) { | |||
float steerMax = 0.5f; | |||
if (carType == TRUCK) { | |||
steerMax = 0.7f; | |||
} | |||
if (binding.equals("Lefts")) { | |||
if (value) { | |||
steeringValue += steerMax; | |||
} else { | |||
steeringValue += -steerMax; | |||
} | |||
vehicle.steer(steeringValue); | |||
} else if (binding.equals("Rights")) { | |||
if (value) { | |||
steeringValue += -steerMax; | |||
} else { | |||
steeringValue += steerMax; | |||
} | |||
vehicle.steer(steeringValue); | |||
} else if (binding.equals("Ups")) { | |||
if (value) { | |||
accelerationValue += accelerationForce; | |||
} else { | |||
accelerationValue -= accelerationForce; | |||
} | |||
vehicle.accelerate(2, accelerationValue); | |||
vehicle.accelerate(3, accelerationValue); | |||
if (carType == TRUCK) { | |||
vehicle.accelerate(4, accelerationValue); | |||
vehicle.accelerate(5, accelerationValue); | |||
} | |||
} else if (binding.equals("Downs")) { | |||
float b; | |||
if (value) { | |||
b = brakeForce; | |||
} else { | |||
b = 0f; | |||
} | |||
vehicle.brake(0, b); | |||
vehicle.brake(1, b); | |||
} else if (binding.equals("Space")) { | |||
if (value) { | |||
vehicle.applyImpulse(jumpForce, Vector3f.ZERO); | |||
} | |||
} else if (binding.equals("Reset")) { | |||
if (value) { | |||
System.out.println("Reset"); | |||
vehicle.setPhysicsLocation(Vector3f.ZERO); | |||
vehicle.setPhysicsRotation(new Matrix3f()); | |||
vehicle.setLinearVelocity(Vector3f.ZERO); | |||
vehicle.setAngularVelocity(Vector3f.ZERO); | |||
vehicle.resetSuspension(); | |||
} else { | |||
} | |||
} | |||
} | |||
} |