1

i'm trying to make a checkers game and atm i'm doing the interface with SDL, but i'm just learning C and SDL, how can I move a surface I added to the screen ? I want it the simplest as possible, just remove from X and show on Y, how do I remove a surface to make it appear on another place on the screen ? here is my code:

#include "SDL.h"
#define BRANCA 2
#define PRETA 1
#define DAMA 2
#define NORMAL 1

//The attributes of the screen
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The surfaces that will be used
SDL_Surface *pecaPreta = NULL;
SDL_Surface *pecaBranca = NULL;
SDL_Surface *pecaDamaPreta = NULL;
SDL_Surface *pecaDamaBranca = NULL;
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;

SDL_Surface *load_image(char * filename )
{
    SDL_Surface* loadedImage = NULL;
    SDL_Surface* optimizedImage = NULL;
    loadedImage = SDL_LoadBMP(filename);

    if( loadedImage != NULL )
    {
        optimizedImage = SDL_DisplayFormat( loadedImage );
        SDL_FreeSurface( loadedImage );

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

    return optimizedImage;
}

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

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

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

void inserePeca(int tipo, int posX, int posY, int cor)
{
    switch(cor)
    {
    case 1:
        switch (tipo)
        {
        case 1:
            apply_surface(posX, posY, pecaPreta, screen);
        break;
        case 2:
            apply_surface(posX, posY, pecaDamaPreta, screen);
        break;  
        }
    break;
    case 2:
        switch (tipo)
        {
        case 1:
            apply_surface(posX, posY, pecaBranca, screen);
        break;
        case 2:
            apply_surface(posX, posY, pecaDamaBranca, screen);
        break;  
        }
    break;
    }
}

int main()
{
    int quit = 0;
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return 1;
    }

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

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

    //Set the window caption
    SDL_WM_SetCaption( "Jogo de Damas 0.1b", NULL );

    //Load the images
    pecaPreta = load_image( "pecapreta.bmp" );
    pecaBranca = load_image("pecabranca.bmp");
    pecaDamaPreta = load_image("pecadamapreta.bmp");
    pecaDamaBranca = load_image("pecadamabranca.bmp");
    background = load_image( "tabuleiro.bmp" );

    //Apply the background to the screen
    apply_surface( 0, 0, background, screen );

    inserePeca(DAMA, 0,0, BRANCA);
    inserePeca(NORMAL, 80,0, PRETA);

    //Update the screen
    if( SDL_Flip( screen ) == -1 )
    {
        return 1;
    }
    while( quit == 0 )
    {
        //While there's an event to handle
        while( SDL_PollEvent( &event ) )
        {
            //If the user has Xed out the window
            if( event.type == SDL_QUIT )
            {
                //Quit the program
                quit = -1;
            }
        }
    }

    //Free the surfaces
    SDL_FreeSurface( pecaPreta );
    SDL_FreeSurface( background );

    //Quit SDL
    SDL_Quit();

    return 0;
}

as you can see I add a block on "inserePeca", I want to move it after I create it

tshepang
  • 12,111
  • 21
  • 91
  • 136

1 Answers1

0

The buffer for the screen doesn't keep all the things you draw on it as separate items -- it just holds the end result of all the drawing operations. So, you can't just draw the background, then draw a piece on it, then move the piece around -- you need to redraw the affected parts of the screen with the required changes.

You still have the images of the pieces, and you still have the background image; the way to move a piece you've drawn is simply to restore the background to the old position by blitting it again, and then blit the piece in the new position. Rather than drawing the whole screen and all the pieces over again, though, you can just draw the changed areas: blit just a part of the background to erase the old square, and then blit the piece onto the new square.

The following function is similar to your apply_surface() function, but instead of copying the whole source image to the the given coordinates of the destination, it copies a region of a given width and height from the given coordinates of the source image to the same coordinates of the destination. This can then be used to restore the background for a small part of the screen.

/* Blit a region from src to the corresponding region in dest.  Uses the same
 * x and y coordinates for the regions in both src and dest.  w and h give the
 * width and height of the region, respectively.
 */
void erase_rect( int x, int y, int w, int h,  SDL_Surface *src, SDL_Surface *dest)
{
  SDL_Rect offset;
  offset.x = x;
  offset.y = y;
  offset.w = w;
  offset.h = h;
  SDL_BlitSurface( src, &offset, dest, &offset );
}

So if your squares are 50x50, and you need to move a piece from a square at (120, 40) to the square at (170, 90), you could do something like the following:

/* erase old 50x50 square at (120,40) (to background image) */
erase_rect( 120, 40, 50, 50, background, screen );
/* draw piece at new position of (170,90) */
inserePeca(NORMAL, 170, 90, PRETA);
Dmitri
  • 9,175
  • 2
  • 27
  • 34