gpt4 book ai didi

c++ - 使用 sfml 绘制瓦片 map

转载 作者:行者123 更新时间:2023-11-30 01:26:49 25 4
gpt4 key购买 nike

所以,我一直在尝试创建一个“ map ”类来处理我在窗口上绘制的瓷砖 map ,但我在将所有瓷砖绘制到屏幕上时遇到了问题。

这是我的问题:假设我有一个 10*10 block 的 map ,有 5 个层,总计为 10*10*5 = 500 个 block (当然在实时情况下, block 数可能是原来的 10 倍会更糟)...它存储在 3d 数组 [layer][row][col] 或 chars 中,每个 char 代表我的 Sprite 图 block 上的索引所以我创建了一个“SpriteSheet”类来处理我的 Sprite 表并通过索引从表中获取每个 Sprite :spriteSheet->GetSubSprite(idx)。所以最后我有类似 Draw(spriteSheet->GetSubSprite((int)mapArray[i][j][k])) 应该为每个 Sprite 调用的东西,每个游戏循环所以让假设我的游戏以 60 fps 运行并且我有 500 个方 block 要绘制:游戏旨在每秒绘制 500*60 = 30,000(!) 个方 block ...

所以你可以看到我在这里遇到了一些问题......?任何人都知道如何在速度方面充分改进这一点? (当然,对我当前的结构进行任何形式的改进都是非常幸运的)。

所以,以防万一这是我的 SpriteSheet.cpp 和我的 Map.cpp 文件,我知道我有很多设计错误,但请关注我的问题,设计远未完成。


#include "Map.h"

sz::Map::Map(std::string path, std::string name, std::string image) : Tmx::Map() {
ParseFile(path);

if (HasError()) {
printf("error code: %d\n", GetErrorCode());
printf("error text: %s\n", GetErrorText().c_str());

system("PAUSE");
}
else {
mapArray = new unsigned char**[GetNumLayers()];
for(int i = 0; i < GetNumLayers(); i++) {
mapArray[i] = new unsigned char*[GetLayer(i)->GetHeight()];
for(int j=0; j<GetLayer(i)->GetHeight(); j++) {
mapArray[i][j] = new unsigned char[GetLayer(i)->GetWidth()];
// [layer][row][col]
}
}
//load the array
for (int i = 0; i < GetNumLayers(); ++i) {

// Get a layer.
const Tmx::Layer *layer = GetLayer(i);

for (int y = 0; y < layer->GetHeight(); ++y) {
for (int x = 0; x < layer->GetWidth(); ++x) {
// Get a tile global id.
mapArray[i][x][y] = (char)layer->GetTileGid(x, y);
//printf("%3d", mapArray[i][x][y]);
/* need to fix later on
/****************************
// Find a tileset for that id.
const Tmx::Tileset *tileset = FindTileset(layer->GetTileGid(x, y));
if (layer->IsTileFlippedHorizontally(x, y)){
printf("h");
}else{
printf(" ");
}
if (layer->IsTileFlippedVertically(x, y)){
printf("v");
}else{
printf(" ");
}
if (layer->IsTileFlippedDiagonally(x, y)){
printf("d ");
} else {
printf(" ");
}
****************************/
}
//printf("\n");
}
//printf("\n\n");
}
}
tiles = new sz::SpriteSheet(name, image, 33, 33);
}

void sz::Map::Draw(sf::RenderWindow *rw) {
// dont know what to do T_T
}

#include "SpriteSheet.h"

sz::SpriteSheet::SpriteSheet(std::string name, std::string path, int tileW, int tileH) : sz::GameObject(name, path) {
this->tileH = tileH;
this->tileW = tileW;
numOfTiles = ((this->GetImage()->GetHeight()) / tileH) * ((this->GetImage()->GetWidth()) / tileW);
}

int sz::SpriteSheet::GetTileWidth() { return tileW; }
int sz::SpriteSheet::GetTileHeight() { return tileH; }
int sz::SpriteSheet::GetNumOfTiles() { return numOfTiles; }

sf::Sprite sz::SpriteSheet::GetSubSprite(int idx) {
if(idx < 1 || idx > numOfTiles) {
std::cout << "Incorrect index!" << std::endl;
// need return value
}

int row=0, col=0, tilesEachRow = (GetImage()->GetWidth() / tileW);

while(idx > tilesEachRow) {
idx -= tilesEachRow;
col++;
}
row = idx-1;

sz::GameObject *sub = new sz::GameObject(name, path);
/*std::cout << "tileW: " << tileW << std::endl;
std::cout << "tileH: " << tileH << std::endl;
std::cout << "row: " << row << std::endl;
std::cout << "col: " << col << std::endl;
std::cout << "tiles per row: " << tilesEachRow << std::endl;
std::cout << "(" << row*tileW << ", " << col*tileH << ", " << (row+1)*tileW << ", " << (col+1)*tileH << ")" << std::endl;*/
sub->SetSubRect(sf::IntRect(row*tileW, col*tileH, (row+1)*tileW, (col+1)*tileH));
return *sub;
}

最佳答案

您是否真的遇到任何速度问题?虽然每秒 30,000 个图 block 听起来很多,但就使用更现代的 PC 进行计算而言,这可能不是什么大问题。

话虽如此,如果输出单个图 block 有一定的相关开销(例如,输出 2 个图 block 比输出 1 个图 block 需要更长的时间,输出两个图 block 的大小合并)。我并不自称对 SFML 了解太多,但我假设存在某种表面/ Canvas 系统。您可以做的是编写一个方法,一次将静态图 block 绘制到表面。然后游戏每一帧输出一次这个表面。这意味着无需以逐 block 方式重复输出每一帧的 block 。您只需输出所有静态图 block 组合的单个图像。

我想您甚至可以动态地使用这个系统。如果某个图 block 需要更改,只需用更新后的图 block 数据覆盖该表面的相关部分即可。换句话说,您将保留所有静态内容,只针对需要更新的区域。

关于c++ - 使用 sfml 绘制瓦片 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9659234/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com