不要尝试复制整个游戏状态。插值将是一场噩梦。只需通过渲染隔离出需要变化的部分即可(我们称其为“可视状态”)。
为每个对象类创建一个伴随类,该类将能够保存对象的视觉状态。该对象将由仿真产生,并由渲染消耗。插值将很容易插入之间。如果状态是不可变的,并按值传递,则不会有线程问题。
渲染通常不需要了解对象之间的逻辑关系,因此用于渲染的结构将是纯矢量,或至多是简单的树。
例
传统设计
class Actor
{
Matrix4x3 position;
float fuel;
float armor;
float stamina;
float age;
void Simulate(float deltaT)
{
age += deltaT;
armor -= HitByAWeapon();
}
}
使用视觉状态
class IVisualState
{
public:
virtual void Interpolate(const IVisualState &newVS, float f) {}
};
class Actor
{
struct VisualState: public IVisualState
{
Matrix4x3 position;
float fuel;
float armor;
float stamina;
float age;
virtual auto_ptr<IVisualState> Interpolate(const IVisualState &newVS, float f)
{
const VisualState &newState = static_cast<const VisualState &>(newVS);
IVisualState *ret = new VisualState;
ret->age = lerp(this->age,newState.age);
// ... interpolate other properties as well, using any suitable interpolation method
// liner, spline, slerp, whatever works best for the given property
return ret;
};
};
auto_ptr<VisualState> state_;
void Simulate(float deltaT)
{
state_->age += deltaT;
state_->armor -= HitByAWeapon();
}
}