Implement PlayerShootControl, PlayerMouseControl and WeaponProjectileControl

This commit is contained in:
Chris@Chris-HP 2013-05-17 09:33:08 +02:00
parent 33c425c368
commit 28675bac6d
12 changed files with 1963 additions and 0 deletions

1
ShootingTest/MANIFEST.MF Normal file
View File

@ -0,0 +1 @@
X-Comment: Created with jMonkeyPlatform

76
ShootingTest/build.xml Normal file
View File

@ -0,0 +1,76 @@
<?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="BasicGameTemplate" default="default" basedir=".">
<description>Builds, tests, and runs the project BasicGameTemplate.</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="BasicGameTemplate-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>

View File

@ -0,0 +1,22 @@
<jnlp spec="1.0+" codebase="${jnlp.codebase}" href="launch.jnlp">
<information>
<title>${APPLICATION.TITLE}</title>
<vendor>${APPLICATION.VENDOR}</vendor>
<homepage href="${APPLICATION.HOMEPAGE}"/>
<description>${APPLICATION.DESC}</description>
<description kind="short">${APPLICATION.DESC.SHORT}</description>
<!--${JNLP.ICONS}-->
<!--${JNLP.OFFLINE.ALLOWED}-->
</information>
<!--${JNLP.SECURITY}-->
<resources>
<!--${JNLP.RESOURCES.RUNTIME}-->
<!--${JNLP.RESOURCES.MAIN.JAR}-->
<!--${JNLP.RESOURCES.JARS}-->
<jar href='lib/assets.jar'/>
<!--${JNLP.RESOURCES.EXTENSIONS}-->
</resources>
<application-desc main-class="${jnlp.main.class}">
<!--${JNLP.APPLICATION.ARGS}-->
</application-desc>
</jnlp>

View File

@ -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>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
build.xml.data.CRC32=94bf7c61
build.xml.script.CRC32=79a29eb7
build.xml.stylesheet.CRC32=958a1d3e@1.32.1.45
# 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=99ad4fd9
nbproject/build-impl.xml.script.CRC32=ed28b3b3
nbproject/build-impl.xml.stylesheet.CRC32=6ddba6b6@1.53.1.46

View File

@ -0,0 +1,76 @@
application.title=MyGame
application.vendor=MyCompany
assets.jar.name=assets.jar
assets.excludes=**/*.j3odata,**/*.mesh\.xml,**/*.skeleton\.xml,**/*.scene,**/*.material,**/*.obj,**/*.mtl,**/*.blend
assets.folder.name=assets
assets.compress=true
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
compile.on.save=true
# 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}/${application.title}.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=false
javac.classpath=\
${libs.jme3.classpath}:\
${libs.jme3-libraries.classpath}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.source=1.5
javac.target=1.5
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
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=
jaxbwiz.endorsed.dirs="${netbeans.home}/../ide12/modules/ext/jaxb/api"
jnlp.codebase.type=local
jnlp.descriptor=application
jnlp.enabled=false
jnlp.offline-allowed=false
jnlp.signed=false
main.class=mygame.Main
meta.inf.dir=${src.dir}/META-INF
manifest.file=MANIFEST.MF
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}:\
${assets.folder.name}
# 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
# or test-sys-prop.name=value to set system properties for unit tests):
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src

View File

@ -0,0 +1,18 @@
<?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>ShootingTest</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots/>
</data>
</configuration>
</project>

View File

