Jump to content
  • Advertisement
Sign in to follow this  
Hannibal111111

Pacman Clone questions

This topic is 4877 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've begun working on a Pacman clone using SDL but have some questions I'm hoping you guys can help me with. First, I have decided to make it using a tile based system using 32X32 tiles, but how do I go about doing movement for Pacman and the ghosts? Using tile-based movement, ie moving 32 pixels every time doesn't look too good so I was hoping for a better system. Also, would it better to have the Pacman and ghost objects as not part of the tilemap but as separate SDL Surfaces? Here is my code for moving:
if (up_pressed)
	{
		Player1.posy=Player1.posy-PLAYER_SPEED;

		//find out which tile you are moving to
		moveToTileX = Player1.posx/32;
		moveToTileY = Player1.posy/32;

		//set tile as player
		Level[moveToTileY][moveToTileX].type = 's';
	}

Share this post


Link to post
Share on other sites
Advertisement
Try this: When up is pressed, set a boolean called moving_up to true. Then as long as it is true move pacman up one pixel. Here's the kicker: have a check that whenever pacman's Y position is evenly divisible by 32 set moving_up to false. Render him as a separate surface from your tile map. That way he'll move smoothly, but still stop on tiles.

pseudo-code:


if(key_pressed(up))
moving_up = true;

if(moving_up)
pacman_y += 1;

if((pacman_y % 32) == 0)
moving_up = false;


That's how I'd do it.

Share this post


Link to post
Share on other sites
Quote:
Original post by wasted_druid
pseudo-code:


if(key_pressed(up))
moving_up = true;

if(moving_up)
pacman_y += 1;

if((pacman_y % 32) == 0)
moving_up = false;


That's how I'd do it.


That's how I've been doing it. It works. Just remember to put in a SDL_KEYUP event to make the boolean false again when you lift the key, which'll in turn stop Pacman moving.

Share this post


Link to post
Share on other sites
Quote:
Original post by ukdeveloper

That's how I've been doing it. It works. Just remember to put in a SDL_KEYUP event to make the boolean false again when you lift the key, which'll in turn stop Pacman moving.


That'll work, if you don't care if pacman stops on a tile... but if you want him to only stop centered on a tile, you don't want to set the boolean false when the key is lifted, because if he's only halfway there, he'll stop, well, halfway there.

I'd think in pacman, it would be useful to stop on tiles, but then again, maybe it wouldn't. Good luck. [grin]

Share this post


Link to post
Share on other sites
I like the idea, but I am having trouble getting it to work. Where would I put that code so that works correctly? Here is my code currently:



void HandleGameInput()
{
static bool up_pressed = false;
static bool down_pressed = false;
static bool right_pressed = false;
static bool left_pressed = false;
bool moving_up = false;
bool moving_down = false;
bool moving_left = false;
bool moving_right = false;
int moveToTileX = 0;
int moveToTileY = 0;

// Fill our event structure with event information. //
if ( SDL_PollEvent(&g_Event) )
{
// Handle keyboard input here //
if (g_Event.type == SDL_KEYDOWN)
{
if (g_Event.key.keysym.sym == SDLK_ESCAPE)
{
Done = 1;
//return; // this state is done, exit the function
}
if (g_Event.key.keysym.sym == SDLK_SPACE)
{

}
if (g_Event.key.keysym.sym == SDLK_UP)
{
up_pressed = true;
}
if (g_Event.key.keysym.sym == SDLK_DOWN)
{
down_pressed = true;
}
if (g_Event.key.keysym.sym == SDLK_RIGHT)
{
right_pressed = true;
}
if (g_Event.key.keysym.sym == SDLK_LEFT)
{
left_pressed = true;
}
}
if (g_Event.type == SDL_KEYUP)
{
if (g_Event.key.keysym.sym == SDLK_UP)
{
up_pressed = false;
}
if (g_Event.key.keysym.sym == SDLK_DOWN)
{
down_pressed = false;
}
if (g_Event.key.keysym.sym == SDLK_RIGHT)
{
right_pressed = false;
}
if (g_Event.key.keysym.sym == SDLK_LEFT)
{
left_pressed = false;
}
}
}

// This is where we actually move the player //
if (up_pressed)
{
moving_up = true;

Player1.posy = Player1.posy - 1;

if(Player1.posy % 32 == 0)
{
moving_up == false;
}
}
if (down_pressed)
{
Player1.posy=Player1.posy+32;
}
if (right_pressed)
{
Player1.posx=Player1.posx+32;
}
if (left_pressed)
{
Player1.posx=Player1.posx-32;
}
}

void Game()
{
if ( (SDL_GetTicks() - g_Timer) >= FRAME_RATE )
{
HandleGameInput();

//Draw the Level
for(int i=0;i<=20;i++) {
for(int j=0;j<=15;j++) {
if(Level[j].type == '.')
{
surTile = SDL_LoadBMP("Data/reg_pellot.bmp");
}
else if(Level[j].type == 'p')
{
surTile = SDL_LoadBMP("Data/power_pellot.bmp");
}
else if(Level[j].type == 'w')
{
surTile = SDL_LoadBMP("Data/straight_up_down_wall.bmp");
}
else if(Level[j].type == 'e')
{
surTile = SDL_LoadBMP("Data/blank.bmp");
}
DrawIMG(surTile,i * 32,j * 32);
}
}

//Draw Pacman
DrawIMG(surPlayer,Player1.posx,Player1.posy);

// Tell SDL to display our backbuffer. The four 0's will make //
// SDL display the whole screen. //
SDL_UpdateRect(g_Window, 0, 0, 0, 0);

// We've processed a frame so we now need to record the time at which we did it. //
// This way we can compare this time the next time our function gets called and //
// see if enough time has passed between iterations. //
g_Timer = SDL_GetTicks();
}
}


