Pacman Clone questions

Started by
7 comments, last by wasted_druid 18 years, 10 months ago
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';
	}

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.
----------------------------------------------------------No matter how eloquently you state your argument, the fact remains that the toilet seat is a bistable device. Therefore it's natural position is no more down than it is up.[SDL Smooth Tile Scrolling]
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.
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]
----------------------------------------------------------No matter how eloquently you state your argument, the fact remains that the toilet seat is a bistable device. Therefore it's natural position is no more down than it is up.[SDL Smooth Tile Scrolling]
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();	}}
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.
----------------------------------------------------------No matter how eloquently you state your argument, the fact remains that the toilet seat is a bistable device. Therefore it's natural position is no more down than it is up.[SDL Smooth Tile Scrolling]
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.
----------------------------------------------------------No matter how eloquently you state your argument, the fact remains that the toilet seat is a bistable device. Therefore it's natural position is no more down than it is up.[SDL Smooth Tile Scrolling]
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();	}}
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]
----------------------------------------------------------No matter how eloquently you state your argument, the fact remains that the toilet seat is a bistable device. Therefore it's natural position is no more down than it is up.[SDL Smooth Tile Scrolling]

This topic is closed to new replies.

Advertisement