C++/SFML中的平稳动量减速
Smooth momentum slowdown in C++/SFML?
我正在用C++和SFML制作一个"小行星"游戏,我想知道动量的平稳减速和加速。在最初的游戏中,当你朝着一个方向移动时,你会建立"动量",当按下按钮时,动量会增加,当释放按钮时会减少。我已经开始了我自己的版本。目前我有一个包含飞船动量的sf::Vector2f
。它可以是消极的,也可以是积极的。问题是,我无法正确地实现减速(我甚至还没有尝试过加速)。我试过以下几种;
if (plr.momentum.x < 0) {
plr.momentum.x++;
}
if (plr.momentum.x > 0) {
plr.momentum.x--;
}
if (plr.momentum.y < 0) {
plr.momentum.y++;
}
if (plr.momentum.y > 0) {
plr.momentum.y--;
}
这样,移动后,玩家会被缓慢拖动到窗口的左上角(坐标0,0)。我认为这是因为float可以满足"大于0"if语句,例如0.05。由此,它取一,使其成为一个负数。下一个if语句向其中添加一个,并且这个语句不断循环。负x
动量使你向左移动,负y
动量使你向上移动,反之亦然。我想知道平稳减速和加速背后的方法。
如果你想知道,我使用以下代码根据玩家的动量移动玩家;
playerSprite.move(plr.momentum);
如果您不熟悉SFML,sf::Vector2f
有一个.x
和.y
,它们用于sf::Sprite playerSprite
的.move
。CCD_ 9使玩家相对于其当前位置移动;所以如果一个玩家在(5,0),你做player.move(sf::Vector2f(-1,0))
,他们的坐标是(4,0)。
编辑:作为朋友的建议,我现在有了下面的减速代码。减速效果很好,但在减速后,它又开始向左上角移动。是什么原因造成的?
if (plr.xSlowdown < 0.f) {
plr.xSlowdown += 0.1f;
}
if (plr.xSlowdown > 0.f) {
plr.xSlowdown -= 0.1f;
}
if (plr.ySlowdown < 0.f) {
plr.ySlowdown += 0.1f;
}
if (plr.ySlowdown > 0.f) {
plr.ySlowdown -= 0.1f;
}
plr.xMomentum = floor(plr.xSlowdown);
plr.yMomentum = floor(plr.ySlowdown);
如果你想让你的飞船在推进器关闭时减速,你应该增加阻力。
阻力根据速度施加力:最简单的方法是对阻力系数K
执行F = -K v
。因此,如果你的船的动量存储在plr.xMomentum
和plr.yMomentum
中,你的程序将是:
// note: "dt" is your timestep;
// if you don't have one, just choose some small value for "fraction", like 0.005
float fraction = drag_coefficient_K * dt;
plr.xMomentum -= fraction * plr.xMomentum;
plr.yMomentum -= fraction * plr.yMomentum;
加速将基于你的宇宙飞船的方向:
// note: "orientation" is the angle of your spaceship;
// the units of orientation are determined by "angle_scale",
// which should be chosen such that "angle_in_radians" is in radians...
float angle_in_radians = angle_scale * orientation;
float thrust_per_timestep = thrust_value * dt;
plr.xMomentum += thrust_per_timestep * cos(angle_in_radians);
plr.yMomentum += thrust_per_timestep * sin(angle_in_radians);
阻力和推力的结合有效地为你所能达到的速度设定了上限(至少在没有重力辅助的情况下…)
你想要的是物理。非常简单的物理学:F=ma。
你需要对加速度、速度和位置有一些概念。用户输入决定了加速度。加速度改变速度,速度改变位置。
旁白:减速和加速没有区别。它们都是加速度。
- SFML纹理像播放器
- 如何使用AngelScript注册SFML Vector2运算符
- 如何修复sfml c++代码编译错误
- SFML library: http request
- 落砂模拟碰撞检测C++和SFML
- 使用 SFML 和 C++ 将 Pixel 打印到屏幕上
- SFML RenderWindow打开窗口需要很长时间
- 矢量下标超出SFML游戏中的范围
- 获取 SFML 窗口的 HWND 和高可用性?
- 将 Vulkan 与 SFML 结合使用?
- SFML 文本未绘制在窗口上
- SFML 碰撞永远不会在我的系统中注册
- 使用对象数组对 SFML 进行动画处理
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 如何使用 SFML 在贪吃蛇游戏中定义游戏结束?
- 如何通过多类"Union variable" (sfml) 使用轮询事件
- 1d.exe找不到SFML文件?
- 当我尝试通过 mingw 使用 CMake 和 SFML 库编译项目时出错
- Declaration of IntRect SFML
- SFML:错误:")"标记之前的预期主表达式