Pacman for Newbies

You are searching for a game engine? Why not trying the PopCap Framework?

Nowadays it isn´t necessary to sit down for about 2 years writing a game engine on your own, because there are hundreds of them, mostly available on the internet. If you´re satisfied with a "bugfree" 2D framework, proved in a lot of commercial games, and you don´t need the lastest graphic-features, why not taking a look at the free PopCap programming framework?

The PopCap framework (PCF) can both be used by hobbyists who make games as a hobby and need a platform to develop games instead of starting from scratch and indies or companies whose aim is to develop a commercial game. The PCF provides the core software components of a game, to make the game work. It combines different media elements (fonts, sounds, graphic files, level geometry and other art assets) and makes them work together, thus creating the game.

By the way: this site has no affiliation with Popcap Games.

This little project here was my way to work myself into the PCF and game programming itself after finishing the PCF tutorials/demos. Perhaps it can help you too. (btw: take a look at the neat breakout tutorial by vortex on the PCD board).

What you DON´T find here:
- complicated things in relation to the PopCap framework
- a step-by-step instruction on "how to make a game"

If you take a closer look at the sourcecode, perhaps answers to questions can be found here, for example, it could read:
- how can i use a finite state machine in a game?
- how to control time dependant events?
- how to implement an easy AI (i.e. a simple chase algorithm), like the ghosts in Pacman?
- how to define (array based) levels of a game?
- how to animate a sprite in a easy way?
- how to draw on a image with PopCap when the image is not visible on the screen?
- how to use the C++ STL with sense? 
- how to program a Pacman-like game in C++ ? ;)
- and hopefully even more ;)

This is the game when its running, so you can make yourself a first impression. However, i assume everyone knows the game Pacman ;)

Pacman Screen

 

[ Background of this description:
The focus here is the use of a finite state machine and the control of time dependant events. These are the topics im most interested in and which are effectively used here. ]

And this is the class diagram of the game:

Pacman Class Diagram
(click for larger image)

The finite state machine (FSM)

The FSM is a central element of the whole game and is used to control states, their properties and the transitions to other states.

#ifndef STATEMACHINE_H_
#define STATEMACHINE_H_

// a finite state machine (FSM)

#include 
#include
#include 
#include "state.h"

// substates for the fsm
// every state is subdivided into these three substates
enum SUBSTATES
{
 SM_SUB_INIT = 1,	// the state is beginning
 SM_SUB_IN,		// inside the state
 SM_SUB_EXIT		// the state is ending
};

class StateMachine
{
  private:
    
    std::map<:string state=""> states; // map to store the states under a name
    std::string prevState;	// previous state
    std::string curState;	// actual state
    SUBSTATES subState;		// the actual substate (SM_SUB_INIT, SM_SUB_IN or SM_SUB_EXIT)
    std::string newState;	// the new state; will become the actual state in the next step()
    std::string lastHandledEvent; // the last handled event
    
  public:
    StateMachine();
    StateMachine(const StateMachine& s);
    ~StateMachine();

    StateMachine& operator = ( StateMachine& s);
    
    void handleEvent(const std::string& e);
    void step();
    void dump();
    bool isInit();
    bool isIn();
    bool isExit();
    void addState(State& state);
    void addState(char * s);
    std::string getState();
    std::string getPrevState();
    int hasProperty(char * s);
    std::string lastEvent();
    void setInitialState(std::string& s);
    void setInitialState(char * s);
};

#endif /*STATEMACHINE_H_*/
,>

Example: the states intro and game

Our game should start with a small intro screen. So we declare intro as a state. If the player is pressing the space bar (to start the game, event start_game), he/she initiates the state transition from intro to game. We stay in the state game, until no more lives are left (event game_over). Then we change the state back to intro. As a state diagram, the whole thing looks like this:

Pacman States Intro Game
 

How to teach this to my state machine ?

You have to tell the state machine about the states and transitions. This could be directly translated from the state diagram:

State sIntro("intro"); 
State sGame("game"); 

