将表面涂在另一个表面上(SDL2,C ++,VS2015)

时间:2015-12-29 16:34:20

标签: c++ sdl-2 tile surface blit

我正在为学校做一个小游戏。我在屏幕上平铺了一个图像,但每次我的角色移动时我都要重新平铺它(平铺在角色后面,因为它是一个网格,角色在单元格中移动)。我尝试将所有东西都平铺在不同的表面上,然后将该表面涂抹在我的屏幕表面上,以避免每次都进行爬行,并节省处理时间。 它没有真正起作用,就像我平铺的表面忘记了平铺在它上面的东西。它没有错误,它只是不显示窗口表面上的平铺表面。

这是我的代码(至少是相关部分)

void postaviTiles() {

SDL_BlitSurface(cell, NULL, polje, &offsetcell); //cell

for (int i = 0; i < 89; i++) {
    SDL_Delay(5);
    if (offsetcell.x < 450) {
        offsetcell.x += 50;
        SDL_BlitSurface(cell, NULL, polje, &offsetcell);
    }

    else {
        offsetcell.x = 9;
        offsetcell.y += 50;
        SDL_BlitSurface(cell, NULL, polje, &offsetcell);
    }
    SDL_UpdateWindowSurface(okno);
}

poljezrisano = true;
}

//--------------------------------------------------------------//

void tileCells() {

if (poljezrisano == false) {
    postaviTiles();}

SDL_BlitSurface(polje, NULL, oknoSurface, NULL); //cell
SDL_UpdateWindowSurface(okno);
}

//--------------------------------------------------------------//

值得一提的是,每次拼贴它都可以正常工作,但是我想要将其平铺一次,将其放在表面上,然后将该表面涂在我的屏幕表面上。

P.S。:很抱歉大多数变量和函数名称不是英文

2 个答案:

答案 0 :(得分:1)

SDL_BlitSurface接收源表面,该源表面的剪辑,然后是目标表面以及要显示(blit)源的位置。

传递给SDL_BlitSurface的最后一个参数忽略了宽度和高度,它只需要x和y。

以下是documentation

的引用
  

srcrect中的宽度和高度决定了复制矩形的大小。仅在dstrect中使用该位置(忽略宽度和高度)。

该功能的原型:

int SDL_BlitSurface(SDL_Surface*    src,
                const SDL_Rect* srcrect,
                SDL_Surface*    dst,
                SDL_Rect*       dstrect)

要记住这一点,不确定这是否适用于您的案例,因为您的变量名称不是英语。

但基本上就是这一行:

SDL_BlitSurface(cell, NULL, polje, &offsetcell);

您告诉SDL您希望将所有单元格放在polje中位于offsetcell.x和offsetcell.y的位置,其中包含cell.w的宽度和cell.h的高度。

如果你想使用offsetcell的宽度和高度将单元格放在polje中,那么你将不得不使用另一个blit函数,即SDL_BlitScaled

以下是我在网格(地图)中blit tile的方法。

SDL_Surface* grid; // assuming this is the new grid surface that holds the blited tiles
SDL_Surface* tile; // assuming this is a single tile of width 50, height 50
SDL_Surface* windowSurface;
SDL_Window* window;

int TileWidth = 50;
int TileHeight = 50;
int NumTiles = 90;
int TileColumns = 450 / TileWidth; // = 9, so we have a grid of 9X10

bool isFillGridTiles = false;

void FillGridTiles()
{
    for (int i = 0;i < NumTiles; i++)
    {
        auto y = i / TileColumns; // divide to get the y position and...
        auto x = i % TileColumns; // the remainder is the x position inside the grid

        SDL_Rect srcClip;
        srcClip.x = 0;
        srcClip.y = 0;
        srcClip.w = TileWidth;
        srcClip.h = TileHeight;

        SDL_Rect dstClip;
        dstClip.x = x * TileWidth;
        dstClip.y = y * TileHeight;
        dstClip.w = TileWidth;
        dstClip.h = TileHeight;

        SDL_BlitSurface(tile, &srcClip, grid, &dstClip); //since we have the same width and height, we can use SDL_BlitSurface instead of SDL_BlitScaled

    }

    isFillGridTiles = true;
}

void BlitOnScreen()
{
    if(!isFillGridTiles)
    {
        FillGridTiles();
    }

    SDL_BlitSurface(grid, NULL, windowSurface, NULL);
    SDL_UpdateWindowSurface(window);
}

答案 1 :(得分:1)

不确定代码是否已完成发布,但似乎您没有初始化offsetcell。这符合没有任何表现的症状。 offsetcell的显式定义可能比您提供的增量方法更好。例如:

for( offsetcell.x = 0; offsetcell.x < 450; offsetcell.x += 50) {
    for( offsetcell.y = 0; offsetcell.y < 450; offsetcell.y += 50) {
        ...
    }
}