Character Animation problem, please help

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
liveordie2112
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 14
Joined: Mon Mar 02, 2009 10:06 am
Favorite Gaming Platforms: Give it up for the Snes and the n64 :D
Programming Language of Choice: C++, and Lua
Location: The middle of nowhere, Nevada

Character Animation problem, please help

Post by liveordie2112 »

I am working in Visual c++ and am using SDL

I am trying to animate a character(in this case, mario) using six frames of animation. Three for the left walk cycle and Three for the right walk cycle. I am also using the right and left walk cycles for when the character moves up and down, like the way luigi moved in the episode from the adventures in game development(specifically this episode,http://www.youtube.com/watch?v=ojVwBtzB ... 4C&index=3).

I was trying to debug this and the screen immediately disappears and then a window appears that says there was an error at part of my code. It stopped in my apply surface function, under the function named SDL_BlitSurface and the debugger tells me that its the parameter called "clip"

it said that it could not calculate the value for the x,y,w,and h of "clip"

(in the tree on the bottom left of the screen)

I have no idea where to begin even trying to fix this problem. :( Any help would be greatly appreciated :worship:
main.cpp

Code: Select all

#include "SDL.h"
#include "SDL_image.h"
#include "Timer_class.h"
#include <string>

using namespace std;

const int SCREEN_WIDTH	 = 640;
const int SCREEN_HEIGHT	 = 480;
const int SCREEN_BPP	 = 32;

const int PLAYER_WIDTH	 = 17;
const int PLAYER_HEIGHT	 = 32;

const int PLAYER_LEFT   = 0;
const int PLAYER_RIGHT  = 1;
const int PLAYER_UP     = 2;
const int PLAYER_DOWN   = 3;

const int PLAYER_VEL    = 20;

SDL_Surface *MarioSheet = NULL;
SDL_Surface *screen     = NULL;

SDL_Event event;

SDL_Rect clipsRight[3];
SDL_Rect clipsLeft[3];

SDL_Surface *load_image(string filename)
{
	SDL_Surface *loadedimage    = NULL;
	SDL_Surface *optimizedimage = NULL;

	loadedimage = IMG_Load(filename.c_str());

	if(loadedimage != NULL)
	{
		optimizedimage = SDL_DisplayFormat(loadedimage);

		SDL_FreeSurface(loadedimage);
	}

	if(optimizedimage != NULL)
	{
		SDL_SetColorKey(optimizedimage,SDL_SRCCOLORKEY,SDL_MapRGB(optimizedimage->format,0,0xFF,0xFF));
	}

	return optimizedimage;
}

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
	SDL_Rect offset;

	offset.x = x;
	offset.y = y;

	SDL_BlitSurface(source,clip,destination,&offset);
}

void set_clips()
{
    //Clip the sprites
    clipsLeft[ 0 ].x = 0;
    clipsLeft[ 0 ].y = 0;
    clipsLeft[ 0 ].w = PLAYER_WIDTH;
    clipsLeft[ 0 ].h = PLAYER_HEIGHT;
    
    clipsLeft[ 1 ].x = PLAYER_WIDTH;
    clipsLeft[ 1 ].y = 0;
    clipsLeft[ 1 ].w = PLAYER_WIDTH;
    clipsLeft[ 1 ].h = PLAYER_HEIGHT;
    
    clipsLeft[ 2 ].x = PLAYER_WIDTH * 2;
    clipsLeft[ 2 ].y = 0;
    clipsLeft[ 2 ].w = PLAYER_WIDTH;
    clipsLeft[ 2 ].h = PLAYER_HEIGHT;
    
    
    clipsRight[ 0 ].x = 0;
    clipsRight[ 0 ].y = PLAYER_HEIGHT;
    clipsRight[ 0 ].w = PLAYER_WIDTH;
    clipsRight[ 0 ].h = PLAYER_HEIGHT;
    
    clipsRight[ 1 ].x = PLAYER_WIDTH;
    clipsRight[ 1 ].y = PLAYER_HEIGHT;
    clipsRight[ 1 ].w = PLAYER_WIDTH;
    clipsRight[ 1 ].h = PLAYER_HEIGHT;
    
    clipsRight[ 2 ].x = PLAYER_WIDTH * 2;
    clipsRight[ 2 ].y = PLAYER_HEIGHT;
    clipsRight[ 2 ].w = PLAYER_WIDTH;
    clipsRight[ 2 ].h = PLAYER_HEIGHT;
    
}

bool init()
{
	if(SDL_Init(SDL_INIT_EVERYTHING) == -1)
	{
		return false;
	}

	screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);

	if(screen == NULL)
	{
		return false;
	}

	SDL_WM_SetCaption("Mario Animation test", NULL);

	return true;
}
bool load_files()
{
	MarioSheet = load_image("mario.png");

	if(MarioSheet == NULL)
	{
		return false;
	}

	return true;
}
void clean_up()
{
	SDL_FreeSurface(MarioSheet);

	SDL_Quit();
}

