Thursday, June 21, 2012

Terrain Collision detection

Today I implemented collision detection between the camera and the terrain.  Here is a short clip showing this collision detection in action:


To do this, I added an invisible shape (a capsule, but it could be anything really) to the scene graph that I use as the camera's physical space representation.  By that, i mean that object takes up as much space as the camera and it's vehicle take up, and I simply move this object around and use JME3's built in collision detection mechanic to see where that object is able to move.  Then I just manually moved the camera to this invisible object's location, and it is as if the camera had collision detection itself.

The part that I had the most trouble with was hooking up my own camera physics class with JME3's collision detection mechanics.  With a bit of trial and error, I found the best way to do this was to just use JME3's CharacterControl class, which has a very simple physics engine that mimics a player-character's movement. What I did was to send my own physics engine's movement calculation to it, which act as a suggestion on where to go, and the CharacterControl will then tell if that is a viable movement and either go there or not.  Then I just update my own physics engine with the results of the CharacterControl.  Here is my moveCamera code, which is called from the main update loop, to hopefully help explain:

public void moveCamera(Vector3f move, float rotation){
        //remember the previous position vector.
        positionVectorClone = positionVector.clone();
        //Movement
        positionVector = positionVector.add(move);
**this is the CharacterControl**
        //move the physics body, walk in the direction of the difference
        //between the original position vector and the news one.
        cameraPhysicsBody.setWalkDirection(positionVector.subtract(positionVectorClone));
       
        System.out.println("move Vector: " + move);
        System.out.println("position Vector: " + positionVector);
       
        //Put camera onto its physics body.
        cam.setLocation(cameraPhysicsBody.getPhysicsLocation().clone());
       
        //reset position vector to reflect what the phsyics engine actually moved.
        positionVector = cameraPhysicsBody.getPhysicsLocation().clone();
       
**rotation was not effected by the new collision detection**
        //Rotation
        quat = new Quaternion();
        quat.fromAngleAxis(rotation, Vector3f.UNIT_Y);
        cam.setRotation(quat);
    }

Wednesday, June 20, 2012

HUD concept

Today I was able to create a proof of concept for a heads up display.  The text can be placed anywhere on screen, but I placed mine in the cockpit image's HUD display.  Here is an image of my concept:



I still have to make a class that controls the text that is input into the hud, since the text can go right off the cockpit's display if "\n"s are not inserted.  Also I want to make it very easy for other programmers to control what all is being displayed.  Another thing I wanted to do to this HUD is apply a little green to it.  To do this, I was thinking about adding a transparent green shape to the guiNode in this location.  Should be easy, and would look very cool!

Also today, since I gained admin access to my server provided from the school, I looked into implementing Java Webstart.  I found out where the httpd.conf file is for Apache on Red Hat (etc/httpd/conf/httpd.conf) and added the additional AddTypes required for Webstart (Link).  Next I found where Apache looks to for its index.html file (var/www/html/index.html) and put in my own hello world file in, and it works!  Link

However, I found a new problem.  When I was testing out how I was going to get the jar files onto the server, I noticed that my game doesn't work when you run it from the .jar file outside of the IDE!  The menu works, but when you press "play" the screen goes black.  Im thinking the game is not able to find all my assets, even though I have not moved them from the "dist" folder that the IDE generates.  I will look into this first thing tomorrow.

Tuesday, June 19, 2012

camera profile changing

Today I implemented my "camera profile" mechanic..  The camera profiles allow me to switch between different camera physics settings all via the config files.  The way it works is that in the MasterConfig.txt (which cannot be changed in path or name) there is a path to another config file, which I have called CameraConfig.txt but can be named or placed anywhere.  Here is an exact copy of my camera config file:


//        CURRENT CONFIG FILE FORMAT:
//        number of prifiles
//        //
//        float maxVelocity
//        int impulseXZ
//        int impulseY
//        float frictionX
//        float frictionY
//        float frictionZ
//        float frictionYRotation;
//        float rotationYImpulse
//        float rotationYVelocityMax
//        int mass
//--------------------------
//--------------------------
//--------------------------
2
//--------------------------
//helicopter cam
//--------------------------
//max Velocity
10
//impulse in XZ plane
15
//impuse Y plane
5
//friction X
2
//friction Y
4
//friction Z
2
//Rotation friction Y
3
//Rotation Impulse Y
.08
//Rotation Velocity Max Y
.08
//Mass
100
//-----------------------
//walking cam
//-----------------------
//max Velocity
1.8
//impulse in XZ plane
4
//impuse Y plane
0
//friction X
10
//friction Y
10
//friction Z
10
//Rotation friction Y
15
//Rotation Impulse Y
.15
//Rotation Velocity Max Y
.08
//Mass
100


