【问题标题】:Checkers game in SDLSDL 中的跳棋游戏
【发布时间】:2014-03-08 15:51:15
【问题描述】:

我正在尝试制作跳棋游戏,而 atm 我正在使用 SDL 做界面,但我只是在学习 C 和 SDL,如何移动我添加到屏幕的表面?我希望它尽可能简单,只需从 X 中移除并在 Y 上显示,如何移除表面以使其出现在屏幕上的另一个位置?这是我的代码:

#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;
}

如您所见,我在“inserePeca”上添加了一个块,我想在创建后移动它

【问题讨论】:

    标签: c sdl game-engine


    【解决方案1】:

    屏幕缓冲区不会将您在其上绘制的所有内容作为单独的项目保存——它只是保存所有绘制操作的最终结果。所以,你不能只画背景,然后在上面画一块,然后四处移动——你需要重新绘制屏幕受影响的部分并进行所需的更改。

    你仍然有碎片的图像,你仍然有背景图像;移动已绘制的块的方法是通过再次blitting 将背景恢复到旧位置,然后在新位置blit 块。不过,无需重新绘制整个屏幕和所有部分,您可以只绘制更改的区域:只对背景的一部分进行 blit 以擦除旧正方形,然后将其 blit 到新正方形上。

    以下函数类似于您的apply_surface() 函数,但不是将整个源图像复制到目标的给定坐标,而是从源图像的给定坐标复制给定宽度和高度的区域到目的地的相同坐标。然后可以使用它来恢复屏幕一小部分的背景。

    /* 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 );
    }
    

    因此,如果您的正方形是 50x50,并且您需要将一块从 (120, 40) 的正方形移动到 (170, 90) 的正方形,您可以执行以下操作:

    /* 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多