class PlayerClass
{
private:

	int status;

	float x, y;

	float xVel, yVel;

	int frame;

public:

	PlayerClass();

	void move(Uint32 deltaTicks);

	void handle_input();

	void show();

};

 PlayerClass::PlayerClass()
{
	status = PLAYER_RIGHT;

	int x = 0;
	int y = 0;
	int xVel = 0;
	int yVel = 0;
	int frame = 3;
}

void PlayerClass::handle_input()
{
	if(event.type == SDL_KEYDOWN)
	{
		switch(event.key.keysym.sym)
		{
		case SDLK_UP:    yVel -= PLAYER_VEL; break;
		case SDLK_DOWN:  yVel += PLAYER_VEL; break;
		case SDLK_LEFT:  xVel -= PLAYER_VEL; break;
		case SDLK_RIGHT: xVel += PLAYER_VEL; break;
		}
	}
	else if(event.type == SDL_KEYUP)
	{
		switch(event.key.keysym.sym)
		{
		case SDLK_UP:    yVel += PLAYER_VEL; break;
		case SDLK_DOWN:  yVel -= PLAYER_VEL; break;
		case SDLK_LEFT:  xVel += PLAYER_VEL; break;
		case SDLK_RIGHT: xVel -= PLAYER_VEL; break;
		}
	}
}
void PlayerClass::move(Uint32 deltaTicks)
{
	x += xVel * (deltaTicks/1000.f);

	if(x < 0)
	{
		x = 0;
	}
	else if( x > SCREEN_WIDTH)
	{
		x = SCREEN_WIDTH - PLAYER_WIDTH;
	}
	
	y += yVel * (deltaTicks/1000.f);

	if(y < 0)
	{
		y = 0;
	}
	if(y > SCREEN_HEIGHT)
	{
		y = SCREEN_HEIGHT - PLAYER_HEIGHT;
	}

}



void PlayerClass::show()
{
	if(xVel < 0)
	{
		status = PLAYER_LEFT;
		
		frame++;
	}
	else if(xVel > 0)
	{
		status = PLAYER_RIGHT;

		frame++;
	}
	else
	{
		frame = 2;
	}

	if(yVel < 0)
	{
		status = PLAYER_DOWN;
		frame ++; 
	}
	else if(yVel > 0)
	{
		status = PLAYER_UP;

		frame++;
	}

	if(frame > 3)
	{
		frame = 0;
	}

	if(status == PLAYER_UP)
	{
		apply_surface((int)x,(int)y,MarioSheet,screen,&clipsRight[frame]);
	}
	else if(status == PLAYER_DOWN)
	{
		apply_surface((int)x,(int)y,MarioSheet,screen,&clipsRight[frame]);
	}
	else if(status == PLAYER_LEFT)
	{
		apply_surface((int)x,(int)y,MarioSheet,screen,&clipsLeft[frame]);
	}	
	else if(status == PLAYER_RIGHT)
	{
		apply_surface((int)x,(int)y,MarioSheet,screen,&clipsRight[frame]);
	}

}

int main(int argc, char* argv[])
{
	bool quit = false;
	set_clips();
	Timer Delta;
	PlayerClass Mario;

	if(init() == false)
	{
		return 1;
	}
	if(load_files() == false)
	{
		return 1;
	}

	Delta.start();
	
	while( quit == false)
	{
		if(SDL_PollEvent(&event))
		{
			Mario.handle_input();

			if(event.type == SDL_QUIT)
			{
				quit = true;
			}
		}

		Mario.move(Delta.get_ticks());
		Delta.start();

		
		SDL_FillRect(screen,&screen->clip_rect,SDL_MapRGB(screen->format,0xFF,0xFF,0xFF));
		
		Mario.show();
		
		if(SDL_Flip(screen)==-1)
		{
			return 1;
		}

	}

	clean_up();

	return 0;
}
Timer Class.h

