我想尽我所能来概括这个问题,但这确实与我编程的游戏有关。
我有一个具有std::map成员的类:
class Player {
...
private:
std::map<Action, Command> mActionBinding;
...
}
Action 是Player类中的一个枚举。它包含 Action 标题,例如MoveLeft或MoveRight。命令是包含函数和类别的结构。
struct Command
{
Command();
std::function<void(SceneNode&, sf::Time)> action;
unsigned int category;
// SceneNode& node
};
该系统背后的想法是,我可以将一个将操纵SceneNode(游戏中可绘制对象)的函数绑定(bind)到一个SceneNode类别。游戏的update()将迭代我游戏中的所有SceneNode,并在SceneNode的类别与命令中的类别匹配时在SceneNode上执行命令。 (如果这一切听起来都很熟悉,那么这是SFML的GQE引擎,可以在这里找到源代码:https://github.com/LaurentGomila/SFML-Game-Development-Book)
我希望命令比此实现更具体。如果该SceneNode与命令指定的命令匹配,而不仅仅是类别比较,我希望在SceneNode上执行该命令。
但是,命令是在此Player类中创建的,它们是在该std::map中创建的。播放器的构造函数调用initializeAction()函数,该函数调用类似以下内容:
mActionBinding[MoveLeft].action =
derivedAction<SpaceCraft>(SpaceCraftMover(-playerSpeed, 0.f));
基本上,它为操纵航天器节点的某些功能设置 Action 。稍后在Player构造函数中,将mActionBinding的命令类别设置如下:
for(auto& pair : mActionBinding)
pair.second.category = Category::PlayerSpaceCraft;
我的问题:命令的构造函数在我看到的地方没有被调用。我想更改Command的构造函数以接受SceneNode&,因此可以将其设置为SpaceCraft节点(用注释的SceneNode&替换未签名的int)。如何以可以看到Command(SceneNode&)并因此能够正确设置的方式创建这些命令?换句话说,我怎么能得到这个:
Command::Command(SceneNode& n)
: action()
// , category(Category::None)
, node(n)
{}
,目前在我不明白的STL_map.h中给我一个错误,大概是因为Command构造函数在Player的函数中被错误地调用了
在此先感谢您,对这个冗长的问题深表歉意,但我认为上下文是必要的。
最佳答案
如果我正确地理解了这个问题,那么我认为您正在观察 std::map::operator[]
的创建是否不存在并返回引用行为:
如果要自己构造Command
对象(可能通过非default constructor),则可能要根据所需的语义(以及编译器对较新标准的支持)调用 std::map::insert
或 std::map::emplace
,而不要使用operator[]
。
将所有这些放在一起,尝试这样的事情:
Command cmd(theSceneNode);
cmd.action = derivedAction<SpaceCraft>(SpaceCraftMover(-playerSpeed, 0.f));
// more command setup, possibly
mActionBinding.insert(std::make_pair(MoveLeft, cmd));
// or possibly, mActionBinding.insert(std::make_pair(MoveLeft, std::move(cmd)));
关于c++ - std::map如何/在何处初始化其成员?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20298205/