Advertisement

Artificial Intelligence Problem With SDL?

Started by November 30, 2010 09:23 PM
4 comments, last by Erik Rufelt 13 years, 11 months ago
any SDL expert please help

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]
If you think you have an AI problem with SDL, there's something very wrong with how you are thinking about your program. SDL is a library that allows access to the hardware, AI is something that deals with the logic of your game, and the two of them should never be in the same sentence. You should have a game state that is independent of the particulars of how you render your world, and the AI should only have to deal with that.

I was too lazy to read your question when you posted it on the Graphics Programming and Theory forum, and I can't be bother reading it now either.

Advertisement
frankly i don't get with your meaning

yes i know SDL library and i prefer like it rather than OpenGL because it's relatively easy to use
what do you mean with game state.shall i use this to make AI movement?
Quote: Original post by Alvin31
frankly i don't get with your meaning
I think what he's getting at is that SDL and AI really have nothing to do with one another. If it really is an AI-related problem you have, then it's not an SDL expert that you need.

That said, from reading your post it sounds like more of a rendering and/or program logic problem than an AI problem; if that is the case, this probably isn't the best forum for the question.
To use a metaphor, you are asking about the steering problem you are having with the engine in your car.

Dave Mark - President and Lead Designer of Intrinsic Algorithm LLC
Professional consultant on game AI, mathematical modeling, simulation modeling
Co-founder and 10 year advisor of the GDC AI Summit
Author of the book, Behavioral Mathematics for Game AI
Blogs I write:
IA News - What's happening at IA | IA on AI - AI news and notes | Post-Play'em - Observations on AI of games I play

"Reducing the world to mathematical equations!"

I think you need to add an Enemy::set_camera and use musuh.x - camera.x when calling apply_surface in Enemy::show.

This topic is closed to new replies.

Advertisement