C++游戏开发:如何实现跳跃速度范围控制?clamp是否最优?
按住空格键调整跳跃高度的实现方案
关于clamp的适用性
使用clamp是简洁且高效的实现方式,尤其是C++17及以后标准提供的std::clamp(需包含<algorithm>头文件)。它的底层逻辑就是简单的边界比较,性能和手动写条件判断几乎无差异,但代码更简洁易读,属于最优实现之一。
代码修正与实现
首先要修正原代码中的逻辑问题:原代码在角色空中时会重置jumpVelocity为-15,这会导致地面蓄力的逻辑失效。我们需要把jumpVelocity的初始化/重置放到角色处于地面的分支中,同时在按住空格时调整其值并限制在-22(最小,跳得最高)到-15(最大,基础跳跃)的范围内。
方案一:使用std::clamp
#include <raylib.h> #include <algorithm> // 引入std::clamp int main() { const int windowWidth{512}; const int windowHeight{380}; InitWindow(windowWidth, windowHeight, "Alex's Dapper Game"); const int gravity{1}; int jumpVelocity{-15}; // 定义跳跃速度的边界 const int MIN_JUMP_VEL{-22}; const int MAX_JUMP_VEL{-15}; const int rectWidth{50}; const int rectHeight{80}; bool isInAir{false}; float posX{(windowWidth * .5f) - (rectWidth * .5f)}; int posY{windowHeight - rectHeight}; int rectVelocity{0}; SetTargetFPS(60); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(WHITE); // 地面检测 if (posY >= (windowHeight - rectHeight)) { rectVelocity = 0; isInAir = false; // 回到地面时重置跳跃速度为基础值 jumpVelocity = MAX_JUMP_VEL; } else { rectVelocity += gravity; isInAir = true; } // 按住空格蓄力,调整跳跃速度并限制边界 if(IsKeyDown(KEY_SPACE) && !isInAir) { // 每次帧减少1(让jumpVelocity更负,跳得更高) jumpVelocity -= 1; // 使用clamp限制范围 jumpVelocity = std::clamp(jumpVelocity, MIN_JUMP_VEL, MAX_JUMP_VEL); } // 松开空格触发跳跃 if (IsKeyReleased(KEY_SPACE) && (!isInAir)) { rectVelocity += jumpVelocity; } posY += rectVelocity; DrawRectangle(posX, posY, rectWidth, rectHeight, BLUE); EndDrawing(); } CloseWindow(); }
方案二:手动条件判断(兼容C++17之前的标准)
如果你的环境不支持C++17,手动写边界判断的性能和clamp完全一致,代码如下:
// 替换方案一中的clamp代码段 if(IsKeyDown(KEY_SPACE) && !isInAir) { jumpVelocity -= 1; // 手动限制边界 if (jumpVelocity < MIN_JUMP_VEL) jumpVelocity = MIN_JUMP_VEL; // 因为初始是MAX_JUMP_VEL,只会往更小的方向变,所以上限判断可以省略 // 若有特殊情况需要限制上限,再加:if (jumpVelocity > MAX_JUMP_VEL) jumpVelocity = MAX_JUMP_VEL; }
额外说明
- 注意原代码中你写的目标是
-25,但需求是限制到-22,所以代码中用MIN_JUMP_VEL{-22}来匹配需求。 - 只有当角色在地面时才允许蓄力,避免空中误操作。
内容的提问来源于stack exchange,提问作者a.b89
相关产品推荐
相关产品推荐

