Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

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.

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.

Thursday, 5 January 2012

Making use of particles for explosions

So far when I collide with a building. Nothing happens other than the player UFO bounces off.

I've added some quick code to make the player disapper and reset position.

But it would be nice to have a cool explosion. Well these new particles will work nicely.

Firstly I've created a wrapper class to contain the particle effects and then I can just pass this to my player object and upon collision just add the explosion particle to the game world.

Very easy to implement and now when I crash there is a satisfying explosion.

I decided to add another particle effect too for when you thrust the player UFO it now has an emission trail shoot out of the bottom.

All I did was copy the fire particle system and tweak it with a new graphic to get my desired effect.

This is kind of a distraction from getting my core game done but it was a fun experience and has added a nice polish to the game.

Wednesday, 4 January 2012

Particles are fun

Just a quick post to say I'm going to be implementing a particle system to handle things like my explosions.

Been having a play with the sample on App Hub (link) and this is what I've achieved in about an hour of tinkering

I want to see my bounding boxes

I want to try and figure out why my collision routines are all messed up now.

The logic isn't that complex, it's just a bounding box that intersects another box. How can rotation cause so many issues?

Well, first things first I want to see if I can draw my bounding boxes around my player UFO to see how things are looking.

Drawing a bounding box can't be that difficult, I know all my points of the cube, just need to add some lines. Rather than re-invent the wheel, I'll check google first to see if someone has already solved this issue.

App Hub again never fails to disappoint, this wonderful shape renderer class will do just nicely (link)

Easy enough to bolt on to my current code and get my bounding boxes rendering.

So now I have my bounding boxes drawn around the player UFO I can instantly see a random effect to the bounding box. With every rotation update, the bounding box is changing shape.


This is because the bounding box is calculated with every update to ensure it stays aligned to my player UFO.

I think there is probably a better way of doing things, but for now I'm just going to remove the rotation at the point of the bounding box calculation and re calculate when positioning the 3d object.

That works, probably not ideal but I'll revisit this later on to clean it up.

Tuesday, 3 January 2012

Giving the player a bit of character

So far the player UFO just slides around the map. It would be nice to have some sort of animation. Something like the UFO spinning around.

I think you can pre animate models and then play them in XNA, not sure though I've not really researched it.

My needs are simple, I Just want to rotate the 3D object through the Y axis and my base3Dobject already has a rotation property. All I need to do is add to this value every game iteration and my 3D object will rotate as the world matrix of the object takes scale, rotation and position into consideration.

Now the player UFO spins around when I run the game.

But now I'm getting some strange collision detection issues. I can cut right into the buildings and sometimes when I land I drop through the building.

What's going on? I've only changed the rotation!

Don't let the player escape

One thing I've noticed is that the basic game is there, but as a controlling player, I can pretty much go where ever I want (as long as I don't collide with a building object). I can completely fly out of shot, or fall through the invisible floor.

This would be a bit of a rubbish game artifact if I could just fly away and never know where the player UFO was.

The simplest solution is an invisible barrier around the game area, called my play area (I have a different play area for personal purposes)

This play area is just another bounding box and any time the player tries to move in any direction, I simply check to see if the player UFO bounding box will leave the play area bounding box. If it does then I don't let the player move.

Calculating the play area bounding box is very simple for this game.

I know the bottom left coordinates of my box as it will be the same coordinates as the bottom right bounding box of the first building cube drawn.

I also know the top right coordinates of my box as it will be the same as the top right bounding box of the last building cube drawn.

So all I need to do is when I'm generating the map, capture these two coordinates and create my bounding box out of those Min and Max values.

Quick test on the xbox

Well you need an App Hub membership to push any game code to the Xbox or Win Phone 7. If you're lucky you can get a free one for personal use whenever Microsoft do their Indie game competitions.

