我在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语句中,该语句只允许每帧更新一次错误,但控件的平滑性和响应性要差得多。
所以我的问题是,如何保持运动快速更新的响应能力,同时避免进入自身的错误?
答案 0 :(得分:1)
我没有游戏开发经验,我甚至不确定我理解你的问题。
但是,我想知道您的代码的以下结构是否有助于控制更新过程:
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和update 或保存时间戳并移动(然后仅在最后一个时间戳减去当前时间戳多于/少于某个数字。)
答案 1 :(得分:1)
做你的蛇;问题不在于你的输入(但是那些"如果"应该是一个switch语句),而是在对象中对输入作出反应,例如。 " Snake_Object"。正常游戏在按下方向时强制设定数量的位置移动。如果你观看比赛,如果你向上按,那么蛇就会被迫立即从上面的一个碰撞盒上方。这可以确保您无法进行不必要的即时碰撞,并且仍能保持常规的fps流量。
因此,当移动变量发送到Snake时,它应该在第一个实例中沿该方向移动整个碰撞盒,然后以正常速度移动。