My ConfigReader class reads in this file, and creates and fills out an array of custom data-holding classes filled with data the data found above.  Since this array's size is dependent on the first line in this config file, there is no real limit to how many profiles there can be.

The use for this feature is that I can now switch between helicopter and walking physics profiles with a simple function call: camPhys.setPhysicsProfile((short) indexOfProfileHere );  After that call, the camera will behave completely differently, e.g. going from helicopter controls to walking controls.

Tomorrow I will work on getting a popup window for displaying game dialog.  I want to try and get it to display in the cockpit's heads up display, but if that turns out to be too hard I will use the well used game mechanic of displaying game dialog in a boxed popup towards the bottom of the screen, something like:


Thursday, June 14, 2012

flying cameras



Well, here is a video of my camera controller so far.  It might not be as apparent when you are not pushing the buttons, but there is momentum in the camera now.  I am not always pushing the move buttons in this film, sometimes the "weight" of the camera is moving it, which gives the player more feed back and makes it appear more like a helicopter now.

Here is a quick way for keeping track of local physics stats for an object (a camera in my case) like it's velocity:  When keeping these variables, keep the coordinate systems relative to that object.  So for the camera, I kept the velocity vector's coordinate system the same as the camera's local coordinate system, or rather I kept the positive x-axis on the velocity to move the camera to it's right.  Then when it comes time to move that object relative to the world space (so a positive x-axis velocity might move the camera any direction!) find out how you need to rotate the camera's local coordinate system to match that of the world coordinate system, then apply those same rotations to the movement vectors.  Here is my code to do this for my camera:

        //make a quaternion that rotates the velocity vector
        //from camera space to world space.  Only on X-Z plane right now.
        //lookAt is a convienence method for auto-setting the quaternion based on a direction and an up vector.
        quaternion.lookAt(camOriginalDirection, Vector3f.UNIT_Y);
        movementVector = quaternion.mult(velocity);

Wednesday, June 13, 2012

Zero Means Ten in JME3

So a quick update from yesterdays camera problem I was having.  It turns out I was having a brain fart, since the camera actually was moving!  The mountain that the camera looks at by default was so far away that I just could not notice the movement... we all make newb mistakes every now and then.

Anyways, I have found a new problem that is very strange.  After doing more work on the camera system, I went to test out what I had created.  When I started the game, the camera took off at blazing fast speeds in the y direction.  After poking around and reviewing the code for a while, I decided to test out JME3's debugger.  I was quick to find the problem.  In short, the Vector3f class's static ZERO vector has a positive ten value for the y direction.  Below is what I found when debugging:


Maybe this is me being a newb again, but shouldn't the ZERO vector be all zeros?  Anyways, I experimented with different ways to initialize the vector, and here are the results:



So I need to go through and change all my code that has vectors in it so that they get zeroed out properly.  On a side note, the JME3 debugger works great (being based on netbeans I would expect it to) and I'm sure this wont be the last time I will be using it.

The camera system is turning out to be more challenging then I had thought, but I think it will be very nice and add to the users experience in the end.

Tuesday, June 12, 2012

Changes and Problems

Today I spent the majority of my time trying to get the camera to control like I wanted it to.  There seems to be something I am missing, as any changes I do on the main update method do not get reflected in game.  So I can position the camera where I want it initially, but on the update method if I try and move the camera nothing happens, and I use the same method to do both of these so something funny is happening that I need to figure out.  I am also experimenting with attaching the camera to a node and moving the node around, I will be sure to post the solution to this problem when I figure it out!

I also learned about AppStates today, which is a JME3 built in way of changing different "states" of game play very quickly.  For example, if you change from first person to third person, those could be two different AppStates.  AppStates can also change entire scenery, so you could potentially use AppStates to define different levels.  What is nice about AppStates is that they give access to all the Main class's SimpleApp objects, such as the root node, assetmanager, soundmanager, etc.  AppStates also hook into the update method and other very useful methods, so updating these AppStates is very easy to do.  So I am somewhat torn between carrying on with what I have, which is passing in pointers of the required objects to the classes I make, or if I should convert them to AppStates.

