package javara;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javara.world.physical.Hector;
import com.jme3.app.SimpleApplication;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.font.BitmapText;
import com.jme3.input.ChaseCamera;
import com.jme3.input.InputManager;
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.input.controls.MouseAxisTrigger;
import com.jme3.light.DirectionalLight;
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.scene.CameraNode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.CameraControl.ControlDirection;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Line;
import com.jme3.texture.Image;
import com.jme3.texture.Texture2D;
import com.jme3.texture.plugins.AWTLoader;
import com.jme3.util.SkyFactory;
public class HectorTest extends SimpleApplication {
private ChaseCamera chaseCam;
private static Vector3f xPoint = new Vector3f(3.0f, 0.0f, 0.0f);
private static Vector3f yPoint = new Vector3f(0.0f, 3.0f, 0.0f);
private static Vector3f zPoint = new Vector3f(0.0f, 0.0f, 3.0f);
private static Geometry xAxis = new Geometry("xAxis", new Line(xPoint.negate(), xPoint));
private static Geometry yAxis = new Geometry("yAxis", new Line(yPoint.negate(), yPoint));
private static Geometry zAxis = new Geometry("zAxis", new Line(zPoint.negate(), zPoint));
private DirectionalLight light;
private Material axisMaterial;
private BitmapText xLabel, yLabel, zLabel;
private Hector hector;
private Node headNode;
protected static float BODY_DEG_PER_SECOND = 120.0f;
protected static float HEAD_MOVE_SPEED_X = 30.0f;
protected static float HEAD_MOVE_SPEED_Y = 40.0f;
protected static float HEAD_MAX_ROTATION_X = 120.0f;
protected static float HEAD_MAX_ROTATION_Y = 50.0f;
protected static float MAX_JUMP_TIME = 0.3f;
public float headAngleX = 0.0f, headAngleY = 0.0f;
public boolean jumpCrouching = false, crouching = false;
public float jumpCrouchTime = 0.0f;
protected CameraNode camNode;
public static void main(String[] args) {
HectorTest app = new HectorTest();
app.start();
}
@Override
public void simpleInitApp() {
// Set background color.
viewPort.setBackgroundColor(ColorRGBA.Gray);
// Create axes.
axisMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
axisMaterial.setColor("Color", ColorRGBA.Green);
xAxis.setMaterial(axisMaterial);
axisMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
axisMaterial.setColor("Color", ColorRGBA.Red);
yAxis.setMaterial(axisMaterial);
axisMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
axisMaterial.setColor("Color", ColorRGBA.Blue);
zAxis.setMaterial(axisMaterial);
rootNode.attachChild(xAxis);
rootNode.attachChild(yAxis);
rootNode.attachChild(zAxis);
// Create the light source.
light = new DirectionalLight();
rootNode.addLight(light);
// Load the hector model.
// hector = new Hector("test", assetManager, new Vector3f(0.0f, 0.0f, 0.0f), 0,
// ColorRGBA.Yellow, ColorRGBA.Yellow, ColorRGBA.Blue);
headNode = hector.getHeadNode();
Node body = hector.getHectorNode();
rootNode.attachChild(body);
Geometry geom = new Geometry("box", new Box(Vector3f.ZERO, 0.5f, 0.5f, 0.5f));
geom.setLocalTranslation(0.0f, 0.0f, 5.0f);
// geom.setMaterial(WorldObject.materialForColor(assetManager, ColorRGBA.Green));
rootNode.attachChild(geom);
// Set-up the camera.
flyCam.setEnabled(false);
chaseCam = new ChaseCamera(cam, body, inputManager);
chaseCam.setDefaultDistance(10.0f);
chaseCam.setMaxDistance(100.0f);
chaseCam.setInvertVerticalAxis(true);
chaseCam.setMinVerticalRotation(-FastMath.PI / 2);
boolean pov = false;
if (pov) {
chaseCam.setEnabled(false);
camNode = new CameraNode("Camera Node", cam);
camNode.setControlDir(ControlDirection.SpatialToCamera);
camNode.setLocalTranslation(new Vector3f(0, 0, 0));
camNode.lookAt(new Vector3f(0, 0, 1), Vector3f.UNIT_Y);
headNode.attachChild(camNode);
}
// Add the axis labels.
xLabel = createAxisLabel("+x", ColorRGBA.Green);
yLabel = createAxisLabel("+y", ColorRGBA.Red);
zLabel = createAxisLabel("+z", ColorRGBA.Blue);
// Build a gradient skybox.
Color topColor = new Color(44, 25, 86);
Color bottomColor = Color.BLACK;
int boxSize = 512;
rootNode.attachChild(buildGradientSkybox(bottomColor, topColor, boxSize));
setupKeys(inputManager);
}
private Spatial buildGradientSkybox(Color bottomColor, Color topColor, int texSize) {
BufferedImage sides = new BufferedImage(texSize, texSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = sides.createGraphics();
GradientPaint p = new GradientPaint(0, 0, bottomColor, 0, texSize, topColor);
g.setPaint(p);
g.fillRect(0, 0, texSize, texSize);
BufferedImage top = new BufferedImage(texSize, texSize, BufferedImage.TYPE_INT_ARGB);
g = top.createGraphics();
g.setColor(topColor);
g.fillRect(0, 0, texSize, texSize);
BufferedImage bottom = new BufferedImage(texSize, texSize, BufferedImage.TYPE_INT_ARGB);
g = bottom.createGraphics();
g.setColor(bottomColor);
g.fillRect(0, 0, texSize, texSize);
AWTLoader loader = new AWTLoader();
Image sideImg = loader.load(sides, false);
Image topImg = loader.load(top, false);
Image bottomImg = loader.load(bottom, false);
Texture2D sideTex = new Texture2D(sideImg);
Texture2D topTex = new Texture2D(topImg);
Texture2D bottomTex = new Texture2D(bottomImg);
return SkyFactory.createSky(assetManager, sideTex, sideTex, sideTex, sideTex, topTex, bottomTex);
}
private BitmapText createAxisLabel(String label, ColorRGBA color) {
BitmapText axisLabel = new BitmapText(guiFont, false);
axisLabel.setSize(guiFont.getCharSet().getRenderedSize());
axisLabel.setColor(color);
axisLabel.setText(label);
guiNode.attachChild(axisLabel);
return axisLabel;
}
@Override
public void simpleUpdate(float tpf) {
// Keep the camera as the light source.
light.setDirection(cam.getDirection());
xLabel.setLocalTranslation(cam.getScreenCoordinates(xPoint));
yLabel.setLocalTranslation(cam.getScreenCoordinates(yPoint));
zLabel.setLocalTranslation(cam.getScreenCoordinates(zPoint));
if (!crouching)
hector.uncrouch(tpf);
Quaternion rot = new Quaternion();
rot.fromAngles(-headAngleY * FastMath.DEG_TO_RAD, -headAngleX * FastMath.DEG_TO_RAD, 0);
headNode.setLocalRotation(rot);
}
private void setupKeys(InputManager input) {
input.addMapping("jump", new KeyTrigger(KeyInput.KEY_SPACE));
input.addMapping("center", new KeyTrigger(KeyInput.KEY_2));
input.addMapping("crouch", new KeyTrigger(KeyInput.KEY_LSHIFT));
input.addMapping("explode", new KeyTrigger(KeyInput.KEY_E));
input.addMapping("head_left", new MouseAxisTrigger(0, true));
input.addMapping("head_right", new MouseAxisTrigger(0, false));
input.addMapping("head_up", new MouseAxisTrigger(1, false));
input.addMapping("head_down", new MouseAxisTrigger(1, true));
input.setCursorVisible(false);
input.addListener(analogListener, "crouch", "jump", "head_left", "head_right", "head_up", "head_down");
input.addListener(actionListener, "crouch", "jump", "center", "explode");
}
private AnalogListener analogListener = new AnalogListener() {
public void onAnalog(String name, float value, float tpf) {
if (name.equals("jump")) {
jumpCrouchTime += tpf;
}
else if (name.equals("crouch")) {
hector.crouch(tpf);
}
else if (name.equals("head_left")) {
headAngleX -= HEAD_MOVE_SPEED_X * value;
if (headAngleX < -HEAD_MAX_ROTATION_X)
headAngleX = -HEAD_MAX_ROTATION_X;
}
else if (name.equals("head_right")) {
headAngleX += HEAD_MOVE_SPEED_X * value;
if (headAngleX > HEAD_MAX_ROTATION_X)
headAngleX = HEAD_MAX_ROTATION_X;
}
else if (name.equals("head_up")) {
headAngleY += HEAD_MOVE_SPEED_Y * value;
if (headAngleY > HEAD_MAX_ROTATION_Y)
headAngleY = HEAD_MAX_ROTATION_Y;
}
else if (name.equals("head_down")) {
headAngleY -= HEAD_MOVE_SPEED_Y * value;
if (headAngleY < -HEAD_MAX_ROTATION_Y)
headAngleY = -HEAD_MAX_ROTATION_Y;
}
}
};
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("crouch")) {
crouching = keyPressed;
}
else if (name.equals("jump")) {
if (keyPressed) {
jumpCrouching = true;
jumpCrouchTime = 0.0f;
}
else {
jumpCrouching = false;
float jumpSpeed = Math.min(((jumpCrouchTime / MAX_JUMP_TIME) * 300.0f) + 1.0f, 7.0f);
System.out.println("jump with speed = " + jumpSpeed);
}
}
else if (name.equals("center") && keyPressed) {
headAngleX = 0.0f;
headAngleY = 0.0f;
}
else if (name.equals("explode")) {
ParticleEmitter explosion = new ParticleEmitter("Explosion", ParticleMesh.Type.Triangle, 20);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
mat.setTexture("Texture", assetManager.loadTexture("Effects/Shrapnel.png"));
explosion.setLocalTranslation(new Vector3f(0, 0, 3));
explosion.setMaterial(mat);
explosion.setStartColor(ColorRGBA.Yellow);
explosion.setEndColor(ColorRGBA.Red);
explosion.setImagesX(4);
explosion.setImagesY(4);
explosion.setStartSize(0.1f);
explosion.setEndSize(0.1f);
// explosion.setRandomAngle(true);
explosion.setGravity(0, 0.5f, 0);
explosion.setRotateSpeed(0.25f);
explosion.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 2, 0));
explosion.getParticleInfluencer().setVelocityVariation(0.4f);
rootNode.attachChild(explosion);
}
}
};
}