这可能是错误的方法,但随着我对开发游戏引擎的深入研究,我遇到了一个时间问题。
所以我想说我有一组陈述,如:
for(int i = 0; i < 400; i++)
{
engine->get2DObject("bullet")->Move(1, 0);
}
子弹将移动,但是,在屏幕上将不会有任何动画。它基本上会从屏幕的一个部分“扭曲”到下一个部分。
所以,我在想......为每个基础对象(用户继承)创建一个函数指针向量,当他们调用“Move”时,我实际上不会移动对象,直到游戏的下一次迭代环。 如下所示:
while(game.running())
{
game.go();
}
go()
{
for(...)
2dobjs.at(i)->action.pop_back();
}
或类似的东西,这样它在每次迭代期间只运行每个对象的一个动作(当然我会添加一个检查,看看是否有实际的“动作”要运行)。
如果这是一个好主意,我的问题是如何存储参数。由于每个对象可以执行多于一种类型的“动作”而不是移动(rotateby是一个示例),我认为创建一个类似于时尚的结构是没有意义的:
struct MoveAction {
MovePTR...;
int para1;
int para2;
};
思考?或者这是完全错误的方向?
答案 0 :(得分:3)
思考?或者这是完全错误的方向?
这是错误的方向。
实际上,能够排队行动或命令的想法有一些优点。但通常这适用于人工智能和更一般的任务(如“前往位置X”,“攻击你看到的任何东西”等)。所以它通常不包括你在这里处理的逐帧移动问题。
对于像子弹这样非常简单的实体,排队任务相当矫枉过正。毕竟,除了每次前进之外,还有什么东西可以做?这也是实现这种简单动作的尴尬方式。它提出了一些问题,为什么只有400步呢?如果前面的区域更长怎么办?如果它更短?如果只说了50步之后其他一些物体挡住了怎么办? (然后350排队的移动行动是一种浪费。)
这个想法的另一个问题(至少以你所呈现的简单方式)是你的子弹将在游戏循环的每次迭代中移动一个固定的数量。但并非所有迭代都需要花费相同的时间。有些人的计算机显然能够比其他人更快地运行代码。甚至无视这一点,有时游戏循环可能比其他时间做更多的工作(例如当游戏中有更多实体活跃时)。所以你真的想要一种方法来计算每次迭代调整运动所花费的时间,以便一切看起来以一致的速度向用户移动,无论游戏循环的运行速度有多快。
因此,不是每个移动动作都是“移动X量”,而是“以X速度移动”,然后乘以类似于自上次迭代以来经过的时间。然后你真的不知道有多少移动动作要排队,因为它取决于你的游戏循环在那个场景中的运行速度。但同样,这是另一个迹象,排队运动行动是逐帧移动的尴尬解决方案。
大多数游戏引擎的做法是简单地在每个帧上调用某种功能来评估其移动。也许像void ApplyMovement(float timeElapsedSinceLastFrame);
这样的函数。在子弹的情况下,它会使子弹每秒移动的速度乘以自最后一帧以来的传入时间,以确定子弹应移动此帧的数量。对于更复杂的对象,您可能希望使用旋转,加速度,减速度,目标搜索等进行数学运算。但总体思路是相同的:在游戏循环的每次迭代中调用函数来评估该迭代应该发生什么。 / p>
答案 1 :(得分:1)
我不认为这是正确的方向。在函数指针向量中存储400个移动后,您仍然需要弹出并执行移动,重绘屏幕并重复。移动(),重绘和重复是不是更容易?
我会说你的子弹翘曲是因为它移动了400像素/帧,而不是因为你需要延迟移动计算。
但是如果这是你的架构的正确解决方案,那么在C ++中你应该使用类而不是函数指针。例如:
class Action // an abstract interface for Actions
{
public:
virtual void execute() = 0; // pure virtual function
}
class MoveAction: public Action
{
public:
MoveAction(Point vel) : velocity(vel) {}
virtual void execute();
Point velocity;
...
}
std::vector<Action*> todo;
gameloop
{
...
todo.push_back(new MoveAction(Point(1,0))
...
}
答案 2 :(得分:0)
那么400
来自哪里?为什么不这样做呢:
go()
{
engine->get2DObject("bullet")->Move(1, 0);
}
答案 3 :(得分:0)
我认为一般的方法可能会有所不同,无法得到你想要的东西。我个人更喜欢一种设置,其中每个循环调用函数来设置包括子弹在内的所有对象的位置,然后绘制场景。因此,每个循环都会将子弹放在应该正确的位置。
如果你决定走自己的路,那么你可能不得不做你的结构理念。这不愉快,但在我们关闭之前,你必须这样做。