Or you can pay the £65 a year for a license (only worth it if you're going to attempt to sell games on the Xbox!)

Anyway, I do have a membership and I want to make sure what I've done so far works on the Xbox. I don't want to suffer the same fate as my 2D tile based engine, where I spent months tweaking and sweating over it to make it great, only to find out it doesn't work at all well on the Xbox because of the difference in garbage collection on the xbox to the PC!

After a quick check, it all seems to work fine so far, phew!

Cleaning up collision logic

Originally I Just used a couple of booleans to let me know if and where the player had collided.

Not very informative though, so I've added a collision enun that now tells me the state of collision

* none
* building
* roof

I can then use these accordingly to achieve other game mechanics later on.

Shadows and learning to read

So my first attempt at implementing the shadow mapping example was a mess.

I figured I would add all of the shadow creation code straight to the base3Dobject as that held all the lighting information.

Then I would call the draw shadow method on the player object only and I should get a shadow.

Well, mostly right but the shadow mapping uses something called a RenderTarget2D.

Not really sure exactly what it is but I think it is what is used to draw the shadows.

You set the render target as the item you want to cast shadows then pass this render target to other objects so they know where to draw the shadows.

What I had originally done was to define this render target object in everyone of my objects so they were all casting shadows only on themselves.

All I needed to do set this render target as a scene variable and pass it to my objects and now I have my shadow working the way I want.

The lighting is a bit basic at the moment as everything is lit very uniformly. This is because there is only one light source processed. For now I'm happy enough and I'll look into multi pass lighting later on.

I've added some textures to my objects in 3D max just to make it look a bit nicer.

Things are starting to shape up, I have the basics of a game.

Monday, 2 January 2012

My fun with shadow mapping

The first thing I noticed when trying to adapt the shadow mapping example from Msdn was it extends the model render content pipeline again.

No big deal as I've already done this to get my bounding boxes so I've just ripped out the new custom effect rendering code and added it to my existing custom content pipeline.

This example uses a custom effect and not the standard basic effect. From what I can tell, this custom effect is responsible for figuring out which pixel should be in shadow from the shadow map.

Once I had added the code to my custom content processor extension I started getting some strange long error messages about the effect is null.

It turns out that if you have a custom content processor that uses a custom effect, you have to tell visual studio that the model using the custom content processor also knows the name of the custom effect file. You just do this in the properties explorer.

So my initial implementation of the shadow map didn't work as planned. Partly because I had no idea what I was doing and blindly copy and pasting and hoping for the best.

Casting a shadow

From doing some research, it would seem that shadows in games and game engines is not an easy thing.

Getting a good looking shadows or even shadows at all takes some doing.

The Riemers XNA tutorials have a good section on dynamic lighting and using HLSL to write realistically lit scenes. The output is quite impressive but the effort to implement is substantial and not required for what I want.

I Just want a shadow cast from directly under the player UFO, nothing more than that.

So more research shows that shadow volumes are an easy way to build basic shadows.

There are XNA tutorials on shadow volumes and implementing them with the XNA stencil buffer. Problem is, every example I found was for XNA 3.1 or before and none of them seemed to work in XNA 4.0.

Rather than mess around with trying to get it to work I found another way using shadow maps.

Msdn has a nice example of how to implement a shadow map (link) and it gives me essentially what I'm after (and it works in XNA 4.0)

Setting the world alight

My use of 3D packages in the past like 3Dmax and povray help me realise that shadows are cast from scene light sources that can cast shadows.

These light sources are part of the world and cast shadows by varying techniques like ray tracing. This works fine in pre rendered scenes as the shadows don't dynamically move depending on player input.

Also, XNA doesn't have world lighting, you apply how an object is lit and you can have this info as a global variable so all objects are lit the same.

Problem is that no object knows about any other objects lighting and therefore can't block any light rays.

This means that shadows aren't a given in XNA. You can't just apply a light source and say cause this to cast shadows.

So it's not as easy as I thought. But I still think shadows are the best way to achieve my game mechanic so time to google!

Making my landing zone

So I need a way of checking the type of collision that has occurred.

For now I'll just have a boolean that states if the collision is safe.

So I need to determine what is a safe and unsafe collision.

If it hits the side its unsafe, if it hits the top then It's safe.

I could do all sorts of things like calculate the intersecting path to determine the plane intersected.

But my needs are simple.

If the intersection occurs and the max.Y of the player UFO bounding box is less than the max.Y of the building block bounding box then it can't have hit the top. So its unsafe.

Otherwise it must have collided with the top, therefore assume it's safe? Not quite.

The player UFO can just barely touch the top of the building block to cause an intersection and it will be considered safe. Which looks silly as it looks like the player UFO is balancing on the edge of a building. Really it should crash.

Again this isn't a hard check. If the player UFO has has collided with the top of the building and the player UFO bounding box x and z min and max limits is contained within the x and z min and max limits of the block bounding box, then it can be considered the player UFO has landed safely and is not over hanging the building at all.

So now I have the means to know if the building collision is safe or not.

I need to make this more challenging later based on the speed of the player descent. If you come down too fast then you crash land and die (just like in lunar lander)

But for now I have the basics of a game. I have my map and a controllable player that can collide with the landscape.

It works pretty well, the one annoying thing is you never really know exactly where the player UFO is hovering over so before you start your descent you can't be sure if you will crash.

This was a problem in the 2D version of the game too, and I solved it with a player shadow showing which building you were over.

So shadows are still in my opinion the easiest game mechanic to aid the player in knowing their position and helping them to a safe landing.

Better collision detection

So now I have bounding boxes to use, it is obvious from running the game that the clipping issue is much better.

Now the player UFO actually collides when you would expect it to.

Although it still rapidly bounces off walls, which isn't too bad as you would blow up anyway.

The biggest issue is when the player UFO lands on the top of a building, it flickers like crazy because of this bouncing. It doesn't look as if has landed. It's looks like it is having a fit!

This is because I'm reversing the velocity upon collision. Which is fine for the x and z axis but doesn't really help on the Y axis.

Also the world matrix for the objects is calculated in the update based on the current object position. Then the collision is checked, then the object is drawn.

When the collision is checked it resets the position but not the world, So when it comes to draw it, it actually draws the intersecting frame.

Easily fixed by storing the safe world matrix and using that when drawing the object.

This is common practice, check for collision and reset before you even draw it's position, then you never see the intersection.

So now the collision works well and I think is acceptable.

My only issue is what to do on a collision. If the player UFO touches the side of a building, then it's bad. However if it touches the top then it shouldn't die as it should be landed.

Extending the content pipeline

So XNA provides a very nice content pipeline.

Basically the way it takes content or media and makes it available in the programming environment and game.

So the model processor is the content processor that lets you work with the 3D objects. It's what creates the bounding spheres and provides all the other methods.

So you can extend any of these processors and use your own custom one on any content imported.

You don't have to do this at all. I could work out bounding box coordinates from my model mesh at run time, but it would need to be constantly updated and therefore processor intensive.

Extending the content processor means I can pre process the models and provide the data I need at point of initialization so the processor only has to do this once at game load (or at least model load)

So with a custom model processor that generates my bounding box data for me, means an more efficient solution.

Now all I need to do is set the content processor of the model fbx files (in the property explorer in visual studio) to the new custom model processor.

Now I have a bounding box for my 3D objects.