Monday, June 11, 2012

Custom Camera Controls

Today I stopped using the built in camera controller and made my own.  By default, the SimpleApp class in JME3 has a camera built in (cam) and an "appstate" that extends this camera called "flycam".  Flycam is nice for debugging and such since it comes with built in WASD controlls and mouse rotation, but for my project it needed to be replaced.  Building my own flycam replacement was important because it allows more control over how the user inputs are handled.  Now any kind of input device can, with some work, be made to work with the game.

All that is left to do on my controller is to play around with the way the camera gets moved so that it feels more like a helicopter and less like a flying super camera.  By this I mean there should be acceleration and momentum to the movement, and when not moving the camera should return to a position parallel to the ground like it was hovering.  Also, though it should be very simple now to make different perspectives (such as first person) I have not tested this out yet, so that also needs to be done.

Wednesday, June 6, 2012

Main Menu and Cleanup

Today I was able to get a menu system in place using JME's "Nifty GUI" technology.  This technology is very powerful from the demos I watched, and I dont expect to use even a fraction of that power in my game but it's nice to know what it can do.  The menu I created is very expandable, even dynamically expandable!

Here is a short video of the menu, along with a small bit of flying around my terrible testing level:

The Nifty GUI works a lot like Android in that you have Scenes (android activities) that hold different panels (android layouts) and have controls (android buttons and such) on them.  This is all changeable on the fly.  One example of this is that when a config file loads in, if the file cannot be found I let the GUI know this so that it can inform the user the file was not found.  When there is no reading error, the user does not see any error texts.


Also of note was a lot of cleaning up of the code; adding comments, putting large blocks of related code in new classes, etc.

Tuesday, June 5, 2012

Cube Maps and Terrain

Today, I got some of the basic visuals working in game, such as the terrain, a static cockpit, and a skybox.  I did the loading of these files through the use of external config files, this way changes can be made to maps without recompiling the game.  I plan on eventually making a master config file that a user can edit to tell the game to automatically look for his added config files and assets.



All the assets I made today are very much prototypes, just used to make sure everything is loading.  However, all that needs to be done is replace those assets with nicer ones and everything is good to go, that's nice!

As you can see in the picture, the changes in terrain height are a little abrupt!  The temporary height map I made just had grey lines around the edges, no nice transition from black to grey.  Again, just a test to see if the config file was getting the height map to the game engine.

For tomorrow, I plan to start working on a main menu, since a lot of what I am writing could be a little more final if I had a main menu.

Monday, June 4, 2012

Physics and Terrain

For the collision detection, jMonkeyEngine does most of the heavy work, which is very nice!  All the user must do is add bounding shapes over the object they want to have physics applied to, and then register those objects with the physics engine.  Also, its very important to change the way you move that object and go through the physics engine, not through the setLocalTranslation() method.

Terrain in JME is handles through the use of height maps and texture splatting maps.  Instead of storing every single point in the terrain's height, we just make a much smaller map of the height of the terrain and interpolate that map across the much larger game terrain.  Here is an example of a height map:

The whiter the color, the higher the terrain.  Thus, this map makes a mountain in the middle of the terrain, with another steeper peak in the top left.

Texture Splatting is similar in concept.  There is a small map of colors that determine which texture will be loaded to that area of the terrain.  For example, if you assign the color red to mean load a grass.png texture and blue to load ice.png, then the above height map will have blue where the peaks are and read where the valleys are.

That wraps up the tutorials for now, next I will begin to create the Wind Explorer game!

The first thing I worked on is seeing how to setup and load a scene.  Scenes are an organization of objects that can be quickly loaded into the game engine with two lines of code.  Behold:



Blue Pies!  These three pies were loaded into the initApp() function at those locations with only this code:

Spatial scene = assetManager.loadModel("Scenes/pie.j3o");
rootNode.attachChild(scene);

Scenes themselves have a graphical editor to them, making building of a game a little less trial and error.  Here is a picture of what the scene editor looks like:


 More to come!

Game Design Document

Last Friday was spent going to a brainstorming meeting in which the final game was discussed.  From this meeting, I have made a game design document.  Below is a link to this document:

GDD Link

Note: This document can change to reflect design changes.