C++中如何存储数组位置后续使用 解决游戏特殊元素被覆盖问题
问题根源
你现在的代码设计存在状态耦合问题:把玩家的动态移动状态和地图的静态固定元素存在同一个cMap数组里。玩家移动时,会直接把站过的旧位置硬编码赋值为.,根本不记得这个位置原本存的是不是E这类特殊标记。
只要玩家踩过E的位置,这个位置的E会先被@覆盖,等玩家离开的时候又被直接写成.,E的原始信息就彻底丢失了,自然没法正常恢复。
最稳妥的解决办法
把静态地图信息和动态玩家状态彻底拆开,不要把玩家@直接写进静态地图数组:
- 专门保留一份从来不会被改动的原始静态地图,所有墙、地板、
E的信息永久存在这份数组里,玩家的移动操作永远不直接修改这份数组的内容 - 单独用两个变量记录玩家的实时坐标
- 每次渲染画面时,遍历静态地图,走到玩家坐标的位置就临时输出一个
@,其他位置直接输出静态地图原本的字符 - 移动的时候只需要校验目标位置在静态地图里是不是墙,不是墙就直接更新玩家坐标,根本不用反复在数组里改来改去
这种方法从根上就不会让静态元素被玩家状态覆盖,以后再加传送点、宝箱这类特殊元素,也不用修改核心移动逻辑。
具体代码调整
- 调整静态地图初始化内容,把原来写在地图数组里的
@删掉(玩家坐标单独管理,不写入静态地图):
char cMap[20][35] = { "##################################", "#................................#", "#................................#", "#................................#", "#................................#", "#................................#", "#................................#", "#................................#", "#................................#", "#................................#", "#................................#", "##########.#.....................#", "#..........#.....................#", "#..........#.....................#", "#....E.....#.....................#", "#..........#.....................#", "#..........#.....................#", "#..........#.....................#", "##################################" }; bool running = true; int x = 1, y = 1; // 玩家初始坐标单独存储,不写入静态地图
- 替换原来的画面渲染逻辑,不再直接整行输出静态地图,而是逐字符判断当前位置是不是玩家坐标:
system("cls"); for (int i = 0; i < 20; i++) { for (int j = 0; j < 35; j++) { if (i == y && j == x) { cout << '@'; } else { cout << cMap[i][j]; } } cout << endl; }
- 简化所有方向的移动逻辑,不再修改地图数组内容,只做目标位置校验,通过就直接更新玩家坐标:
if (GetAsyncKeyState(VK_DOWN)) { int new_y = y + 1; // 直接查静态地图的目标位置是不是墙,不修改数组内容 if (cMap[new_y][x] != '#') { y = new_y; } } if (GetAsyncKeyState(VK_UP)) { int new_y = y - 1; if (cMap[new_y][x] != '#') { y = new_y; } } if (GetAsyncKeyState(VK_RIGHT)) { int new_x = x + 1; if (cMap[y][new_x] != '#') { x = new_x; } } if (GetAsyncKeyState(VK_LEFT)) { int new_x = x - 1; if (cMap[y][new_x] != '#') { x = new_x; } }
效果说明
调整完成后,静态地图里的E、#、.所有元素都不会被玩家状态覆盖,不管玩家在E位置停留多久、向哪个方向移动,离开后E都会自动恢复显示,不会再被硬替换成.。
要是不想大改现有代码,凑合用的临时方案是新增一个变量专门记录玩家当前位置对应的原始静态值:玩家走到某个位置的时候,先把这个位置原本存的字符暂存下来,等玩家要离开的时候,把存下来的字符写回原位置就行。但这种方法很容易漏判边界情况,比如玩家站在
E上的时候按ESC退出,忘了还原E的位置,就会导致地图元素永久丢失,远不如拆分静态/动态状态的方案稳妥。
内容的提问来源于stack exchange,提问作者Gavin C.
相关产品推荐
相关产品推荐

