Snake游戏:快速反应vs碰撞漏洞
Snake game: fast response vs. collision bug
我在SFML c++中有一个蛇游戏,我在两个选项之间卡住了。如果这样设置控件:
if(event.type == sf::Event::KeyPressed && (event.key.code == sf::Keyboard::Up
|| event.key.code == sf::Keyboard::W) && move != Down)
move = Up;
else if(event.type == sf::Event::KeyPressed && (event.key.code == sf::Keyboard::Down
|| event.key.code == sf::Keyboard::S) && move != Up)
move = Down;
else if(event.type == sf::Event::KeyPressed && (event.key.code == sf::Keyboard::Left
|| event.key.code == sf::Keyboard::A)&& move != Right)
move = Left;
else if(event.type == sf::Event::KeyPressed && (event.key.code == sf::Keyboard::Right
|| event.key.code == sf::Keyboard::D) && move != Left)
move = Right;
这里,控件非常灵敏。问题是,例如,如果蛇向右移动,而你要快速连续按下向上和向左键,蛇还没有向上移动,但是向上的控制将被缓冲,所以蛇将被允许向左移动到自己身上,从而死亡。
如果我将这些移动条件包装在一个只允许每帧更新一次的If语句中,那么漏洞就得到了解决,但控制就不那么流畅和响应性了。
所以我的问题是,我如何保持允许运动快速更新的响应性,同时避免移动到自己的bug ?
既然你在制作Snake;问题不在于你的输入(但那些"if"应该是一个开关语句),而在于与输入反应的对象,例如"Snake_Object"。正常的游戏中,当一个方向被按下时,会强制进行一定数量的位置移动。如果你观看游戏,如果你向上按压,那么蛇就会立即被推到它原来所在位置上方的一个碰撞箱。这确保你不能做你不想要的直接碰撞,仍然保持正常的fps流。
所以当move变量被发送给Snake时,它应该在第一个实例中向那个方向移动整个碰撞框,然后以正常速度移动。
我没有游戏开发经验,我甚至不确定我是否理解你的问题。
但是,我想知道您的代码的以下结构是否有助于控制更新过程:
inline void UpdateMoveUp(Move& move) { if(move != Down) { move = Up; }}
inline void UpdateMoveDown(Move& move) { if(move != Up) { move = Down; }}
inline void UpdateMoveLeft(Move& move) { if(move != Right) { move = Left; }}
inline void UpdateMoveRight(Move& move) { if(move != Left) { move = Right; }}
inline void UpdateMoveInvalid(Move& move) { move = Invalid; }
inline void HandleUpdate(const Code& code, Move& move) {
switch(code) {
case sf::Keyboard::Up:
return UpdateMoveUp(move);
case sf::Keyboard::W:
return UpdateMoveUp(move);
case sf::Keyboard::Down:
return UpdateMoveDown(move);
case sf::Keyboard::S:
return UpdateMoveDown(move);
case sf::Keyboard::Left:
return UpdateMoveLeft(move);
case sf::Keyboard::A:
return UpdateMoveLeft(move);
case sf::Keyboard::Right:
return UpdateMoveRight(move);
case sf::Keyboard::D:
return UpdateMoveRight(move);
default:
return UpdateMoveInvalid(move);
}
}
void HandleInput(const Event& event, Move& move) {
// I assume that `move` comes from somewhere else
if(event.type == sf::Event::KeyPressed) {
return HandleUpdate(event.key.code, move);
}
}
我的看法是,您将更新函数隔离到一个地方,您可以在那里添加更多的更新条件,而不必再次测试整个条件。
换句话说,您可以为每个UpdateMoveXXXX
函数添加进一步的条件,例如unbuffer并更新或保存时间戳并移动(然后仅当最后一个时间戳减去当前时间戳大于/小于某个数字时移动)。
相关文章:
- 落砂模拟碰撞检测C++和SFML
- SFML 碰撞永远不会在我的系统中注册
- 在均匀网格中处理碰撞
- 指向unique_ptr的指针 - 这是一个漏洞吗?
- 平台游戏 - 下车时避免与平台碰撞
- AABB 碰撞使实际精灵的大小翻倍
- 标头中有哪些固有的安全漏洞<filesystem>?
- 具有随机值的多个对象及其碰撞的 SFML
- SFML 中的重力和碰撞检测
- 我的碰撞检测中的奇怪行为
- Box2D Contact Listener碰撞仅间歇性工作
- 如何为球形物体和三角形地形提供高效的碰撞检测和响应
- 同时与两个片段着色器发生碰撞
- 2D 障碍物碰撞
- 可破坏的网格块会导致奇怪的碰撞
- ptrdiff_t typedef 碰撞 - 谷歌测试和英特尔蟒蛇
- 玩家移动和碰撞之间的交互问题
- 圆形与方形碰撞检测以及需要响应C++ |OpenGL。我的问题就是这个"I need to keep the circle outside the square"
- 需要帮助了解这个简短的C++程序及其漏洞
- Snake游戏:快速反应vs碰撞漏洞