Friday, December 3, 2010

2D Games with Kitten-Fu, Part One

As part of the UVOG arcade project, Jeff has been working on a 2d graphics library for C++ called Kitten-Fu. It's cute and fuzzy like a kitten but powerful like a ninja ...

I'm going to be using Kitten-Fu (KFu) and other open software to create a retro, side-scrolling game about ... what else, ninja cats.

As a way of introduction, I am a novice programmer who has dabbled in PHP and AVR Assembler. I'm going to be blogging my very first C++ program during this series.

First, we need to install the KFu library. KFu has a couple of dependencies, so make sure you install them first:

$ sudo apt-get install build-essential libsdl1.2debian libsdl1.2-dev libsdl-image1.2 libsdl-image1.2-dev

Once you have that, go to the Kitten-Fu wiki page and download the latest version of the library. I'm going to be using KFu alpha 10 to start with. After you have the file downloaded, extract it and in a terminal, navigate to the extracted files and type:

$ sudo make install

Now we have access to the KFu C++ libraries and can use them in our program.

Now, let's create a folder for our program to live in, for example: /home/yourName/Programing/kittens

The Sprites


I already know that I want my program to involve cats, and since I'm better at drawing than coding at this point, I'm going to start by drawing a sprite and then worry about getting it to the screen. For sprite creation, I use a program called MTPaint which is a great pixel editor. You can use any graphics program you like.

I drew my first cat at 16 by 16 pixels and in 4 colors, one of which (black) will end up transparent. I saved my sprite as an 8bit .png, which is an indexed file format - perfect for making a retro game. You could also use a 24bit .png which has alpha transparency (various shades of transparent) which lets you have pretty, smooth and curvy edges all at once! Make sure to let the file know that you want the first color to be transparent. In MTPaint this is through the save dialog. Here's a screenshot of my final kitty:




The Code


Okay now let's create our program files. I like to work with Nano, a command line text editor. You should use whichever program you are comfortable with as long as it's a text editor and not a word processor. (ie, not Open Office Writer or AbiWord, but using Kate or Gedit is fine)

In my kittens folder, I create a new file titled kittens.cc with the following contents:

// kittens
#include <unistd.h>
#include "KFu/KFu.h"
using namespace kfu;


This tells me the name of my new program, and that I want to use the KFu library. Save the file and then create another empty file named Makefile. A makefile is a type of script file so that you don't have to type out the compile instructions every time:

all: kittens_norun

kittens_norun: kittens.cc
 g++ -o kittens kittens.cc -lKFu -Wall --pedantic

kittens: kittens_norun
 ./kittens

IMPORTANT: The spaces on lines 4 and 7 are really tabs, make sure you replace them in your code.

Okay, save that, and now let's get that sprite to the screen! Open kittens.cc and add this to your file:

int main(int argc, char* argv[]) {
screen display(128, 120, 640, 480);
stamp kitt1("kitten1.png");

kitt1.put(100, 100);
display.flip();

sleep(5);
}

Before we talk about what everything does, let's make sure it works:

$ make kittens

A smallish black screen should pop up and have a little cat standing in the middle of it, and then it should close after 5 seconds. If this didn't happen, look back over all your code, and double check that everything is correct. I do have the project files included at the bottom of this post if you need them.

So, let's take a look at the code we just added. int main(...) { ... } is the wrapper for our actual program. Pretty much everything we do will be included inside of it.

screen display(128, 120, 640, 480); This sets up the parameters of our game screen. The first two numbers are the width and height of the game window. The next two numbers are the width and height of the screen. The game space will expand and center in the available screen space. This lets you change the size of the pixels on the screen. With the setup that we're using, we'll have a fairly small screen, and the pixels will be magnified x4.

stamp kitt1("kitten1.png"); This line sets up our stamp, giving it a name (kitt1) and telling it which file to use.

That's it for the setup, now we get to actually place the kitten on the screen.

kitt1.put(100, 100); Here, we name our stamp, tell it to "put" it to the screen, and tell it the x and y coordinates.

display.flip() is what actually paints the sprites to the screen. Very important, don't leave this out!

The last thing we do is tell it to do nothing for 5 seconds (sleep(5);) and then it gets the the final } and closes our program.

There are two things we need to add to our "game" to make it a bit more functional: movement, and a way to close it when we want rather than only letting it last for 5 seconds. Both of these are going to involve key presses, so let's add those in!

In between the screen set up and where we actually paint the cat, let's add a section:

/// HANDLE EVENTS ///
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE: done = 1; break;
default: break;
}
break;
}
}

This basically says, look at all the keys that are down, if you see the escape key get pressed, then done equals 1 and then skip to the end of this section.

You will also need to add the following line to the top of your program, right after int main() { in order to access the SDL event handling.

SDL_Event event;

Now, we need to tell the program that it should should skip on down to the end of the entire program when we press escape.

So, surrounding everything but the first few lines of setup, add a while statement:

int main(int argc, char* argv[]) {
SDL_Event event;
screen display(128, 120, 640, 480);
stamp kitt1("kitten1.png");

while (!done) {
... your code ...
}
}

We're going to have to set up the variable at the very top of our program, in between main() and the SDL_Event line:

int done = 0;

Now, we can clean up our code by removing sleep(5); as well as #include <unistd.h> since we aren't using them any more.

I guess I should mention that you should be compiling and running your program in between each set of changes so that you see the progression as we go along.

So, let's make that kitten move! Add the following line underneath the escape key press:

case SDLK_LEFT: walkleft = 1; break;

This sets the walkleft variable to 1. Add the walkleft variable underneath the done variable:

int walkleft = 0;

All by itself, that doesn't do anything--we need to use that variable in an if statement in order to change the coordinates of our cat.

First, change kitt1.put(100, 100); to:

kitt1.put(k1x, k1y);


now, let's preset our kitten's coordinates to the bottom right of the screen by setting our variables:

int k1x = 110, k1y = 88;

Now all we have to do is create our if statement and place it right before we put the cat to the screen:

/// GAME LOGIC ///
if (walkleft == 1) {
k1x = (k1x - 1);
}

If you run the file now, you'll notice that the cat smears itself across the screen, we need a way to clear the screen each time we paint. So let's add the following right before we "put" our cat to the screen:

display.clearSurface();

Next, we need to get the kitten to stop moving after you let go of the left arrow. We need to add a whole section to our Handle Events section right after the break; for case SDL_KEYDOWN::

case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_LEFT: walkleft = 0; break;
default: break;
}
break;

To get the kitten to wrap around to the other side, add the following tight after we decrement our x position:

if (k1x < -16) { k1x = 128; }

The numbers I chose here make sure that the kitten disappears off the screen before it re-appears on the other side.

You should be able to add all of the code to move the kitten to the right rather than just the left.

Next time we'll flip the kitten, animate it and add another kitten to follow it around!

The Files


You can download everything from part 1 here: kittens-01.tar.gz

* * *

No comments: