Thursday, October 28, 2010

Morning Coffee: Fun Projects

Screen capture of a 230x130 section of the heightmap below.
the 126,161 blocks are instanced using a single opengl VBO
Just thought I would share some of the personal projects I have been dabbling with these days. I just started looking at the game Minecraft, and Dwarf Fortress. Some of you are probably wondering "where have you been". Well DF (Dwarf Fortress) was started during my college years and probably didn't gain popularity and stability in the game till I graduated so theres that, and Minecraft is a recent development and quiet popular.

They are very interesting concepts and my mind has been spinning since I was introduced to them by a guy at work. So my project is to make my own game based off these two games. I have always liked the idea of an infinite gameplay world where the player can build pretty much anything they want and create a completely unique experience for themselves. Basing things off a simple set of blocks seems like the easiest way to go. I could just play DF and Minecraft but there are too many things I know I would like to have or different ways I would have done things as it is with most games I play.

Oh that and the fact I am pretty broke atm, too many bills to speak of, darn economy. So paying for Minecraft didn't sound good at this point though I will probably give it a try when I have that extra $15. I have started playing DF but I'm afraid the game is really involved and will take me a while to get into it. I am slowly beginning to learn how to play. So I decided I'd start by using JOGL (hehehe).

634x427 Procedurally generated heightmap using perlin noise.
4 octaves and 0.205 persistence
I ran into some issues with the Depth Buffer not working correctly. I basically took a simple cube example from Nehe and fixed it up a bit. It was Lesson 05 and I had to fix up the code a little bit because of the changes to JOGL for the most recent aggregated build. And I used a perlin noise generator I wrote based off of pseudo code from an article on perlin noise. So the image above is the generated world, with only a small 250x130 section of the heightmap generating 842,456 blocks, and further reduced to only about 126,161 being drawn. Performance is pretty bad right now because I am drawing all 126,161, no fog or visibility culling. But then lighting isn't turned on which is my next task and will probably kill my Nvidia GeForce 8400 GS.

I also implemented the Quaternion Camera Class from the Nehe Lesson: Quaternion Camera Class. I had to implement the quaternion of course I was kind of surprised JOGL does not have an implementation for Quaternions. But then it's supposed to simply be Java bindings to opengl.

Angled View: All 126,161 also notice the cutout portion at the bottom.
Apparently the algorithm needs some work, I don't need the blocks
on the bottom, or on the sides.
Since I have done a couple implementations of terrain generators and various other land, maze generation it wasn't that hard to implement. I hope to provide from useful snippets for procedural map generation soon. Today's post was actually going to be about 2D map/level rendering, but I didn't have the snippet ready so I decided I'd write about this little side project instead. By next Tuesday I should have a series of snippets on 2D map and level rendering done. My plan is to go over ways to rendering 2D maps and levels drawing only the visible area, showing a really nice way to draw layers, and how to do smooth level scrolling. After that it's on to collision detection algorithms, and then after that I can finally get to the meat and reason for creating this blog and show the really interesting gameplay snippets and talk about the fun part of game programming.

Side-View: The removing the side and bottom layers of blocks
should reduce the amount of blocks even more
Ok that's enough rambling for this morning.

Tuesday, October 26, 2010

Angular Character Movement

So as you've probably noticed the past few posts have been about character movement, the first being Basic Character Movement where I went over briefly a few movement style options you have for making a game. This post is going to be another extension of the character movement snippets, where the character will only be moving forward but this time the right and left arrow keys will turn the character right or left. This gives you full 360 degree movement.

Implementation
The code changes are fairly minimal as we still are only interested in whether the up, left, or right arrow keys are pressed. We need to utilize some trigonometric functions sin and cos to determine the amount to move the characters position in the x and y directions, respectively. Here is the new update function:
// angular movement is based on a radian angle for direction

  if (right) {
   this.direction += -0.2; // angular turning speed
  }

  if (left) {
   this.direction += 0.2; // angular turning speed
  }

  if (up) {
   // the movement calculations, sin and cos are used to get the
   // distance in x and y directions respectively. We multiply by the
   // timed passed so that we get more accurate movement and then the
   // speed variable controls how fast the block moves. And it has
   // specific units which are pixels per second.
   basicBlock.x += Math.sin(direction) * dt * speed;
   basicBlock.y += Math.cos(direction) * dt * speed;
  }
