我正在使用SDL库制作2D游戏。
我试图一遍又一遍地绘制每一帧的地图,因为我正在根据玩家的移动来移动地图,以实现相机跟随玩家的错觉。
因此,基本上,如果玩家移动了,我将移动所有块(这两个,玩家移动和更新块的位置,在单独的线程中处理),然后在主线程中再次渲染地图纹理。 / p>
尽管,实际上每帧绘制所有块的效率并不高,并且滞后于窗口渲染,所以我要做的是制作另一个线程,这将创建一个空白纹理,可以在此处渲染块。
问题是: 没有渲染器,是否可以这样做?将所有块绘制为新纹理而没有实际卡住绘制窗口的主渲染器,并防止每帧遍历所有块?
这是遍历地图块并将其绘制到新纹理的代码:
SDL_Texture* GraphicsDrawer::drawMap() {
map = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, WINDOW_WIDTH, WINDOW_HEIGHT);
SDL_SetTextureBlendMode(map, SDL_BLENDMODE_BLEND); // set texture to be transparent
SDL_SetRenderTarget(renderer, map);
for (Block block : blocks) {
std::cout << block.getTexture() << std::endl;
SDL_RenderCopy(renderer, block.getTexture(), NULL, &block.getPosition());
SDL_RenderPresent(renderer);
}
SDL_SetRenderTarget(renderer, NULL);
return map;
}
这是将纹理绘制到窗口的代码:
void Game::render() {
SDL_RenderClear(renderer);
//map
SDL_RenderCopy(renderer, map, NULL, NULL);
//player
SDL_RenderCopy(renderer, player->getAnimation(player->getFlipImageFlag()), NULL, &player->getPosition());
SDL_SetRenderDrawColor(renderer, BG_R, BG_G, BG_B, BG_A);
SDL_RenderPresent(renderer);
}
答案 0 :(得分:0)
如果我了解您的要求,那么您每次只想更新地图上的某些街区/瓷砖吗?除非将地图纹理分成几部分,否则这是不可能的,这可能会产生比您节省的更多开销。您不能仅SDL_RenderClearClear清除部分纹理而没有一些潜在的不良副作用。
我要做的是将地图纹理分解为几层(map_floors,map_walls等)并缓存每一层。因此,与其在每一帧都调用GraphicsDrawer :: drawMap(),不如在层发生变化的帧上调用它。因此,如果NPC移动,则仅重绘具有NPC的图层。您仍然会每帧调用SDL_RenderCopy(),但是不必每帧都重新生成每一层的纹理。