Thursday, April 23, 2009

Sounds for Games


Recently I wrote a quick post about the awesome sfxr. A great little utility for creating bleeps and bloops.

But that's not all today I stumbled on http://www.freesound.org. It has loads of sounds, all free and easily searchable.

Wednesday, April 22, 2009

Quickie Rotations

In my C# codebase I have no rotation code - which may be a little surprising but as I'm making a 2D game it's not been a issue until now.

I just want to be able to rotate my sprites around other sprites. A nice general solution would be to allow matrices to be be applied to the four vertices that make up each corner of my sprite.

But I didn't want to write a matrix class. So I just implemented the rotation manually:


public void Rotate(double angle, EinPoint origin)
{
for (int i = 0; i < _rawVerts.Count(); i++)
{
float cosAngle = (float)Math.Cos(angle);
float sinAngle = (float)Math.Sin(angle);
float newX = (_rawVerts[i].x - origin.x) * cosAngle + (_rawVerts[i].y - origin.y) * sinAngle;
float newY = (_rawVerts[i].y - origin.y) * cosAngle - (_rawVerts[i].x - origin.x) * sinAngle;
_rawVerts[i].x = newX + origin.x;
_rawVerts[i].y = newY + origin.y;
}
}


I'll be the first to say it's not pretty and there's probably a way to avoid the casting. But for my needs it's perfect. I've promised myself I'll implement all the matrix code once I finished my current game - which is coming along quite nicely.

Here's a good rotation reference.

I'm using OpenGL so of course I could use the OpenGL rotation commands - push a matrix, do the rotation, pop the matrix. But doing it this way sends extra commands to the graphics card. If I do the translation manually them I can skip those commands and I only need to pay for the cost of doing the rotation once instead of every frame. I'm thinking of also doing some rotations in my particle system so it's worth considering these issues.

Saturday, April 18, 2009

Sound for all

I'm not really a sound person, I know nothing of it. I liked fruity loops when it first came out but that's it. Like so many children the recorder was forced upon me when I was very young ... perhaps these things are related.

But games need sounds!



That's why Dr Petter's sounds effects tool is so awesome. You press one button and it makes a sound. If you like the sound you save it. That's the kind of program and user instructions I can throw my weight behind. It's name is the somewhat unwieldy 'sfxr'.

I only wish there was a little more variety. It seems to be based on what the NES sound hardware can produce - or some similar system. Still very good gamey sounds for very little effort. Thumbs up!

Saturday, April 11, 2009

Data bindings


Data bindings in C# are something I've totally ignored because I've always assumed they're boring database related code.

Yesterday I ported my simple particle system from C++ to C#. Previously I'd defined particle systems in my own special file format and then used that to create them. So I'd edit the file then load the test program and see what it looked like. (I may even have had a quick reload key, that reset the particle system with the new data)

In C# I thought I may as well have a second window with a load of controls on it. This is about two lines of code in C# and some mouse clicking. I remembered when I was doing some MFC stuff I could have a text box that had a pointer to a value of an object. So the data was totally real time, the number in the box was the number in the object.

I wondered if databindings would let me do something similar in C# and cut down on the amount of code I'd need to write. Here's what I've got at the moment:


public partial class ParticleTester : Form
{
ParticleSystem _system;
public ParticleTester(ParticleSystem system)
{
_system = system;
InitializeComponent();

particleSizeBox.DataBindings.Add("Text", _system, "ParticleSize");
}
}


That's the entire class. What the data binding means is - get the 'Text' field from the textbox 'particleSizeBox' and fill it up with data from _system.ParticleSize. This works both ways - if I change that value in the text box the value in my particle system changes. Very neat and quick - it's handles changing from a number to string and back again automagically.

Obviously I'm a little late to the party on databindings but it's nice to find something new and useful.



Just in case you want to know - this is how I did a combo box:


comboType.DataSource = System.Enum.GetValues(typeof(ParticleSystem.eParticleType));
comboType.DataBindings.Add("SelectedItem", _system, "ParticleType");

Sunday, April 05, 2009

Fiddly bits

Finally, I've written some code that I've been meaning to for a quite some time - the frame.

By frame, I mean an in-game window. A good example is the final fantasy screen shot below. It has a blue box with text in it. The blue box is a frame.



If you are using 3d acceleration the way to write this is to split the frame image up into a number of quads. So the corners are each a quad, so are columns and cross bars and the middle is a quad as well.

The columns and crossbars repeat their texture vertically and horizontally respectively. This allows the frame to be of arbitrary size but still look nice.

Here's a screen grab of the image I made in photoshop.



I have a small drop shadow, so the upper cross bar and the lower cross bar are different. The same for the columns. In total I have nine images each 16 x 16. I've packed all my images in a texture atlas.

Tiling or repeating a texture from a texture atlas using OpenGL isn't as simple as it is without a texture atlas. Without a texture atlas, you set the texture co-ords past 1.0 and for each unit over 1.0 it will repeat the texture. You also need to set a texture repeat flag somewhere. So a quad that has texture coordinates from 0,0 to 2,2 will repeat the texture four times over it's surface.

Using a texture atlas you can't alter the texture coordinates - as you're using them to cut a chunk out of the texture. So to get round this I just increased the vertex count on my frame mesh. Each time I want to repeat a texture I apply the same texture to a new quad and put the new quad next to the old one.

Here's the final result:



My frame has black border and I'm rendering on black so it appears a little strange - but at least it's working nicely now!

In the above each corner is a quad, the crossbars and columns and several quads in a row. The middle is a big mesh of quads - though often this middle section could be single large quad.