@ -0,0 +1,62 @@
package mygame;
import com.jme3.app.DebugKeysAppState;
import com.jme3.app.SimpleApplication;
import com.jme3.app.StatsAppState;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
/**
* @author Snowsun
*/
public class Main extends SimpleApplication {
private Spatial player;
private PlayerMouseControl playerMouseControl;
private PlayerShootControl playerShootControl;
private WeaponProjectileControl weaponProjectileControl;
public Main() {
super(new StatsAppState(), new DebugKeysAppState());
}
public static void main(String[] args) {
Main app = new Main();
app.start();
}
@Override
public void simpleInitApp() {
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
player = new Geometry("Player",b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
player.setMaterial(mat);
inputManager.setCursorVisible(false);
playerMouseControl = new PlayerMouseControl(inputManager,cam);
player.addControl(playerMouseControl);
playerMouseControl.setSpeed(2);
playerShootControl = new PlayerShootControl(inputManager);
player.addControl(playerShootControl);
weaponProjectileControl = new WeaponProjectileControl(assetManager, rootNode, inputManager);
player.addControl(weaponProjectileControl);
rootNode.attachChild(player);
}
@Override
public void simpleUpdate(float tpf) {
}
@Override
public void simpleRender(RenderManager rm) {
}
}

View File

@ -0,0 +1,120 @@
package mygame;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
/**
*
* @author Snowsun
*/
public class PlayerMouseControl extends AbstractControl implements AnalogListener {
private float speed;
private InputManager inputManager;
private Camera cam;
private Vector3f initialUpVec;
public PlayerMouseControl(InputManager inputManager, Camera cam) {
this.inputManager = inputManager;
this.cam = cam;
initMappings();
}
@Override
public void setSpatial(Spatial spatial) {
super.setSpatial(spatial);
initialUpVec = spatial.getLocalRotation().getRotationColumn(1).clone();
}
@Override
protected void controlUpdate(float tpf) {
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
public Control cloneForSpatial(Spatial spatial) {
PlayerMouseControl control = new PlayerMouseControl(inputManager,cam);
spatial.addControl(control);
return control;
}
public void setSpeed(float speed) {
this.speed = speed;
}
public float getSpeed() {
return speed;
}
public void onAnalog(String name, float value, float tpf) {
if (name.equals("PLAYER_Left")) {
rotateCamera(value, initialUpVec);
} else if (name.equals("PLAYER_Right")) {
rotateCamera(-value, initialUpVec);
} else if (name.equals("PLAYER_Up")) {
rotateCamera(-value, spatial.getLocalRotation().getRotationColumn(0));
} else if (name.equals("PLAYER_Down")) {
rotateCamera(value, spatial.getLocalRotation().getRotationColumn(0));
}
}
private void initMappings() {
inputManager.addMapping("PLAYER_Left", new MouseAxisTrigger(MouseInput.AXIS_X, true),
new KeyTrigger(KeyInput.KEY_LEFT));
inputManager.addMapping("PLAYER_Right", new MouseAxisTrigger(MouseInput.AXIS_X, false),
new KeyTrigger(KeyInput.KEY_RIGHT));
inputManager.addMapping("PLAYER_Up", new MouseAxisTrigger(MouseInput.AXIS_Y, false),
new KeyTrigger(KeyInput.KEY_UP));
inputManager.addMapping("PLAYER_Down", new MouseAxisTrigger(MouseInput.AXIS_Y, true),
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addListener(this, new String[]{"PLAYER_Left","PLAYER_Right","PLAYER_Up","PLAYER_Down"});
}
private void rotateCamera(float value, Vector3f axis) {
Matrix3f mat = new Matrix3f();
mat.fromAngleNormalAxis(speed * value, axis);
Vector3f up = spatial.getLocalRotation().getRotationColumn(1);
Vector3f left = spatial.getLocalRotation().getRotationColumn(0);
Vector3f dir = spatial.getLocalRotation().getRotationColumn(2);
mat.mult(up, up);
mat.mult(left, left);
mat.mult(dir, dir);
Quaternion q = new Quaternion();
q.fromAxes(left, up, dir);
q.normalizeLocal();
float[] angles = q.toAngles(null);
if (angles[0] < -1.4f) {
angles[0] = -1.4f;
spatial.setLocalRotation(new Quaternion(angles));
} else if (angles[0] > 1.4f) {
angles[0] = 1.4f;
spatial.setLocalRotation(new Quaternion(angles));
} else {
spatial.setLocalRotation(q);
}
}
}

View File

@ -0,0 +1,74 @@
package mygame;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
/**
*
* @author Snowsun
*/
public class PlayerShootControl extends AbstractControl implements ActionListener {
private InputManager inputManager;
private final float maxTimeToOverheat = 3f;
private float timeToOverheat = maxTimeToOverheat;
private boolean isShooting = false;
public PlayerShootControl(InputManager inputmanager) {
this.inputManager = inputmanager;
initMappings();
}
@Override
protected void controlUpdate(float tpf) {
if (isShooting) {
timeToOverheat -= tpf;
if (timeToOverheat <= 0) {
isShooting = false;
}
}
}
@Override
public void setSpatial(Spatial spatial) {
super.setSpatial(spatial);
}
public boolean getIsShooting() {
return this.isShooting;
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
public Control cloneForSpatial(Spatial spatial) {
PlayerShootControl control = new PlayerShootControl(inputManager);
spatial.addControl(control);
return control;
}
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("PLAYER_Mouse_Left_Click") && isPressed) {
isShooting = true;
} else if (name.equals("PLAYER_Mouse_Left_Click") && !isPressed) {
isShooting = false;
timeToOverheat = maxTimeToOverheat;
}
}
private void initMappings() {
inputManager.addMapping("PLAYER_Mouse_Left_Click", new MouseButtonTrigger(MouseInput.BUTTON_LEFT),
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addListener(this, new String[]{"PLAYER_Mouse_Left_Click"});
}
}

View File

@ -0,0 +1,109 @@
package mygame;
import com.jme3.asset.AssetManager;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.scene.shape.Box;
/**
*
* @author Snowsun
*/
public class WeaponProjectileControl extends AbstractControl implements ActionListener{
private Spatial projectile;
private AssetManager assetManager;
private Node rootNode;
private Vector3f location;
private InputManager inputManager;
public WeaponProjectileControl(AssetManager assetManager, Node rootNode, InputManager inputManager) {
this.assetManager = assetManager;
this.rootNode = rootNode;
this.inputManager = inputManager;
initMappings();
}
@Override
public void setSpatial(Spatial spatial) {
super.setSpatial(spatial);
location = spatial.getLocalTranslation();
initProjectile();
}
@Override
protected void controlUpdate(float tpf) {
if(spatial.getControl(PlayerShootControl.class).getIsShooting()) {
shoot();
} else {
rootNode.detachChild(projectile);
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
public Control cloneForSpatial(Spatial spatial) {
WeaponProjectileControl control = new WeaponProjectileControl(assetManager, rootNode, inputManager);
spatial.addControl(control);
return control;
}
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("PLAYER_Mouse_Left_Click") && isPressed) {
rootNode.attachChild(projectile);
} else if (name.equals("PLAYER_Mouse_Left_Click") && !isPressed) {
rootNode.detachChild(projectile);
}
}
private void initMappings() {
inputManager.addMapping("PLAYER_Mouse_Left_Click", new MouseButtonTrigger(MouseInput.BUTTON_LEFT),
new KeyTrigger(KeyInput.KEY_DOWN));
inputManager.addListener(this, new String[]{"PLAYER_Mouse_Left_Click"});
}
private void initProjectile() {
Box box = new Box(Vector3f.ZERO, 1, 1, 2);
projectile = new Geometry("Projectile", box);
projectile.setLocalTranslation(spatial.getLocalTranslation());
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Red);
projectile.setMaterial(mat);
}
/*
* Fires a projectile
*/
private void shoot() {
projectile.setLocalTranslation(location.add(0, 0, -4));
Vector3f vectorDifference = new Vector3f(spatial.getLocalTranslation().subtract(spatial.getWorldTranslation()));
projectile.setLocalTranslation(vectorDifference.addLocal(spatial.getLocalTranslation()));
Quaternion worldDiff = new Quaternion(spatial.getLocalRotation().subtract(spatial.getWorldRotation()));
projectile.setLocalRotation(worldDiff.addLocal(spatial.getLocalRotation()));
projectile.move(spatial.getLocalRotation().getRotationColumn(2).mult(-3f));
projectile.move(spatial.getLocalRotation().getRotationColumn(1).mult(0f));
projectile.move(spatial.getLocalRotation().getRotationColumn(0).mult(0));
projectile.rotate(0f, FastMath.PI, 0);
}
}