Tutorial 13 - Game API #1

Written By Akki On Friday, November 16, 2007

Tutorial 13 - Game API #1

PPL Game Programming - Part 1 - Game code structure.

PPL comes with a very powerful set of gaming functions called the GameAPI. The GameAPI comes in two different flavors. The first is the standard edition which does not contain the physic engine and the particles engine. You can create very nice games without them as well. In this first article of the series, we will concentrate on how games are handled in PPL.

Designing a game is a long and tedious process. You have to lay down your plan well in advance before even writing a single line of code. When it comes time to write the game you are often presented with low-level functions where you have to create custom routines to handle your particular kind of game. Writing a game engine requires good knowledge and time. With PPL, you can cut this step, saving days, weeks even months of hard work. The GameAPI will offer plenty of power for any type of 2D game programming.

The first step when you write a game with PPL is to start with a solid code structure that you will use as your starting template for all your future projects, unless you use the Game Level Editor that comes with the PIDE, the code generated by the GLE (Game Level Editor) has the same basic code structure as you will have here.

Let's review our code structure:

#include "GameAPI.ppl"
func mainproc(hWnd$, Msg$, wParam$, lParam$)
ok$ = true;
  case (Msg$)
    WM_CLOSE:
ShutGameAPI(hWnd$);
    WM_KEYDOWN:
g_KeyEvent(wParam$, True);
    WM_KEYUP:
g_KeyEvent(wParam$, False);
  end;
  return (ok$);
end;
func GameProc(hWnd$, Msg$, wParam$, lParam$)
case (Msg$)
WM_PAINT:
G_Clear(0);
RenderSprites;
    WM_TIMER:
if (g_key.vkA$)
PostMessage(hWnd$, WM_CLOSE, 0, 0);
end;
  end;
return (true);
end;
func WinMain
h$ = newform(, , &mainproc);
ShowWindow(h$, SW_SHOW);
  InitGameAPIEx(h$, &GameProc, 240, 320, false, 5, 60);
ShowFPS(true, G_RGB(255, 255, 255));

return (true);
end;

At the first line of code we include the GameAPI library into our project. This is where most of the GameAPI constants are defined. Some really handy functions are defined in as well. The mainproc function is where all GameAPI events are handled. The first event we will handle by default is the WM_CLOSE, which is triggered when the GameAPI main form is closed. Here we need to shutdown the GameAPI by calling ShutGameAPI(hWnd$). It is generally here that you will free all global objects. Sprites are freed by the function automatically. If you load surfaces manually, it is a good place to free them. Next we handle the WM_KEYDOWN and WM_KEYUP events. When a key is pressed (hardware keys on the PocketPC device), a keydown is triggered, then when the key is released, the keyup event is triggered. This code is pretty standard, a special function is called to set the g_key$ structure values, then you can easily check to see which key is being pressed and it supports multiple key presses too.

Next, every game as to have a main code function. At every internal cycle this function will be called. This is where you will handle game specific events like painting and timer. The painting can be handled manually using the WM_PAINT event or if you set the G_AutoDraw(True) right after the InitGameAPIEx() line, PPL will handle the drawing of sprites for you. If you use manual painting, the whole screen as to be repainted, that is why we clear the screen with G_Clear(0). Zero is the color of the background, black in this case. The RenderSprites() function will paint all sprites on screen with the correct layer order and everything. The WM_TIMER is called every game code cycle. We will see later how to change the cycle rate with the SetAISpeed() function. Here is a good place to check for key pressed. In our case if the hardware A key is pressed, we send a close message to the main game form.

The WinMain function is where PPL will start executing instructions for this program. Here we need to create a new form, display it using the ShowWindow() function. Next we need to initialize the GameAPI and the sound engine. InitGameAPIEx() will do all this work for us. We need to tell it what form will be used for the game display (h$), which main game code function to use (&GameProc), the resolution of the game (240x320 QVGA), the fullscreen parameter as to be false. Next is the cycle rate at which to call the WM_TIMER event in the main game function (&GameProc). Every 5 milliseconds PPL will try to trigger the WM_TIMER event. The last parameter is the maximum frames per second to display. 60 is a good generic value, it's smooth, gives time to the main game code to be executed and won't slow down the game by trying to draw unnecessary frames. Next we want to display the FPS (frames per second) information on screen. You might want to turn this off when your game is finished and you are ready to distribute it.

Finally we return a value of true to tell PPL to keep the application alive that it hasn't been closed.

This is a very basic game code structure. We will get into more details with sprites and their internal functions, pixel-perfect collision detection, sprite's mass, friction and velocity, particles and so much more as the series evolve. See you next month and happy game creation.

Share and Enjoy:
  • del.icio.us
  • StumbleUpon
  • Digg
  • Sphinn
  • Facebook
  • Mixx
  • Reddit
  • Technorati
  • IndianPad
  • YahooMyWeb

No Comments