You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20游戏循环移动逻辑实现咨询:如何避免代码冗余

C++20 游戏移动逻辑的几种实现方案

结合你使用C++20和GCC 11.1.0的环境,针对移动逻辑需求,下面提供几种可行的实现方案:

方案一:使用std::optional(类型安全,推荐)

利用C17引入、C20完善的std::optional标记速度值是否存在,既保证类型安全,又能清晰区分"无值"与"有值"状态,可读性和维护性都不错。

#include <optional>

// 游戏循环内的代码
std::optional<int> xVel, yVel;

if (direction == LEFT /* && 其他条件 */) {
    xVel = /* left_calculation */;
} else if (direction == RIGHT /* && 其他条件 */) {
    xVel = /* right_calculation */;
} else if (direction == UP /* && 其他条件 */) {
    yVel = /* up_calculation */;
} else if (direction == DOWN /* && 其他条件 */) {
    yVel = /* down_calculation */;
}

// 统一处理逻辑
if (xVel.has_value() || yVel.has_value()) {
    // 使用*xVel、*yVel访问实际值
    if (xVel) player.pos.x += *xVel;
    if (yVel) player.pos.y += *yVel;
    // 其他庞大的处理逻辑...
}

优点:类型安全,无未初始化变量风险;逻辑清晰,分支职责明确;符合现代C++风格。
缺点:需引入<optional>头文件,新手需理解基础用法。

方案二:使用goto跳转(简洁直接)

若追求代码紧凑,且处理逻辑庞大不想重复编写,可通过goto直接跳转到统一处理块。注意提前声明变量,避免跳过初始化导致未定义行为。

// 游戏循环内的代码
int xVel = 0, yVel = 0;
bool hasX = false, hasY = false;

if (direction == LEFT /* && 其他条件 */) {
    xVel = /* left_calculation */;
    hasX = true;
    goto handle_movement;
} else if (direction == RIGHT /* && 其他条件 */) {
    xVel = /* right_calculation */;
    hasX = true;
    goto handle_movement;
} else if (direction == UP /* && 其他条件 */) {
    yVel = /* up_calculation */;
    hasY = true;
    goto handle_movement;
} else if (direction == DOWN /* && 其他条件 */) {
    yVel = /* down_calculation */;
    hasY = true;
    goto handle_movement;
}

// 无有效方向时跳过处理
goto end_movement;

handle_movement:
// 统一处理逻辑
if (hasX || hasY) {
    if (hasX) player.pos.x += xVel;
    if (hasY) player.pos.y += yVel;
    // 其他庞大的处理逻辑...
}

end_movement:
// 后续代码

优点:避免重复编写处理逻辑,代码紧凑;适合简单场景快速实现。
缺点:滥用goto会降低代码可读性,增加维护难度;需额外布尔标记判断值有效性。

方案三:重构为独立函数(解耦逻辑,适合复杂场景)

若底部处理逻辑非常庞大,将计算与处理拆分到独立函数,能让主逻辑更简洁,也方便单独测试处理逻辑。

#include <optional>
#include <utility>

// 计算速度的函数
std::pair<std::optional<int>, std::optional<int>> calculateMovement(Direction direction /*, 其他参数 */) {
    std::optional<int> xVel, yVel;
    if (direction == LEFT /* && 其他条件 */) {
        xVel = /* left_calculation */;
    } else if (direction == RIGHT /* && 其他条件 */) {
        xVel = /* right_calculation */;
    } else if (direction == UP /* && 其他条件 */) {
        yVel = /* up_calculation */;
    } else if (direction == DOWN /* && 其他条件 */) {
        yVel = /* down_calculation */;
    }
    return {xVel, yVel};
}

// 处理移动的函数
void handleMovement(std::optional<int> xVel, std::optional<int> yVel) {
    if (xVel.has_value() || yVel.has_value()) {
        if (xVel) player.pos.x += *xVel;
        if (yVel) player.pos.y += *yVel;
        // 其他庞大的处理逻辑...
    }
}

// 游戏循环内的代码
auto [xVel, yVel] = calculateMovement(currentDirection /*, 其他参数 */);
handleMovement(xVel, yVel);

优点:逻辑解耦,主循环代码简洁;处理逻辑可单独维护测试;符合模块化编程思想。
缺点:需额外定义函数,简单场景略显繁琐;若需访问全局游戏状态(如player),需合理设计参数或类结构。


内容的提问来源于stack exchange,提问作者spaL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:57:43