As you can see it's not that many lines of code, the right and left arrow keys will change the direction angle which is in radians. You can put it in degrees if you want but radians gives us more precision.

Upgrades
You might want to play around with this snippet a little and try enhancing the turning speed. If you multiply the amount to turn the character by the time passed you can make movement a bit more smooth and consistent. You can also easily add in some basic collision detection and make a nice little game out of this snippet. Combine it with the Game State Machine and the Keyboard Input: Polling System in Java possibly the Toggle Fullscreen Mode and a few other snippets I've posted and you've got a decent basis for a nice little Java game. Then the only limitation is your creativity in gameplay.

So here is the snippet for you to play around with:


Next -> Mouse Movement

Thursday, October 21, 2010

Character 8-Directional Movement

Eight directional movement is where the character can move in any of the following either directions: north, south, east, west, northeast, northwest, southeast, and southwest. This is a common top-down RPG style movement. Of course each game is free to modify and create it's own type of movement. For instance the classic game Asteroids, your ships movement was propelled by a rocket in the rear of the ship thus it always moved you in the direction your ship was facing for the time you applied thrust. You could turn left and right rather quickly but forward momentum always kept carrying you in the same direction. Momentum and friction are used commonly enough in movement it will be worth covering at some point.

In order to make 8 directional movement using the previous Basic Character Movement snippet, some pretty small changes need to be made. It isn't much and you possibly already know what those changes are, or have made them yourself if you've messed around with previous snippet.

So we are already capturing the keyboard state for the keys we care about and they are all the arrow keys and in order to do 8 directional movement we only need to know whether those keys are being pressed or not.

// 8 directional movement, n,s,e,w,ne,nw,se,sw

  // direction variables used to determine whether to move the block in
  // either the x or y directions.
  int dx = 0;
  int dy = 0;

  if (up) {
   dy = -1;
  }

  if (down) {
   dy = 1;
  }

  if (right) {
   dx = 1;
  }

  if (left) {
   dx = -1;
  }

  // move the block by multiplying the amount of time in seconds that has
  // passed since the last update by the speed constant and by the change
  // in x or y directions which will either will result in += 0 or
  // dt * speed negative or positive.
  basicBlock.x += dt * speed * dx;
  basicBlock.y += dt * speed * dy;
As you can see above the difference between the previous snippet and this one is that in the previous update code only one of the if statements would be handled and so if dx was non-zero then dy would always be zero which means no movement in the y direction. Now we allow dx and dy to both be set to anything depending on the arrow keys that are currently pressed.

So here is the snippet for you to play around with:



Tuesday, October 19, 2010

Basic character movement

Moving a character is probably the first thing that you want to do when making a game. There are many different ways to move a character however. This time I will only cover a very basic way of moving a character, I will post more movement examples later. But its good to start from a simple example and it should be enough to get you started making games.

Movement Types
This snippet will show 4 directional movement. Which means the character is will only move in one of four directions. This is an extremely simple movement type but is still very applicable for a lot of games. Platformers for example only use 2 directional movement, right or left, with the added jumping and climbing mechanics in some games. Pacman is an example of a game that uses 4 directional movement even though you are limited to continue moving in that direction until you hit a wall. More complex example of movement are ones such as 2D shooters which either have 8 directional movement or 360 degree movement. Almost all utilize the arrow keys on the keyboard, or a D-pad/thumbstick on a gamepad. Some like the point-click movement only use the mouse. New styles of movement are possible with the emerging multi-touch screens and are especially applicable to iphone and android game developers.

