我正在开发一款游戏(并且已经问过几个问题),现在我还有一个问题要问你们。映射分支平铺路径
这个游戏中的关卡格式被设置为Uint16(我使用SDL)的tilemap,它们是tilemapData结构数组中的索引。 tilemapData结构的一个位是isConductive位/布尔值。
该位的使用基本上是创建将各种对象连接成一个“powerNet”的路径。我有以下关于当前方法的一些代码(这工作,但我将介绍为什么我真的很讨厌后话)
void findSetPoweredObjects(unsigned long x, unsigned long y, powerNetInfo * powerNet) {
//Look for poweredObjs on this tile and set their powerNet to the given powernet
for (int i = 0; i < level->numChunks[CHUNKTYPE_POWEREDDEF]; i++)
if (level->poweredObjects[i]->position[0] == x && level->poweredObjects[i]->position[1] == y)
level->poweredObjects[i]->powerNet = powerNet, powerNet->objectsInNet++;
}
void recursiveCheckTile(bool * isWalked, powerNetInfo * powerNet, unsigned long x, unsigned long y, tilemapData * levelMap) {
//If out of bounds, return
if (x < 0 || y < 0 || x >= level->mapDimensions[0] || y >= level->mapDimensions[1]) return;
//If tile already walked, return
if (isWalked[x + (y * level->mapDimensions[0])]) return;
//If tile is nonconductive, return
if (!(level->tiles[levelMap->map[x + (y * level->mapDimensions[0])]]->flags & TILETYPE_CONDUCTIVE)) return;
//Valid tile to check, see if there's a poweredobj on the tile (link it to the net if it is) and check the adjacent tiles.
isWalked[x + (y * level->mapDimensions[0])] = true;
findSetPoweredObjects(x,y,powerNet);
recursiveCheckTile(isWalked, powerNet, x - 1, y, levelMap);
recursiveCheckTile(isWalked, powerNet, x + 1, y, levelMap);
recursiveCheckTile(isWalked, powerNet, x, y - 1, levelMap);
recursiveCheckTile(isWalked, powerNet, x, y + 1, levelMap);
}
bool buildPowerNets(void) {
//Build the powernets used by the powered objects
//TODO: Rewrite buildPowerNets() & recursiveCheckTile() to avoid stack overflows and make it easier to backtrace powernets in-game
bool * isWalked;
isWalked = new bool[(level->mapDimensions[0] * level->mapDimensions[1])];
unsigned long x, y;
tilemapData * levelMap = level->layers[level->activeMap];
for (y = 0; y < level->mapDimensions[1]; y++) {
for (x = 0; x < level->mapDimensions[0]; x++) {
if (isWalked[x + (y * level->mapDimensions[0])]) continue;
isWalked[x + (y * level->mapDimensions[0])] = true;
if (level->tiles[levelMap->map[x + (y * level->mapDimensions[0])]]->flags & TILETYPE_CONDUCTIVE) {
//it's conductive, find out what it's connected to.
//But first, create a new powernet
powerNetInfo * powerNet = new powerNetInfo;
powerNet->objectsInNet = 0;
powerNet->producerId = -1;
powerNet->supplyType = POWER_OFF;
powerNet->prevSupplyType = POWER_OFF;
powerNet->powerFor = 0;
//Find adjacent tiles to this one, add them to it's powernet, and then mark them walked. Then repeat until the net is done.
recursiveCheckTile(isWalked, powerNet, x, y, levelMap);
}
}
}
delete isWalked;
for (int i = 0; i < level->numChunks[CHUNKTYPE_POWEREDDEF]; i++)
if (level->poweredObjects[i]->powerNet == NULL) return false;
return true;
}
注意,返回false意味着该函数失败(在这种情况下,没没有正确地链接所有的对象)。
我担心的是,由于堆栈溢出,走过导电图块的功能会在更复杂的贴图上失败。这些功能如何减轻这种风险有什么想法?如果需要,我可以提供更多关于结构的信息。
我想过修改代码,以便recursiveCheckTile
只有在它到达交叉点时才进行递归调用,并且只是交互地跟随它的导电路径,否则这似乎只是一个部分解决方案,因为我可以'事先知道如何扭曲或分支路径可能。
如果它有所不同,速度在这里完全不重要,因为这个函数只在使用前处理地图时运行一次,所以使用一点额外时间不会造成伤害。
那些动画非常棒。 – 2009-07-24 04:07:13