Share this post


Link to post
Share on other sites
Change

if (g_Event.key.keysym.sym == SDLK_UP)
{
up_pressed = true;
}


to


if (g_Event.key.keysym.sym == SDLK_UP)
{
moving_up = true;
}


Then you change


if (up_pressed)
{
moving_up = true;

Player1.posy = Player1.posy - 1;

if(Player1.posy % 32 == 0)
{
moving_up == false;
}
}


to



if (moving_up)
{

Player1.posy = Player1.posy - 1;

if(Player1.posy % 32 == 0)
{
moving_up == false;
}
}



Give that a shot.

Share this post


Link to post
Share on other sites
Also, loading the tile BMPs every time you draw a tile, every game loop isn't a very good way to do things. Load them into an array of SDL_Surfaces and access them that way. It's a whole lot quicker. Also, you're probably going to want to switch over to checking keystates for pacman movement, as opposed to waiting for a KEY_DOWN signal. That way the player can just hold down the direction keys to get pacman to move, instead of having to hit them repeatedly. It's pretty easy in SDL. I'll throw up the code for you, if you like.

Share this post


Link to post
Share on other sites
I was able to load the tile BMP's into an array of SDL_Surfaces and now the program runs much faster. But the pacman movement is still not working correctly...he only seems to move 1 pixel and then stops. Do I need to put my movement code somewhere else for this to work? Also, I would love to see your code on how to check for keystates for movement. Below is my latest coding for moving pacman (I'm only working on the up movement for now):


void HandleGameInput()
{
bool moving_up = false;
bool moving_down = false;
bool moving_left = false;
bool moving_right = false;
int moveToTileX = 0;
int moveToTileY = 0;

// Fill our event structure with event information. //
if ( SDL_PollEvent(&g_Event) )
{
// Handle keyboard input here //
if (g_Event.type == SDL_KEYDOWN)
{
if (g_Event.key.keysym.sym == SDLK_ESCAPE)
{
Done = 1;
//return; // this state is done, exit the function
}
if (g_Event.key.keysym.sym == SDLK_SPACE)
{

}
if (g_Event.key.keysym.sym == SDLK_UP)
{
moving_up = true;
}
if (g_Event.key.keysym.sym == SDLK_DOWN)
{
moving_down = true;
}
if (g_Event.key.keysym.sym == SDLK_RIGHT)
{
moving_right = true;
}
if (g_Event.key.keysym.sym == SDLK_LEFT)
{
moving_left = true;
}
}
if (g_Event.type == SDL_KEYUP)
{
if (g_Event.key.keysym.sym == SDLK_UP)
{
moving_up = false;
}
if (g_Event.key.keysym.sym == SDLK_DOWN)
{
moving_down = false;
}
if (g_Event.key.keysym.sym == SDLK_RIGHT)
{
moving_right = false;
}
if (g_Event.key.keysym.sym == SDLK_LEFT)
{
moving_left = false;
}
}
}

// This is where we actually move the player //
if (moving_up)
{
Player1.posy = Player1.posy - 1;

if(Player1.posy % 32 == 0)
{
moving_up = false;
}
}
if (moving_down)
{
Player1.posy=Player1.posy+32;
}
if (moving_right)
{
Player1.posx=Player1.posx+32;
}
if (moving_left)
{
Player1.posx=Player1.posx-32;
}
}

void Game()
{
if ( (SDL_GetTicks() - g_Timer) >= FRAME_RATE )
{
HandleGameInput();

//Draw the Level
for(int i=0;i<20;i++) {
for(int j=0;j<15;j++) {
DrawIMG(surTile[j],i * 32,j * 32);
}
}

//Draw Pacman
DrawIMG(surPlayer,Player1.posx,Player1.posy);

// Tell SDL to display our backbuffer. The four 0's will make //
// SDL display the whole screen. //
SDL_UpdateRect(g_Window, 0, 0, 0, 0);

// We've processed a frame so we now need to record the time at which we did it. //
// This way we can compare this time the next time our function gets called and //
// see if enough time has passed between iterations. //
g_Timer = SDL_GetTicks();
}
}


Share this post


Link to post
Share on other sites
Ha ha!!! I think I figured it out. Variable scope. Your moving_up variable doesn't maintain it's value from the first time you call HandleGameInput() to the next. Try making the bools Global, see if that works. And the code for checking Keystates:


Uint8 *keys;
keys = SDL_GetKeyState(NULL);
if(keys[SDLK_UP]) {
moving_up = true;
}
if(keys[SDLK_DOWN]) {
moving_down = true;
}




As I understand it it loads the keystate of the whole keyboard into an 8 bit integer. It uses the same keycodes as checking for Keypress events.

***EDIT*** Sometimes I think I'm an idiot. Just make the bools static. No reason to make them globals.

[Edited by - wasted_druid on June 10, 2005 2:24:19 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!