Friday, 20 January 2012

Creating state and screens

So far the game has loaded, jumped straight into the action and on completing a level just jumped straight back to playing.

I need to have some sort of naturally flowing state to the game such as...

Start page
Playing game
Level complete page
Game over page

And probably a Game paused page

This will allow the user to naturally flow through the main states of the game and provide input into what happens. Such as start or quit the game, pause play, see how well they did on a level or review how well they did at game over.

I've already got my enum to let me know what state my playing game is so I've added more states to this to represent these extra sections.

All I need to do is have some screens displayed to the user with a way of choosing options.

I've created a base Game screen class that draws a background image on screen and You can also provide it an array of menu choices which get rendered to screen. The default class also allows navigation and selecting menu items.

Now for each game state that requires a screen, I just extend this base class and add any custom functions such as displaying the end of level score or letting the user start a game.

There are much better state systems for XNA but this one is very easy to implement and serves my needs just fine.

Now my game has a nice flow of states.

Splash: check for user input to determine controlling game pad.

Main menu: can start the game, view controls or quit game.

Playing: game play mode

Paused: game froze, can also quit to main menu

Level complete: show score break down

Game over: show final score

Quit confirm: any time the user wants to quit just get them to confirm it.

Monday, 16 January 2012

Creating the HUD

Most games have some visual representation of how you're doing in the game. This is usually represented via a HUD (Head Up Display). It's basically an overlay of important game information such as score, lives, weapons you have, etc.

My game is starting to shape up and is actually playable now, however I don't know how well or badly I'm doing because all of my game variables aren't presented to me.

So I need a HUD!

My HUD just needs to display my current score, my lives left, the remaining peeps I need to abduct and most importantly... how much fuel I have left before I crash.

HUD information is displayed in many different ways, from simple text, to icons to bars and other fancy graphics.

For my HUD I'm going to keep it fairly simple. Score is going to be text, Lives and Peeps Left are going to be text next to a friendly icon explaining the text and the Fuel is going to be a bar representing a fuel gauge showing how much fuel I'm burning through.

The text and icons are fairly straight forward, I've just used the SpriteBatch function to draw fonts on screen and other Texture2D items for my icons.

The fuel gauge again isn't overly difficult, all I've done is built a simple function that draws a single pixel in a given colour a certain width and height across the screen. Then I repeat this drawing to give the impression of a full potential fuel level (red bar) and the actual fuel level (green bar).

Then in my HUD class when my update code is executed, I just update the relevant variables from the game code and the HUD displays them accordingly.

Very easy to implement but makes the game a whole heap more playable.

One other thing I can see now is when I complete a level, my score and lives reset. This is because previously I was setting lives and score in the level and not keeping track of them in a global state. Simple fix and now when I progress levels my lives and score stay as they should do.

Sunday, 15 January 2012

Adding a skybox

So far the game area has consisted of my 3d objects floating in a void of blue space. This doesn't look overly impressive for a game and I don't want to have to build an infinite 3D model of a city so it looks more realistic.

Most 3D games suffer from this issue of having to give the impression of a real world environment without having to build the full visible area (unless you're building a flight sim or something!)

The common solution to this problem is called adding a skybox.

A skybox is just another 3D object (usually a cube or a sphere) with the textures on the inside and then you ensure it moves according to your camera and all of your play area is located within the skybox object.

Then your textures applied to the skybox are of the background landscape and it seems as if there is a game world past the actual game world.

This technique was actually used in many Hollywood films, where a large matte painting would be hung behind the set to give the impression of a city or a large hanger bay full of X-Wings.

So to create my skybox, all I've done is to create a 3D object in 3D Studio Max made out of 6 planes with textures applied to. Load this object into my game and scale it up so it engulfs the game area. All I need to do is make sure the camera can never leave the skybox object and it all seems to work just nicely.

There are many other tutorials on how to create skyboxes in XNA and probably better, more efficient ways than what I've done, but this works for me and for this game so no need to tinker.

Sunday, 8 January 2012

A bit more of a challenge

I've also added a game state so I know if the player is currently playing the game, completed the level, is completely dead or has completed the game (I don't think this game will have an end?!)

The game starts out with a small number of peeps to abduct, and each time you capture (or kill) all of the peeps, you move on to the next level where there is 1 extra peep to collect (a maximum of 16 peeps then it resets back to 3 peeps but with less fuel to start with).

When I said you can kill peeps, I don't mean in a fun shoot em' up kind of way. If you land hard on a peep and you explode, you kill the little chap meaning you don't get any points for the abduction but you can still complete the level.

Adding the peeps

The game needs some sort of aim. In the original game, the aim was to abduct the humans standing on top of the buildings. As I'm doing a remake then I may as well keep this as the aim.

All I've done is created a new in game object called a person (extended from my Base3DObject), which is another model to load in.

However, this time around I want the little person to jump up and down and wave their arms around (like in the original). For this I'm going to need to animate my 3D object.

I'm sure there are many ways to animate the 3D objects from using bones and skeletal structures to probably having multiple frames of the object and quickly load them in succession (this seems daft though).

I could have even used the Xbox avatars as the best way to add a human to abduct. I did look into it, but for now I'll keep things simple.

What I'm going to do is animate the individual meshes of the person 3D object.

The person is made up of 6 sub meshes.

1. The head
2. The body
3. The left leg
4. The right leg
5. The left arm
6. The right arm

Up until now, any matrix transformation I've applied to my objects has been applied to all meshes. So if I rotate anything, then everything in the object rotates with it. This is all I've needed up until now as I wanted my entire UFO to rotate.

What I've done is to add another matrix multiplication to the world matrix for each mesh that I want to transform individually.

In this case, I want to rotate the arms of the person so they look as if they are waving.

I found a great link on how to do this (link)

So now I've got my person class and when I render the little fella to screen, he jumps up and down waving his arms.

All I did then was to add an imposed limit to how many could appear on the the map and in the map generation code randomly place my peeps on top of the buildings.

So when the level starts, the map is now littered with little people waiting to get abducted.

I've found the original

Just in case you wanted to have a look at the original flash game I mentioned, I've uploaded it for anyone to play (or mock as it is quite bad!)

Saturday, 7 January 2012

Making gravity work against you

Just a quick update to the game mechanic for player death.

Originally, if you touched anywhere other than the roof on a building, you would die. You could descend full speed down on to the roof and still survive.

In the original flash game (and lunar lander) you had to control your descent with your thrusters and couldn't come down full speed.

A simple addition to the player code now checks to see if the descent rate is too fast and returns an boolean true so the collision can be considered fatal even if you do collide with the roof.

I've also added Fuel in for the player, just a simple int that decreases every time you thrust. When you're out of fuel, you can no longer thrust, meaning you fall to your death!

The last addition is a Lives variable on the player, which I will use in the game to decrease every time you crash and when you reach 0 it's game over.