使瓷砖之间没有边框的最佳方法?

Best way to make tiles not have borders in between them?

本文关键字:最佳 方法 边框 之间      更新时间:2023-10-16

所以我正在尝试使用SFML和Visual c ++制作游戏。目前,对于可能彼此接壤的瓷砖的每个组合,我都有不同的精灵,在某些侧面没有边框,然后使用嵌套的 if 语句来检查要使用的精灵。但是,这会减慢我的游戏速度,以至于我什至无法玩它。有没有更好的方法可以做到这一点?

这是我的代码:

//Render tiles
for (int i = 0; i < blockX.size(); i++) {
block.setPosition(float(blockX[i]), float(blockY[i]));
if (blockType[i] == "metal") {
//if block is metal tile
block.setTexture(metalBlockSingle);
if (doesBlockExist(blockX[i] + 20, blockY[i])) {
//if block is to right
if (doesBlockExist(blockX[i], blockY[i] + 20)) {
//if block is below
if (doesBlockExist(blockX[i] - 20, blockY[i])) {
//if block is to left
if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockCenter);
}
else {
block.setTexture(metalBlockBottomRightLeft);
}
}
else if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTopBottomRight);
}
else {
//if block is neither above nor to left
block.setTexture(metalBlockBottomRight);
}
}
else if (doesBlockExist(blockX[i] - 20, blockY[i])) {
//if block is to left
if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTopRightLeft);
}
else {
block.setTexture(metalBlockRightLeft);
}
}
else if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTopRight);
}
else {
//if block is only right
block.setTexture(metalBlockRight);
}
}
else if (doesBlockExist(blockX[i], blockY[i] + 20)) {
//if block is below
if (doesBlockExist(blockX[i] - 20, blockY[i])) {
//if block is to left
if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTopBottomLeft);
}
else {
//if block is not above
block.setTexture(metalBlockBottomLeft);
}
}
else {
//if block is not to left
if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTopBottom);
}
else {
//if metal block is not above
block.setTexture(metalBlockBottom);
}
}
}
else if (doesBlockExist(blockX[i] - 20, blockY[i])) {
//if block is to left
if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTopLeft);
}
else {
block.setTexture(metalBlockLeft);
}
}
else if (doesBlockExist(blockX[i], blockY[i] - 20)) {
//if block is above
block.setTexture(metalBlockTop);
}
}
window.draw(block);
}

编辑:这是"doesBlockExist"函数的代码:

bool doesBlockExist(int x, int y) {
bool returnVal =  false;
int findX = int(round(x / 20) * 20);
int findY = int(round(y / 20) * 20);
for (int i = 0; i < blockX.size(); i++) {
if (blockX[i] == findX && blockY[i] == findY) {
returnVal = true;
}
}
return(returnVal);
return(true);
}

每当像这样嵌套if语句(高圈复杂度(时,你应该立即停下来考虑其他设计。大型嵌套 if 语句不仅容易包含错误,而且不可能一目了然地真正理解。

更好的设计可以从将事物拆分为多个功能开始,每个功能都有自己的单一职责。其他步骤包括认真思考逻辑以找到消除条件的方法,即当情况X成立时,Y随之而来,无需进一步检查。还有一些情况是,您可以构造一个对象,而不是使用 if 语句,该对象在构造后将具有正确的设置。

至于代码的优化:

  • 使用精灵表,不要使用 x 数量的纹理。setTextureRect基本上是一个免费功能,而一直切换纹理可能会导致性能问题。
  • 如果你保持doesBlockExist的实现,至少确保在找到块时返回正确,不要继续迭代。这意味着,在 if 主体内部只需写入return true,然后在循环之后写入return false并删除变量 returnVal。
  • 但是,doesBlockExist功能似乎实现得很差。它到底检查什么?你只是检查周围的瓷砖吗?如果是这样,那么您可以轻松地检查周围的 8 个磁贴,而不需要遍历所有磁贴。
  • 由于您经常调用doesBlockExist,因此您必须考虑,是否不可能只调用一次并一次报告周围的所有磁贴。
  • int(round(x / 20) * 20);由于 x 已经intx / 20无论如何都是整数除法,所以没有理由四舍五入。

或者,您可以使用像 Tiled 这样的磁贴编辑器,并在设计关卡时相应地放置磁贴,然后加载磁贴地图。

至于标题中的问题,我不知道你说的边界是什么意思。