c++ - 函数指针及其调用参数

标签 c++ design-patterns oop

这可能是错误的方法,但随着我深入研究开发我的游戏引擎,我遇到了时间问题。

假设我有一组语句,例如:

for(int i = 0; i < 400; i++)
{
     engine->get2DObject("bullet")->Move(1, 0);
}

子弹会移动,但是屏幕上不会有任何动画。它基本上会从屏幕的一部分“变形”到另一部分。

所以,我在想...为每个基础对象(用户从中继承)创建一个函数指针 vector ,当他们调用“移动”时,我实际上不会移动对象,直到游戏的下一次迭代环形。 所以像这样:

while(game.running())
{
     game.go();
}

go()
{
     for(...)
          2dobjs.at(i)->action.pop_back();
}

或者类似的东西,这样它在每次迭代期间只运行每个对象的一个​​ Action (当然我会添加一个检查以查看是否真的有要运行的“ Action ”)。

如果这是个好主意,我的问题是如何存储参数。由于每个对象可以执行不止一种类型的“ Action ”而不是移动(rotateby 就是一个例子),我认为创建一个类似于以下样式的结构是荒谬的:

struct MoveAction {
     MovePTR...;
     int para1;
     int para2;
};

想法?或者这是完全错误的方向?

最佳答案

Thoughts? Or is this the completely wrong direction?

这是错误的方向。

实际上,能够对操作或订单进行排队的想法有一些优点。但这通常适用于 AI 和更一般的任务(如“前往位置 X”、“攻击你看到的任何东西”等)。因此,它通常不会涵盖您在此处处理的逐帧移动问题。

对于像子弹这样非常简单的实体,排队任务相当大材小用。毕竟,子弹除了每次向前移动还能做什么?实现这种简单的 Action 也是一种笨拙的方式。它带来了这样的问题,为什么只向前走了 400 步?如果前面的区域更长怎么办?如果它更短呢?如果仅说 50 步后有其他物体挡住了怎么办? (然后 350 个排队的移动 Action 是浪费。)

这个想法的另一个问题(至少在您提出它的简单方式中)是您的子弹将在游戏循环的每次迭代中移动固定的量。但并非所有迭代都将花费相同的时间。有些人的计算机显然能够比其他人更快地运行代码。即使不考虑这一点,有时游戏循环可能比其他时间做更多的工作(例如当更多实体在游戏中处于事件状态时)。所以你真的想要一种方法来考虑每次迭代调整运动所花费的时间,这样无论游戏循环运行多快,一切都以一致的速度移动给用户。

因此,不是每个移动 Action 都是“移动 X 量”,而是“以 X 速度移动”,然后乘以自上次迭代以来耗时。然后你真的永远不会知道有多少移动 Action 要排队,因为这取决于你的游戏循环在这种情况下的运行速度。但同样,这再次表明排队移动 Action 是逐帧移动的笨拙解决方案。

大多数游戏引擎的做法是简单地在每一帧的每个对象上调用某种函数来评估它的运动。也许像 void ApplyMovement(float timeElapsedSinceLastFrame); 这样的函数。在子弹的情况下,它会将子弹每秒移动的速度乘以自上一帧以来耗时,以确定子弹在这一帧中应该移动的量。对于更复杂的对象,您可能希望对旋转、加速、减速、目标搜索等进行数学计算。但总体思路是相同的:在游戏循环的每次迭代中调用一个函数来评估该迭代应该发生什么。

关于c++ - 函数指针及其调用参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3848074/

相关文章:

c++ - 使用 SFML RenderWindow 时内存位置的 std::length_error

c++ - C++基于成员函数从 vector 中删除对象

php - 过程式 PHP 与面向对象的 PHP

c++ - C++ 程序中的 TCHAR 和未解析的外部符号 (LNK2019) 错误?

c++ - 使用 sstream 验证失败

c++ - ifstream.eof() 在 C++ 中未评估为真

c# - 扩展方法(类)或访问者模式

c# - IoC 在构造函数中使用繁重的工作来初始化服务,但避免使用临时的 Init() 方法

c# - 用普通对象重构 long if - else if - else

c# - 泛型是运行时多态还是编译时多态?