sIntro.addEventTarget("start_game", "game"); // (*) see below sGame.addEventTarget("game_over", "intro"); 
gamestatus.addState(sIntro); 
gamestatus.addState(sGame); 
gamestatus.setInitialState("intro");

The class State defines a state we´re giving a name. With addEventTarget we define the state transitions (the arrows going outside the state) and the target state.
(*)  The condition for the transition from state "intro" to change to another state is "start_game" and the target state is "game". Then we add the states to the FSM named gamestatus. Last tell the FSM the initial state and we are ready to use it.

And how should i use it now ?

Imagine, we are in the state "intro" and want to force a transition to "game", it would look like this:

if ( gamestatus.getState() == "intro" ) 
{ 
  gamestatus.handleEvent("start_game"); 
} 
gamestatus.step(); 

After the next "step" we are in the "game" state, because "game" is the defined target state for this transition.

And what´s the need for those substates, defined in the FSM ?

The substates are a subdivision of a single state: init, in and exit:

Pacman A State
 

With this, it is easily possible, to do initialization- and/or clean up work within state transitions. Here an example for the state "game":

if ( gamestatus.getState() == "game" ) // are we in the state game ? 
{ 
  if ( gamestatus.isInit() ) ... // initialize the game here 
  if ( gamestatus.isExit() ) ... // clean up the game here 
  if ( gamestatus.isIn() ) 
  { 
    // process the game here 
  } 
}

What actually are these "properties" ?

The properties are additional informations, stored wihtin a state. A ghost for example, becomes blue if pacman has eaten a powerpill. Now the ghost can be im different states, for example, just in the homebox in the middle, or outside moving on the playfield. Both of this states gets the property "blue" as mark. Now, if you want to draw the ghost, you dont have to know the state exactly, you only have to ask, if the state has the property "blue" and draw the ghost as blue.

And what about the time dependant things, like the fruits in the game ?
 
The fruits are displayed after a certain time, for a certain time. This, at first, is also a good use for a FSM, to define the states:

Pacman FSM Fruits
 

You can nicely see with this diagram, that, if Pacman isn´t able to eat the second fruit, the fruit will never come back again ;) You can also see, that a lot of transitions are triggered by the end of a time (time_over). You can now start a timer, which remembers the time of entry into the state:

if ( statusFruit.getState() == "before1" && statusFruit.isInit() ) timer.startTimer("fruit1");

After that we easily ask the timer, if the (defined as a constant value TIME_SHOW_FRUIT1) time is already over and create a state transition:

if ( statusFruit.getState() == "before1" && timer.getTime("fruit1") > TIME_SHOW_FRUIT1 ) 
{ 
  statusFruit.handleEvent("time_over"); 
}

Now we are in the state "during1", where the fruit (here spCherry) should be displayed on the screen. This can be asked in the draw()-function:

if ( statusFruit.getState() == "during1" ) spCherry->draw(...);

 

Well, that´s it according to the FSM and the timer control, just check out the game now ;)

And if i still have more questions ?

If you still have questions about this, or extending the game or port it to another platform or another framework, then please drop me a line, so that i (curious wise) can watch it ;)

And now, have fun !!

Oh yes, only for legal clarification:

Most of the Code is part of Stefan Gaffgas Pacman clone (see http://www.3dcoding.de) the other part is written by me, Heiko Fischer.

This Pacman clone is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This Pacman clone is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

Credit is not required but it would be appreciated if you feel that this code seriously helps you in any way. This code is under GNU license except anything covered by different licenses such as the PopCap framework part.

I take no responsibility in any way shape or form for any loss or damages resulting from the use or misuse of this code. This code is provided so that others may learn whatever they can from it.

Download the attachments:
I just want to play, i´m not interested in the sourcecode - then download SexyPacman Windows executeable binary
No installation necessary, just extract and start pacman.exe.

Yes, i would like to get the sources - then download SexyPacman source
A Project for Visual C++ Express 2008 (get it for free at ms) is included, but the settings maybe have to be adjusted! In addition to compile it, the PopCap Framework is also necessary.

Downloads: 

Bitte bewerten Sie den Beitrag, vielen Dank für Ihr feedback!: 

Noch keine Bewertungen vorhanden