我正在编写自己的小游戏引擎。 为了将选项菜单与主菜单和主游戏等分开,我想到制作一个状态系统,其中上面提到的所有内容都是一个自己的状态。 引擎主循环在当前状态上调用tick()方法。 但是现在引擎对状态之间的交互,何时切换状态等都一无所知。 为了解决这个问题,我实现了以下内容: tick() - 状态方法返回模板类型:commandset。 Engine获取一个Eventhandler来处理tick() - 方法的返回值。 它看起来像这样:
template<class StateHandler, typename FeedbackType>
void Engine<StateHandler, FeedbackType>::run()
{
run = true;
clock.restart();
while (run)
{
sf::Time elapsed = clock.restart();
Win->clear(sf::Color::Black);
processEvents();
if (!pause)
{
Handler(currentState->tick(elapsed), *this);
if (overlayState != NULL)
Handler(overlayState->tick(elapsed), *this);
}
Win->display();
}
}
因此,引擎在tick的返回值上调用处理程序,并将自身传递给它。这样Handler就可以与引擎进行交互。 (变量处理程序属于StateHandler类型)
现在,当我想测试所有内容,编写一个Teststate和一个处理程序时,我遇到了麻烦。 对于以后的使用,我打算使用一个类作为处理程序,但为了简单的测试目的,我想使用一个函数。 所以当我想编写函数时,我注意到,我无法定义第二个参数,引擎,因为它的模板参数将是函数的类型(取决于引擎类型,这取决于函数类型...)。
现在我的问题是:如何定义处理程序?或者整个想法是垃圾吗? (这真的很悲惨,因为我有点喜欢)
答案 0 :(得分:2)
功能是否少得多,值得担心?
struct TestHandler {
void operator ()(const CommandSet& cs, Engine<TestHandler, TestFeedback>& e) {
}
};
如果你真的想要一个功能,你必须跳过篮球。对于不正当的快乐,我已经添加了一种方法来完成这项工作:
class any_ref {
public:
template <typename T>
any_ref(T& ref)
: pointer(&ref)
#if !defined(NDEBUG)
, type(&typeid(T))
#endif
{}
template <typename T>
T& get() const {
assert(typeid(T) == *type);
return *static_cast<T*>(pointer);
}
private:
void* pointer;
#if !defined(NDEBUG)
const std::type_info* type;
#endif
};
void TestHandler(const CommandSet& cs, any_ref er) {
auto& e = er.get<Engine<void (*)(const CommandSet&, any_ref), TestFeedback>>();
}