我正在将一款游戏从 Ruby 移植到 C++。有一个更新和绘制内容的主渲染循环。现在假设在游戏过程中,您想在另一个屏幕上选择一个项目。它在原始代码中的完成方式是 Item item = getItemFromMenu();
getItemFromMenu
是一个将打开菜单并有自己的更新/渲染循环的函数,这意味着在播放器打开另一个屏幕的整个过程中,您处于嵌套渲染循环中。我觉得这是一个不好的方法,但我不确定为什么。另一方面,它非常方便,因为我只需调用一个函数就可以打开菜单,因此代码已本地化。
知道这是否是一个糟糕的设计吗?
我犹豫要不要将它发布到 gamedev 上,但由于这主要是一个设计问题,所以我将它发布在这里
编辑:一些伪代码给你一个想法:
代码主体部分的常用循环:
while(open) {
UpdateGame();
DrawGame();
}
现在在 UpdateGame() 中我会做类似的事情:
if(keyPressed == "I") {
Item& item = getItemFromInventory();
}
和getItemFromInventory()
:
while(true) {
UpdateInventory();
if(item_selected) return item;
DrawInventory();
}
最佳答案
处理此类问题的一个好方法是将 DrawInventory()
调用替换为类似 InvalidateInventory()
的调用,这将标记当前的图形状态 list 已过时并请求在下一帧渲染期间重新绘制它(这将在主循环到达 DrawGame()
之后很快发生)。
这样,您可以继续运行主循环,但屏幕上唯一需要重绘的部分是那些已经失效的部分,在正常游戏过程中,您可以使 (2/3)D 失效环境作为处理的正常部分,但在库存中,您始终可以仅将库存 Assets 标记为需要重新绘制,从而最大限度地减少开销。
内部循环的另一部分,UpdateInventory()
,可以是 UpdateGame()
的一部分,如果你使用一个标志来指示当前的游戏状态,一些喜欢:
UpdateGame()
{
switch(gameState)
{
case INVENTORY:
UpdateInventory();
break;
case MAIN:
default:
UpdateMain();
break;
}
}
如果你真的想要,你也可以将其应用于绘图:
DrawGame()
{
switch(gameState)
{
case INVENTORY:
DrawInventory();
break;
case MAIN:
default:
DrawMain();
break;
}
}
但我认为绘图应该被封装,你应该告诉它屏幕的哪一部分,而不是游戏的哪个单独区域,需要被绘制。
关于c++ - 嵌套渲染循环是不好的做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8887057/