Code: Select all

#include "SDL.h"
///all credit for the creation of this timer class goes to lazyfoo
//i just memorized the code and how it works
class Timer 
{ 
  private: 
  //The clock time when the timer started 
  int startTicks;

 //The ticks stored when the timer was paused
 int pausedTicks;

 //The timer status
 bool paused;
 bool started;

 public:
 //Initializes variables
 Timer();

 //The various clock actions
 void start(); 
 void stop();
 void pause();
 void unpause();

 //Gets the timer's time
 int get_ticks();

 //Checks the status of the timer
 bool is_started();
 bool is_paused();

}; 
Timer Class.cpp

Code: Select all

#include "Timer_class.h"

Timer::Timer()
 { 
 //Initialize the variables
 startTicks = 0;
 pausedTicks = 0;
 paused = false;
 started = false;
 } 


void Timer::start()
 { 

 //Start the timer
 started = true; 

 //Unpause the timer
 paused = false;

 //Get the current clock time
 startTicks = SDL_GetTicks();
 } 



void Timer::stop()
 {
 //Stop the timer
 started = false;

 //Unpause the timer
 paused = false;
 }



int Timer::get_ticks()
 {
 //If the timer is running
 if( started == true )
 {
 
    //If the timer is paused
    if( paused == true )
    {
      //Return the number of ticks when the timer was paused
       return pausedTicks;
      } 
    else
      {
      //Return the current time minus the start time
      return SDL_GetTicks() - startTicks;
      }
     } 
//If the timer isn't running

 return 0;
}

 

void Timer::pause()
 {
   //If the timer is running and isn't already paused
   if( ( started == true ) && ( paused == false ) )
   {
    //Pause the timer
       paused = true;
    //Calculate the paused ticks
    pausedTicks = SDL_GetTicks() - startTicks;
   }
 }



void Timer::unpause()
 {
 //If the timer is paused
   if( paused == true )
    {
    //Unpause the timer
       paused = false;
    //Reset the starting ticks
    startTicks = SDL_GetTicks() - pausedTicks;
   //Reset the paused ticks
     pausedTicks = 0; 
     }
 }

bool Timer::is_started()
 { 
    return started;
 } 

bool Timer::is_paused()
 {
   return paused;
 }
Mario.png
Image


EDIT: I fixed it! I just had to remove the variable types before the variables in the constructor because I already declared them in the playerclass.

thanks everyone :D
Last edited by liveordie2112 on Thu Jun 18, 2009 9:44 pm, edited 3 times in total.
and by the way did you know you're reading my signature?
Image

________________________________
My Youtube Account:
http://www.youtube.com/user/CheesyBerger
User avatar
MarauderIIC
Respected Programmer
Respected Programmer
Posts: 3406
Joined: Sat Jul 10, 2004 3:05 pm
Location: Maryland, USA

Re: Character Animation problem, please help

Post by MarauderIIC »

I'm not sure. Looks like you call set_clips before you call apply_surface and that they're all initialized. Set up a breakpoint and a watch so that you can check that all the values are what they should be in apply_surface perhaps.
I realized the moment I fell into the fissure that the book would not be destroyed as I had planned.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Character Animation problem, please help

Post by dandymcgee »

If you're still having problems, post your mario.png image and Timer_class.h file and I'll try my hand at debugging it.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
andrew
Chaos Rift Regular
Chaos Rift Regular
Posts: 121
Joined: Mon Dec 08, 2008 2:12 pm

Re: Character Animation problem, please help

Post by andrew »

Part of the problem is here:

Code: Select all

    SDL_Rect clipsRight[3];

    clipsRight[ 3 ].x = PLAYER_WIDTH * 3;
    clipsRight[ 3 ].y = PLAYER_HEIGHT;
    clipsRight[ 3 ].w = PLAYER_WIDTH;
    clipsRight[ 3 ].h = PLAYER_HEIGHT;
clipsRight doesn't have enough elements to access a 4th element.

Don't forget to count array elements from 0 and not 1. ;)
Post Reply