So this snippet needs to handle events, for simplicity I will only use the basic KeyListener interface in java.awt.event. It works well enough for a demonstration of movement. If you want a more game oriented input system see my Keyboard Input Polling System In Java post which goes over how to turn the interrupt driven awt event system into a polling system.

Aside from character movement there are other types of movement some simple and some complex. For instance, click to move here types of movement, these can actually be a bit more complex and utilize path-finding algorithms (i.e. A* for shortest path), which I hope to cover later as well. There is also tactical movement or tile based movement, used mostly by turned based games, where the play field is a grid partitioned into tiles and each turn a character has a specific number of movement points or speed which allows them to move a certain number of tiles in certain directions or along a path around the play field.

Buggy Movement
I remember when I first started coding games my movement code was hideous compared to what I use now. One of the first implementations I used was to increment the characters (x,y) position every key pressed event. The problem with this approach is that it relies heavily on the speed and number of interrupts. I also used to do a lot more in the KeyListener interface, like doing collision detection and almost all the game logic using the key events instead of a timed update call. Those are just a couple examples of things that might create some buggy movement. A much more subtle cause of buggy movement for more advanced game implementations is due to tying the amount to increment (x,y) to a single update. So depending on how many updates you get per second the character will move that much. This can become a problem if the updates happen to take longer than expected or shorter than expected. So tying an objects movement, not just characters, to how much time passed between calls will fix most problems. Of course determining when an by how much to move an object each frame can get quite complex.

Example Details
The snippet for this post uses the KeyListener interface which many know is interrupt driven meaning the operating system your running under sends your program key events, through whatever it's underlying system may be. We don't want to do much at all when we get a key event and certainly no incrementing of anything that affects the game. We simply want to change the state of the keyboard and only the keys we care about. For instance the up-arrow key, we will store whether it's pressed or not. Right now for movement we only really care about doing something specific for the length of time it is being pressed. So we simply save a single boolean state (true/false) for each key we care about. So for 4-directional movement we just want to know if the up, down, left, right arrow keys are pressed (true) or not (false). This makes it simple to write code that only happens when a specific key is down (pressed).

Simple enough so what do we do while the key is down? Well since this is an example of player movement we move the player...in one of 4 directions either north, south, east, or west. Ok well here is the basic character movement snippet, it is based off of the BufferStrategy snippet.

Thursday, October 14, 2010

How to use BufferStrategy in Java

One of the things I didn't know when starting Java programming was the state of the hardware acceleration support. Java does provide hardware acceleration. In earlier version the double buffering was a bit buggy but since jre6 it works very well in swing. It also uses DirectX and Opengl under the hood which you can enable/disable. Hardware accelerated drawing is enabled by default on most systems where it is properly installed. To take advantage of this hardware acceleration you want to use a java.awt.Canvas component. You can let swing do the double buffering which entails simply repainting the screen and not worrying about using the BufferStrategy class. It seems to perform well, so you should test both methods out and see which works best for you. In this snippet I will not mix swing and awt so I use a Frame instead of a JFrame. I noticed from an early access release of jdk7 that if you use a Canvas component inside a JFrame nothing will draw, unlike jre6 and below where it doesn't present an issue. I do not know whether this is intentional to try and keep native resources and lightweight resource from conflicting or some other such implementation detail but it did cause me a headache for a little while.

VSync Improving Visuals or Triple Buffering
This is a minor annoyance when running in windowed mode for a game. Occasionally the display and the drawing of the window will become out of sync and cause some tearing or jittering of the constantly refreshing window. It happens due to not being able to refresh the window contents at the exact same rate the display is actually refreshing the entire screen. This isn't too noticeable with such high refresh rates on monitors, but just in case you need to be able to do this, there is a function. I didn't really know about it till recently, it's in the java.awt.Toolkit called sync(). You can also create a buffer strategy with 3 buffers, or triple buffering, which is known to almost eliminate the need for the sync so that your program isn't in the middle of drawing to the buffer while the display is drawing from the buffer.
EDIT: Use java.awt.Toolkit called sync() to update the display buffer (whatever that really is) to be the most current drawing surface in the buffer strategy. Should help ensure the user sees the latest and greatest from the application.

