i am creating 2d graphical game with SDL.but i got a problem with setting artificial intelligence character on it.my enemy/AI character always following player character around scrolling screen/camera area where my player character walk.i mean the enemy did not walk in his own coordinate and perimeter instead of following my character walking everywhere.
this is the code :
#include "SDL.h"#include "SDL_image.h"#include <string>//Screen attributesconst int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;const int SCREEN_BPP = 32;//The frames per secondconst int FRAMES_PER_SECOND = 5;//The dimenstions of the stick figureconst int FOO_WIDTH = 80;const int FOO_HEIGHT = 160;const int NANDA_WIDTH = 80;const int NANDA_HEIGHT = 160;const int LEVEL_WIDTH = 1900;const int LEVEL_HEIGHT = 960;//The direction status of the stick figureconst int FOO_RIGHT = 0;const int FOO_LEFT = 1;const int FOO_FRONT = 2;const int FOO_BACK = 3;const int NANDA_RIGHT = 0;const int NANDA_LEFT = 1;const int NANDA_FRONT = 2;const int NANDA_BACK = 3;//The surfacesSDL_Surface *foo = NULL;SDL_Surface *enemy = NULL;SDL_Surface *background = NULL;SDL_Surface *screen = NULL;//The event structureSDL_Event event;//The areas of the sprite sheetSDL_Rect clipsRight[ 2 ];SDL_Rect clipsLeft[ 2 ];SDL_Rect clipsFront[ 2 ];SDL_Rect clipsBack[ 2 ];SDL_Rect camera = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};SDL_Rect wall;SDL_Rect tree;SDL_Rect treef;SDL_Rect treeb;//The stick figureclass Foo{ private: //The offset SDL_Rect box; //Its rate of movement int xVel, yVel; //Its current frame int frame; //Its animation status int status; public: //Initializes the variables Foo(); //Handles input void handle_events(); //Moves the stick figure void move(); //Shows the stick figure void show(); void set_camera();};class Enemy{ private: SDL_Rect musuh; int xVel, yVel; int frame; int status; public: Enemy(); void move(); void show();};//The timerclass 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();};SDL_Surface *load_image( std::string filename ){ //The image that's loaded SDL_Surface* loadedImage = NULL; //The optimized surface that will be used SDL_Surface* optimizedImage = NULL; //Load the image loadedImage = IMG_Load( filename.c_str() ); //If the image loaded if( loadedImage != NULL ) { //Create an optimized surface optimizedImage = SDL_DisplayFormat( loadedImage ); //Free the old surface SDL_FreeSurface( loadedImage ); //If the surface was optimized if( optimizedImage != NULL ) { Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ); //Color key surface SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) ); } } //Return the optimized surface return optimizedImage;}void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL ){ //Holds offsets SDL_Rect offset; //Get offsets offset.x = x; offset.y = y; //Blit SDL_BlitSurface( source, clip, destination, &offset );}void set_clips(){ //Clip the sprites clipsRight[ 0 ].x = 0; clipsRight[ 0 ].y = 480; clipsRight[ 0 ].w = FOO_WIDTH; clipsRight[ 0 ].h = FOO_HEIGHT; clipsRight[ 1 ].x = FOO_WIDTH; clipsRight[ 1 ].y = 480; clipsRight[ 1 ].w = FOO_WIDTH; clipsRight[ 1 ].h = FOO_HEIGHT; clipsLeft[ 0 ].x = 0; clipsLeft[ 0 ].y = 320; clipsLeft[ 0 ].w = FOO_WIDTH; clipsLeft[ 0 ].h = FOO_HEIGHT; clipsLeft[ 1 ].x = FOO_WIDTH; clipsLeft[ 1 ].y = 320; clipsLeft[ 1 ].w = FOO_WIDTH; clipsLeft[ 1 ].h = FOO_HEIGHT; clipsBack[ 0 ].x = 0; clipsBack[ 0 ].y = 160; clipsBack[ 0 ].w = FOO_WIDTH; clipsBack[ 0 ].h = FOO_HEIGHT; clipsBack[ 1 ].x = FOO_WIDTH; clipsBack[ 1 ].y = 160; clipsBack[ 1 ].w = FOO_WIDTH; clipsBack[ 1 ].h = FOO_HEIGHT; clipsFront[ 0 ].x = 0; clipsFront[ 0 ].y = 0; clipsFront[ 0 ].w = FOO_WIDTH; clipsFront[ 0 ].h = FOO_HEIGHT; clipsFront[ 1 ].x = FOO_WIDTH; clipsFront[ 1 ].y = 0; clipsFront[ 1 ].w = FOO_WIDTH; clipsFront[ 1 ].h = FOO_HEIGHT;}bool check_collision( SDL_Rect A, SDL_Rect B ){ //The sides of the rectangles int leftA, leftB; int rightA, rightB; int topA, topB; int bottomA, bottomB; //Calculate the sides of rect A leftA = A.x; rightA = A.x + A.w; topA = A.y; bottomA = A.y + A.h; //Calculate the sides of rect B leftB = B.x; rightB = B.x + B.w; topB = B.y; bottomB = B.y + B.h; //If any of the sides from A are outside of B if( bottomA <= topB ) { return false; } if( topA >= bottomB ) { return false; } if( rightA <= leftB ) { return false; } if( leftA >= rightB ) { return false; } //If none of the sides from A are outside B return true;}bool init(){ //Initialize all SDL subsystems if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) { return false; } //Set up the screen screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE ); //If there was an error in setting up the screen if( screen == NULL ) { return false; } //Set the window caption SDL_WM_SetCaption( "Animation Test", NULL ); //If everything initialized fine return true;}bool load_files(){ //Load the sprite sheet foo = load_image( "player.png" ); enemy = load_image( "enemy.png" ); background = load_image( "ground.png" ); //If everything loaded fine return true;}void clean_up(){ //Free the surface SDL_FreeSurface( background ); SDL_FreeSurface( foo ); SDL_FreeSurface( enemy ); //Quit SDL SDL_Quit();}Foo::Foo(){ //Initialize movement variables box.x = 0; box.y = 250; box.w = FOO_WIDTH; box.h = FOO_HEIGHT; xVel = 0; yVel = 0; //Initialize animation variables frame = 0; status = FOO_RIGHT;}Enemy::Enemy(){ musuh.x = 100; musuh.y = 200; musuh.w = NANDA_WIDTH; musuh.h = NANDA_HEIGHT; xVel = 0; yVel = 0; frame = 1; status = NANDA_RIGHT;}void Foo::handle_events(){ //If a key was pressed if( event.type == SDL_KEYDOWN ) { //Set the velocity switch( event.key.keysym.sym ) { case SDLK_RIGHT: xVel += FOO_WIDTH / 2; break; case SDLK_LEFT: xVel -= FOO_WIDTH / 2; break; case SDLK_UP: yVel -= FOO_HEIGHT / 2; break; case SDLK_DOWN: yVel += FOO_HEIGHT / 2; break; } } //If a key was released else if( event.type == SDL_KEYUP ) { //Set the velocity switch( event.key.keysym.sym ) { case SDLK_RIGHT: xVel -= FOO_WIDTH / 2; break; case SDLK_LEFT: xVel += FOO_WIDTH / 2; break; case SDLK_UP: yVel += FOO_HEIGHT / 2; break; case SDLK_DOWN: yVel -= FOO_HEIGHT / 2; break; } }}void Foo::move(){ //Move box.x += xVel; //Keep the stick figure in bounds if( ( box.x < 0 ) || ( box.x + FOO_HEIGHT > LEVEL_HEIGHT ) || ( check_collision( box, wall ) ) || ( check_collision( box, tree ) ) || ( check_collision( box, treef ) ) || ( check_collision( box, treeb ) ) ) { box.x -= xVel; } box.y += yVel; if( ( box.y < 0 ) || ( box.y + FOO_HEIGHT > LEVEL_HEIGHT ) || ( check_collision( box, wall ) ) || ( check_collision( box, tree ) ) || ( check_collision( box, treef ) ) || ( check_collision( box, treeb ) ) ) { box.y -= yVel; }}void Enemy::move(){ musuh.x += xVel; if(musuh.x == 100 AND musuh.y == 200) { xVel += NANDA_WIDTH / 2; } if(musuh.x == 400 AND musuh.y == 200) { xVel -= NANDA_WIDTH / 2; }}void Foo::show(){ //If Foo is moving left if( xVel < 0 ) { //Set the animation to left status = FOO_LEFT; //Move to the next frame in the animation frame++; } //If Foo is moving right else if( xVel > 0 ) { //Set the animation to right status = FOO_RIGHT; //Move to the next frame in the animation frame++; } else if(yVel > 0) { status = FOO_FRONT; frame++; } else if(yVel < 0) { status = FOO_BACK; frame++; } //If Foo standing else { //Restart the animation frame = 0; } //Loop the animation if( frame >= 2 ) { frame = 0; } //Show the stick figure if( status == FOO_RIGHT ) { apply_surface( box.x - camera.x, box.y - camera.y, foo, screen, &clipsRight[ frame ] ); } else if( status == FOO_LEFT ) { apply_surface( box.x - camera.x, box.y - camera.y, foo, screen, &clipsLeft[ frame ] ); } else if( status == FOO_FRONT ) { apply_surface( box.x - camera.x, box.y - camera.y, foo, screen, &clipsFront[ frame ] ); } else if( status == FOO_BACK ) { apply_surface( box.x - camera.x, box.y - camera.y, foo, screen, &clipsBack[ frame ] ); }}void Enemy::show(){ if( xVel < 0 ) { status = NANDA_LEFT; frame++; } else if( xVel > 0 ) { status = NANDA_RIGHT; frame++; } if( frame >= 2 ) { frame = 0; } if( status == NANDA_RIGHT ) { apply_surface( musuh.x, musuh.y, enemy, screen, &clipsRight[ frame ] ); } else if( status == NANDA_LEFT ) { apply_surface( musuh.x, musuh.y, enemy, screen, &clipsLeft[ frame ] ); }}void Foo::set_camera(){ camera.x = (box.x + FOO_WIDTH/2) - SCREEN_WIDTH/2; camera.y = (box.y + FOO_HEIGHT/2) - SCREEN_HEIGHT/2; //Keep the camera in bounds. if( camera.x < 0 ) { camera.x = 0; } if( camera.y < 0 ) { camera.y = 0; } if( camera.x > LEVEL_WIDTH - camera.w ) { camera.x = LEVEL_WIDTH - camera.w; } if( camera.y > LEVEL_HEIGHT - camera.h ) { camera.y = LEVEL_HEIGHT - camera.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;}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; }}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;}bool Timer::is_started(){ return started;}bool Timer::is_paused(){ return paused;}int main( int argc, char* args[] ){ //Quit flag bool quit = false; //Initialize if( init() == false ) { return 1; } //Load the files if( load_files() == false ) { return 1; } wall.x = 800; wall.y = 30; wall.w = 60; wall.h = 200; tree.x = 400; tree.y = 50; tree.w = 60; tree.h = 200; treef.x = 1400; treef.y = 200; treef.w = 120; treef.h = 500; treeb.x = 1500; treeb.y = 500; treeb.w = 400; treeb.h = 150; //Clip the sprite sheet set_clips(); //The frame rate regulator Timer fps; //The stick figure Foo walk; Enemy lawan; //While the user hasn't quit while( quit == false ) { //Start the frame timer fps.start(); //While there's events to handle while( SDL_PollEvent( &event ) ) { //Handle events for the stick figure walk.handle_events(); //If the user has Xed out the window if( event.type == SDL_QUIT ) { //Quit the program quit = true; } } //Move the stick figure walk.move(); lawan.move(); walk.set_camera(); //Fill the screen white SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); //Show the stick figure on the screen apply_surface( 0, 0, background, screen, &camera ); walk.show(); lawan.show(); //Update the screen if( SDL_Flip( screen ) == -1 ) { return 1; } //Cap the frame rate if( fps.get_ticks() < 500 / FRAMES_PER_SECOND ) { SDL_Delay( ( 700 / FRAMES_PER_SECOND ) - fps.get_ticks() ); } } //Clean up clean_up(); return 0;}
there are two class : Foo class for player character and Enemy class for enemy character.look at int main section,i am not set camera function on enemy class but why the enemy character always follow the player scrolling camera,strange.how to fixed it?
[edit: broke a couple of really long lines to make it fit in browser - IF]
[Edited by - InnocuousFox on December 1, 2010 12:13:39 PM]