有没有更优雅的方式来实现“作弊代码”?在 C++ 中实现游戏?
我一直通过深入研究一个项目(一个简单的 2d 游戏)来学习 C++。我试图实现一组作弊,但我在字符串操作方面真的是新手。我确信会有一种比下面的代码更优雅的方式来实现我想要的目标。
根据要求,stringBuffer
只是一个包含最后 12 个按下的字符的字符串。我把它放在前面是因为它会在最后调整大小时被修剪,因此我的作弊必须是向后的。我在字符串操作方面是个菜鸟,我知道这里出了问题,这就是我要求对其进行查看并可能进行改进的原因。
//The following code is in my keyPressed function
cheatBuffer = (char)key + cheatBuffer;
cheatBuffer.resize(12);
string tempBuffer;
string cheats[3] = {"1taehc","2taehc","3taehc"};
for(int i = 0;i < 3;i++){
tempBuffer = cheatBuffer;
tempBuffer.resize(cheats[i].size());
if(cheats[i] == tempBuffer){
switch(i){
case 1:
//activate cheat 1
break;
case 2:
//active cheat 2
break;
case 3:
//active cheat 3
break;
}
}
}
代码分别是“cheat1”、“cheat2”和“cheat3”。我不禁想到这可能会好得多。任何见解将不胜感激。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可能需要考虑使用:
std::map>
(如果您可以使用 C++0x)std ::map>
(如果可以使用 TR1)std::map>
(如果可以使用 Boost)(当然,函数的签名可以不同)
使用 C++0x 的示例
输入:
输出:
现场演示
You might want to consider using:
std::map<std::string, std::function<void ()>>
(If you can use C++0x)std::map<std::string, std::tr1::function<void ()>>
(If you can use TR1)std::map<std::string, boost::function<void ()>>
(If you can use Boost)(Of course, the signature of the function can differ)
Example using C++0x
Input:
Output:
Live demo
我会将字符串存储在 trie 中:
http://en.wikipedia.org/wiki/Trie
(在维基百科文章中也有 C++ 实现的链接)。
在特里树的叶子中,您可以添加有关作弊的附加数据。
当您查找一个字符串时,您只需检查该字符串是否包含在带有作弊代码的特里树中。如果是,您将获得附加数据(例如,指向执行您想要执行的操作的函数的函数指针;或更面向对象:指向类实例的指针,当您调用其成员函数之一时,该指针会执行“作弊”操作东西”)。
I would store the strings in a trie:
http://en.wikipedia.org/wiki/Trie
(in the Wikipedia article there are also links to C++ implementations).
In the leafs of the trie you can add additional data concerning the cheat.
When you lookup a string you simple check whether the string is contained in the trie with the cheat codes. If yes, you get the additional data (for example a function pointer to a function that does what you want to do; or more Object-Oriented: a pointer to a class instance that when you call one of its member functions does the "cheating stuff").
可以通过多种方式改进此代码。
将不可变字符串设为常量静态
,这样就不必每次在“KeyPressed”处理程序中都分配它们。
将每个作弊与可在
case
语句中使用的值相关联我认为所有促进
switch
的附加逻辑并不是一个好主意。怎么样:这样你就可以得到一个整数,你可以将其用作每个作弊代码的案例标签。
搜索要激活的作弊码
您希望能够搜索已轻松激活的作弊码。让我们分解
std::pair
实例并使用std::map
代替。现在,假设
candidate
是您的按键缓冲区,您可以这样做This code can be improved in several ways.
Make your immutable strings const static
So they don't have to be allocated every time in your "KeyPressed" handler.
Associate each cheat with a value that you can use in a
case
statementI don't think all the additional logic to facilitate the
switch
is a good idea. What about something like this:This way you get an integer which you can use as a case label for each of your cheat codes.
Search for the cheat to activate
You want to be able to search for a cheat code that has been activated easily. Let's break up the
std::pair
instances and use astd::map
instead.Now, assuming that
candidate
is your keypress buffer, you can just do我会这样做:当首先按下某个特定按钮时,例如 Enter,它将开始填充 cheatBuffer,并且在缓冲区末尾填充一个字符后,它将使用该缓冲区来检查值是否为它存在于 std::map 中。当该值存在时,它将执行一个函数,该函数的指针存储在 std::map 中。
I would do it this way: when pressing some specific button first, for example enter, it would start to fill the cheatBuffer, and after one char was filled in the end of the buffer, it would use that buffer to check if a value of it exists in an std::map. And when that value exists, it would execute a function, which pointer was stored in std::map.
这可能有点矫枉过正,工作量太大,但您可以制作一个有限状态机来处理您的关键输入,存储当前状态而不是存储关键历史记录。您的起始状态 0 表示没有按下任何适用的键。 'c' 将使您进入状态 1,其中 'h' 将使您进入状态 2,'c' 将使您保持在状态 1,而其他任何内容都会使您返回到 0。因此,在给定的按键上,您打开当前状态,并在其中打开提供的角色以查看您转换到哪个状态。如果是最终状态,则执行作弊并转换回 0。
This might be overkill and too much work, but you could make a finite state machine to handle your key inputs, storing your current state instead of storing a key history. Your starting state 0 represents no applicable keys pressed. A 'c' will put you into state 1, where an 'h' will bring you to state 2, a 'c' will keep you at state 1, and anything else will send you back to 0. So on a given keypress you switch on the current state, and inside of that, switch on the character supplied to see which state you transition into. If it was a final state then execute the cheat and transition back to 0.