Other Useful Options
A number of different options are also available as System Properties for java2d. For instance the trace property which tells you how long and specifically which drawing functions are called. This will let you know whether the hardware acceleration drawing layer in Java is being called at all.
java -Dsun.java2d.trace=log
Setting System Properties in the code
A nice thing to be able to do is to use a configuration file loaded by your program to save/load these types of graphics options or other kinds of options that your program may allow the user to change but are used by the Java API before the application starts. I like to use static initialization blocks for this. So I will have something like the following in my main class.
// performance settings.

static {
    System.setProperty("sun.java2d.transaccel", "True");
    // System.setProperty("sun.java2d.trace", "timestamp,log,count");
    // System.setProperty("sun.java2d.opengl", "True");
    System.setProperty("sun.java2d.d3d", "True");
    System.setProperty("sun.java2d.ddforcevram", "True");
}

You can set it up however you like and even get complex with it, loading the settings from a config file like I mentioned above, or popup a nice little window with selectable options for d3d versus opengl. The trace line specifies the format of all output from java2d as described in the system properties link.

Using BufferStrategy
Use the createBufferStrategy(int numBuffers) in the canvas component only after the frame has been created and displayed. You can control how many buffers to use for rendering, the most I'd suggest would be 3 any more than that is overkill, imho. Creation of the strategy may cause a java.lang.IllegalStateException to be thrown if the canvas does not have a parent who is being displayed. Meaning you need to add the Canvas component to a Container and make sure that container is visible.
// create a strategy that uses two buffers, or is double buffered.
  this.createBufferStrategy(2);

  // get a reference to the strategy object, for use in our render method
  // this isn't necessary but it eliminates a call during rendering.
  strategy = this.getBufferStrategy();

To use the BufferStrategy for rendering you want to use the strategy's getDrawGraphics and show methods. The getDrawGraphics creates a Graphics2D object that will draw to one of the buffers, if you are using 2 or more buffers this will be an offscreen buffer, allowing you to draw everything completely before displaying it which eliminates flickering and allows you to clear the buffer without the user noticing, and being able to redraw everything. Clearing and redrawing is essential for animation as you want to redraw the entire screen when objects move or change.

Example drawing code from the snippet:
// the back buffer graphics object
  Graphics2D bkG = (Graphics2D) strategy.getDrawGraphics();  
  
  // clear the backbuffer, this could be substituted for a background
  // image or a tiled background.
  bkG.setPaint(backgroundGradient);
  bkG.fillRect(0, 0, getWidth(), getHeight());

  // TODO: Draw your game world, or scene or anything else here.

  // Rectangle2D is a shape subclass, and the graphics object can render
  // it, makes things a little easier.
  bkG.setColor(Color.green.darker());
  bkG.fill(basicBlock);

  // properly dispose of the backbuffer graphics object. Release resources
  // and cleanup.
  bkG.dispose();

  // flip/draw the backbuffer to the canvas component.
  strategy.show();

  // synchronize with the display refresh rate.
  Toolkit.getDefaultToolkit().sync();

Precision and high frame rates
To make a good game you really do not need more than 60 frames per second. There is a lot of discussion about the subject and many say that the human eye will always be able to see screen refreshes. I think that it has nothing to do with the frame rate as much as with the movement and update timing. As long as the animation in your game is smooth without noticeable and often glitches then it will still be professional. You can always try and aim for a higher frame rate I think I have seen suggestions about around 100fps and I don't know why it's that number, jumping from either 30 to 60 and then all the way to 100. That's 1 frame every 10 milliseconds. While you can do a lot in 10 milliseconds there is a lot you can't do, so find what works best for your game and try and keep the amount objects moved every frame to change at a steady rate relative to their speed. So if an object is moving really fast across the screen small fluctuations in the rate of change in position every frame will cause jittery and jerky movement.

For this snippet I will not show the particulars of creating smooth movement that is for later snippets, where I will go through different kinds of movement. So at long last here it is: