Monday, 8 July 2013

Game Programming Essentials: Motion of Objects

First topic: making stuff move, obvious stuff.

When I first started making stuff move I tried the following:

for(int x=0;x<640;x+=10)
  draw_enemy(x,20);

But it quickly became obvious that this kind of idea won’t work.


Quite quickly you find out about the game loop:


while(!game_over)
{
  move_everything();
  draw_everything();
}

Which clears matters up and you figure out what you need to do.






Tip:
For those programming XNA: those are the Update() and Draw() functions.
For Unity3D & Flash: its you don’t usually see the Draw() function, you just have a script attached to a sprite/game object, which is in charge of transforming the object.
But generally its the same kind of code.


 


Simple position based movement


So we usually end up with some code to move our player which looks a little like this:



Sprite player;
...
const float SPEED=10;
if (KeyDown(LEFT))
  player.x-=SPEED;
if (KeyDown(RIGHT))
  player.x+=SPEED;
if (KeyDown(UP))
  player.y-=SPEED;
if (KeyDown(DOWN))
  player.y+=SPEED;

And this works just fine.






Tip: Dealing with variable frame rates

Many game engines (especially the 3D ones), are variable frame rate. That means that they might run 30-60 frames per second depending upon how much drawing has to be done. To overcome this variableness (you don’t want your player running twice as fast on some machines), you will include the delta time (amount of time elapsed between two frames) included in the computation:



if (KeyDown(DOWN))
  player.y+=SPEED * deltaTime;


You will need to look in your game engines documentation to check what delta time is in your code.


 

Simple velocity based movement


The next thing we think about it usually how to make a bullet/bomb/car move at a fixed speed in a direction. Normally we end up with code like this:



Sprite bullet;
...
const float SPEED=10;
bullet.y= -SPEED * deltaTime; // -SPEED as its going up

Any this works provided all bullets/bombs/cars go in the same direction, but usually that’s not the case. Therefore we need to have a velocity variable added to our Sprite class (I’m going to assume its vx & vy for simplicity). And our code becomes:



Sprite bullet;
const float SPEED=10;
bullet.vx=0; // not moving left/right
bullet.vy= -SPEED; // moving up
...
bullet.x = bullet.x + bullet.vx * deltaTime; // move by vx
bullet.y = bullet.y + bullet.vy * deltaTime; // move by vy

Does this look familiar to you? How about this?

image

This is the standard equations of motion (https://en.wikipedia.org/wiki/Equations_of_motion) or from your O-level/high-school physics text book.

Look at equation [2], and the code above:



bullet.x = 0 + bullet.vx * deltaTime; // move by vx
s = ut + ½ 0 t2 [2]
// Simplify:
bullet.x = bullet.vx * deltaTime; // move by vx
s = u * t

Guess what? The physics stuff which you studied because you had to pass the physics paper is actually used in your game.








Comment: vx,vy verses vel.x, vel.y

You might be using a game engine with a Vector2 or similar so instead of:



bullet.x = bullet.vx * deltaTime; // move by vx
bullet.y = bullet.vy * deltaTime; // move by vy


You have:



bullet.pos.x = bullet.vel.x * deltaTime; // move by vx
bullet.pos.y = bullet.vel.y * deltaTime; // move by vy


Or even:



bullet.pos = bullet.vel * deltaTime; // move by vel

The concept is the same, it’s just a matter of fitting it to the syntax/game engine.

Remember, I’m selling concepts here, not exact code.

 


Comment: 1D/2D/3D

All my examples here are 2D based (x,y), but the code work 100% the same for 3D (x,y,z) or even for 1D (if you wanted that). If there is anything which is different between 2D & 3D, I will mention it.


 


Adding acceleration to our velocity based movement


Well if the physics stuff works with our velocity routines, we could also add in the acceleration routines. Lets assume the sprite class has an ax, ay for acceleration:



Sprite bullet;
const float SPEED=10;
const float GRAVITY=2;
bullet.vx=0; // not moving left/right
bullet.vy= -SPEED; // moving up
bullet.ax=0; // no acceleration
bullet.ay=GRAVITY; // gravity is down
...
bullet.vx += bullet.ax * deltaTime; // apply acceleration
bullet.vy += bullet.ay * deltaTime; // apply acceleration
bullet.x += bullet.vx * deltaTime; // apply velocity
bullet.y += bullet.vy * deltaTime; // apply velocity

Any there we have it. We launch our bullet, it goes up in the air, and then down again.

 






Comment: Gravity is not always 9.8

I’m sure a few of you looked at the code & said ‘gravity is not 2, its 9.8’. Sorry you are wrong. Gravity on earth is 9.8m/s, but this is not earth, this is a computer game. Our unit of measurement is not meters, its pixels (or some other abstract unit). You will need to fiddle with your SPEED/GRAVITY values until they are the right amount for your game.


 

Adding direction to our velocity based movement


Ok, so a bullet up/down is rather boring, you probably want some kind of directional aiming (like a cannon trajectory), like this:

image

OK, well dust off your maths textbooks & answer me the following question:

image

“But Sir, this is maths!” I hear the cry.

Yes it is! Just like the physics we did earlier!

So get over it & solve it.

...

A bit of head scratching and sin/cosine laws later and we get:






vx = vel cos(elev)

vy = vel sin(elev)


Looking back over our code from earlier we could make the following changes:



const float GRAVITY=2;
const float VELOCITY=5;
const float ELEVATION=PI/2;
// bullet.vx=0; // not moving left/right
bullet.vx=VELOCITY * cos(ELEVATION); 
// bullet.vy= -SPEED; // moving up
bullet.vy=VELOCITY * sin(ELEVATION);

...

And ‘hey presto’, we have a moving object flying on a nice trajectory. All of a sudden all these math classes seem to have some use Smile

 

Next Step: Space Flight


How much new stuff do you think you need to learn to move on to asteroids?

image

Well, pretty much nothing new. It’s just a matter of applying it in a slightly different context.

So here is our basic idea:

The player has a position, a velocity and a rotation. When the press the forward key, it will generate a thrust (acceleration) in whichever direction the player is facing right now. The original asteroids game often did not include a deceleration (drag), but we can add it in later if we chose to.

So here is our basic code:



Sprite player;
const float SPEED=10, TURN_SPEED=PI/2;
player.position=...; // set initial position
player.angle=0; // no angle
player.velocity=Vector2(0,0); // no velocity
...
if (KeyDown(LEFT)) player.angle-=TURN_SPEED * deltaTime;
if (KeyDown(RIGHT)) player.angle+=TURN_SPEED * deltaTime;
if (KeyDown(THRUST))
{
  Vector2 accel;
  accel.x= SPEED * sin(player.angle);
  accel.y= SPEED * cos(player.angle);
  player.velocity += accel * deltaTime;
}
player.position += player.velocity * deltaTime;

 






Comment: Introducing Vector2

I’m getting a little tired of x+= vx; y+= vy; So I’m going to assume some kind of class (Vector2) which holds an X & Y parameter that supports the basic arithmetic operation (+ - * /). Otherwise this code is going to get more and more tedious.


Take note how, when the player presses thrust the velocity changes. But the movement happens regardless of whether the player is thrusting or not. This means that once the player begins moving, they will never stop. The player can only stop if they deliberately turn to face the opposite direction and thrust to stop themselves. This is accurate physics, but not necessarily good for our game.






Comment: Accuracy vs Playability

A key thing to remember in all games is we are aiming for fun, not realism. When I used to play counter-strike in the LAN shop & used to get annoyed at the expert players who would jump out of second floor windows, shooting as they fell & kill me. Or the players who would be continually jumping all over the place while shooting me.
Is it accurate to allow players to jump out of windows without issues? Of course not, but this is an example of where accuracy of the physics is ignored for the benefit of the game.


 

Adding a slowdown: Drag


Now back on topic: lets add in some kind of friction to slow the player down. Actually without some kind of drag it would be possible for the player to reach infinite speed, since they can accelerate forever in one direction. The drag also allows the player who doesn’t press a key to eventually come to a stop. It’s actually quite simple to do:



Sprite player;
const float SPEED=10, TURN_SPEED=PI/2, DRAG=0.01f;
...
if (KeyDown(THRUST))
{
  ...
}
player.velocity -= player.velocity * DRAG * deltaTime; // drag
player.position += player.velocity * deltaTime; // move player

The basic idea here is that, there will always be a bit of drag to slow the player down. The drag is proportional to the players speed. If the drag is 1/10 that’s quite a bit of friction & it will slow down fast. If its 1/1000 that’s very little and will only slow eventually. If the friction is 0.5 or even 1.0, then the object will hardly move at all.

I think the top speed should be SPEED/DRAG, but check it in your game to see how it works & adjust the factors to fit your need.

 

Conclusion


That’s our basic movement. It was only 2D, but the 3D version is just the same. That’s enough for basic gameplay.

Happy Coding:

Mark

Game Programming Essentials: Overview

Hello All,
Today, I’m beginning a series of articles to try to scratch an itch which has been occurring this semester in my game programming classes. The following are questions from my students:
image
image
image
image

image

All the above questions are in effect the same kind of question:
  • “How do I write my game?”
  • “How do I organise my game code?”
  • “How do I code up the game logic?”
Despite the last question saying its a DirectX question, its a more general, more fundamental question than that.  All these questions could be asked for any kind of game in any programming language.

So, here is what this series will be about:
  • Basic game programming techniques:
    • Not graphics, not networking, just the basics
  • No particular language:
    • General bias to C++/C#/Java syntax
    • But its mainly pseudo code
  • No working examples, just idea snippets
    • You will have to convert them to your own programming language/game engine
  • Common ideas, but trying to give as many applications as possible:
    • The same code for a homing missile could be misused to a simple RTS movement
That’s this idea, let’s get coding:

Mark

Wednesday, 17 April 2013

In case of Crash-Use Visual Studio’s Debugger

Today is common sense, but not common practice. Especially not common practice when dealing for students who are just learning to program.

Generally they treat the IDE as a glorified text editor. Yes it is that, but it has a lot more to offer then just that.

This post of focusing on one single point. What to do when the program crashes & how to use the diagnostic tools to isolate the cause of the crash.

 

The crash

We have all seen this often enough:

image

This is the error which the operating system kicks up if your program crashes. It also means that you forgot to turn on the debugger, as normally when you are developing the debugger should have caught it before it got here.

image

This is what you should have done. Set debug mode & use the green arrow (run in debugger). If you are a keyboard shortcut person, that’s F5. Do not use Control+F5, as that runs without the debugger. So try running your program again, this time with the debugger.

Sometimes you might get a window like this:

image

If so, take its advise & press ‘retry’, this will get the debugger helping you to find the error.

 

Take note of the symptoms

If you visit the doctor, they don’t just give you medicines do they? First they check your temperature, blood pressure & ask you what is wrong with you. So let’s do the same for our program. Here are the symptoms.

image

The 0x004117f9 is not useful, that’s the part of the code that failed (our debugger can tell us about that later). But the other bit is interesting. 0x00000000 is the classic null pointer, in fact based upon my own experience, any values 0x000...0x007 or so are likely to be a null pointer somewhere.

At this point we move on, press the ‘break’ key to pause the program, but DO NOT, press the stop button. I’m shocked how often students just immediately stop the program when it crashes & charge off guessing where the crash is. “Hey, Mac! The information is right there, just look at it!”

 

Call stack is your friend

99% of the time, you can get an almost perfect answer on what went wrong by looking to the call stack. If you cannot see it when debugging, try
Debug->Windows->Call Stack. You will see something like this:

image

There it is, a list of all the functions called. If you want, you can double click on each/all of the functions listed there and the IDE will bring you to the correct point of code where it was.

Tip: It’s never <insert name of library here>’s fault

A common mistake is to look at stack trace & say ‘but it crashed in the XXX library, the library must be broken’.

It’s not broken, it’s almost certainly you called the library with some bad values & it crashes. If the crash appears to be in the library code, move back the stack trace until you hit your code & then start looking around there. You will find rubbish being sent into the library.

 

Check your values

So we know where it crashes, what were the values passed in? Try highlighting the values, the IDE will pop up a tooltip with its current value.

image

The other place you can look is the auto’s window, which lists all the variables that the IDE thinks might be useful (Debug->Windows->Autos)

image

In this particular case, it looks like there might be something wrong with the ‘this’ variable (its a null).

If you are not sure, try going the stack trace & moving up a level & see what the context of calling the function was.

image

Ah, here we are. Someone called f->set(), but the issue is that f is a not a good value (its zero).

 

Tip: Good values vs Bad values

With practice, you learn what good values & bad values should look like. A score of -124324 is obviously a bit strange. But here are some thoughts on values:

For normal variables, large values (>10,000 or <-10,000) are probable incorrect.

Pointers are usually 0x0000 or some strange number which refers to a point in memory.

Instead of looking at the pointer, look at the value of the object its referring to
(in the above picture, val=??? which is certainly a bad thing).

Another handy trick which can be done is to watch a variable, so you can keep an eye on it as it changes. This can be done with ‘Right Click->Add Watch’ or
‘Right Click->Quick Watch’.

image

 

Crashes in STL

As mentioned in one of the boxes above, just because the code crashes in a library doesn’t mean it’s not your fault. A common example of this is accessing off the end of an array when using STL’s vector class. Normally you will get an error like this:

image

Don’t just hit return & abort, instead press the retry button & debug. The IDE will then bring you to a line of code in the middle of STL which you will not be able to understand (trust me: I find reading STL source code a headache, you don’t want to do it).

Instead of throwing up your hands in annoyance and giving up, call up the stack trace & search through it until you get back to your code.

image

Once you have got back to your code, you will be able to start checking all the variables to find the cause of the issue and what made the code crash.

image

In this case, its writing to v[10], when v is only 5 units long.

 

Crashes when deleting

This is probably one of the nastiest errors to debug. It’s when nearing the end of the program, you start deleting everything and the code crashes. You end up with an error like this:

image

Again it’s retry to debug, but it will be harder to spot what went wrong, as at this point things are being shutdown.

A general guess on this kind of error: is to check for a double delete. However sometimes errors like this can be caused by wandering off the end of an array. When the delete occurs, the IDE detects there is something wrong, but is not able to tell you what. But at least it has narrowed down to a class/array to check.

 

Conclusion

We could write more on this, there are probably books debugging. But here are a few simple bits of common sense which you can use when the program crashes.

Don’t just stop the program, instead look at where is crashed and why. You can probably guess from there what went wrong.

I won’t say ‘happy debugging’, as C++ debugging is rarely a happy event, but this might help a few of you be able to debug a little better.

Mark

The easy way to make reports (part 2)

Previously

Previously, when presented with a heap of data like this:

image

with a little html coding I turned it into this:

image

So the question is how?

How NOT to do it?

My first attempt had heaps of HTML code scattered inside my program. It worked, but it was so messy to try to maintain. Every time I wanted to change something, I needed to edit syntax, recompile & test.

Second attempt, was reading the C# report generation libraries. <YUK!>

Third attempt, was looking into XSLT and XML transforms. <Bigger YUK!>

Generally I found that I needed to learn a whole new library/language just to write a little HTML.
I needed a simpler solution.

 

Which was?

Lets look at some simple HTML, something like this

<html>
<body>
<h1>Name: [add name here]</h1>
etc,etc,etc
</body>
</html>



Simple enough right?
So we save this HTML off as our ‘template’, then the main code looks like:



  1. Load the template in
  2. Edit the template with a set of copy-paste actions
  3. Save the completed report

Quite straight forward right?


Show me the code!


Ok:



void makeReport()
{
  StringBuilder buffer = new StringBuilder();
  // read the template file
  buffer.append(File.ReadAllText("template/report.html"));
  // make changes
  buffer.replace("[add name here]", "mark gossage");
  // save the final copy
  File.WriteAllText("result/report.html",buffer.ToString()) ;
}



That’s it, kind of trivial isn’t it? 4 lines of code. But it works!!!!
I coded this example in C#, but you could have used python, perl, C++ or any other language you are familiar with.


What about a more complex example?


Life does get a bit more complex when you want a multiline table, but its still not that hard.
Starting with an html template like this:



<html>
<body>
<h1>Some Table Data</h1>
<table>
<tr><td>Name</td><td>Date</td></tr>
<!-- begin row-->
<tr>
  <td>[add name here]</td>
  <td>[add data here]</td>
</tr>
<!-- end row-->
</table>
</body>
</html>



You can do the same thing, you just need to duplicate the data between the ‘begin row’ and ‘end row’ as many times as needed.
The code looks generally like this:



void makeReport()
{
  // assuming buffer holds the template
  // find the section
  string data = buffer.ToString();
  int startIdx = data.IndexOf("<!-- begin row-->");
  int endIdx = data.IndexOf("<!-- end row-->");
  startIdx+=start.Length; // startIdx is at end of the 'start' string
  // get the 'row'
  string row=data.Substring(startIdx, endIdx - startIdx);            
  // temp buffer for working with
  StringBuilder temp=new StringBuilder();
  // for each item needed
  for(...)
  {
    temp.append(row); // add the row in
    // make changes
    temp.replace("[add name here]", ...);
    temp.replace("[add date here]",...);
  }
  // replace the 'row' with the data
  buffer.replace(row,temp.ToString());
  // save the stuff
}

This works perfectly, but is a little untidy, as it leaves the ‘begin row’, ‘end row’ tags in the file. But its only a couple of lines of code to fix that issue.


 


Conclusion


Another short & simple post.
No complex frameworks, no clever use of the language.
Just some simple common sense & problem solving.
You could write some kind of helper functions/class to do this job for you (I did).
Now my reports just need a little work in some HTML and a lot of search-replace.


Happy Coding,


Mark