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

C++读取游戏共享内存时lapTimeInSeconds值异常变动的解决求助

解决圈速值异常变动的问题

核心问题分析

  1. 浮点数精确比较的陷阱:graphic.normalizedCarPosition == 1几乎无法精准命中,往往会在圈完成后、游戏重置计时的下一轮循环才触发判断,此时读取到的iCurrentTime已经被重置。
  2. 共享内存的实时更新:游戏进程会持续修改共享内存中的数据,从计算lapTimeInSeconds到触发圈完成判断的这段时间里,iCurrentTime可能已经被游戏重置。

解决方案

1. 替换浮点数精确比较为范围判断

用接近1.0的区间来检测圈完成,确保在计时未被重置的第一时间触发逻辑:

if (graphic.normalizedCarPosition >= 0.999f && graphic.normalizedCarPosition <= 1.001f)

2. 提前保存圈速快照

在判断圈完成前,把当前计算好的圈速值存入临时变量,确保后续文件名生成等操作使用的是固定值,不受共享内存更新影响:

// 在判断圈完成前,先保存当前圈速的快照
float finalLapTime = lapTimeInSeconds;

3. 增加防重复触发标志(可选)

避免同一圈多次触发保存逻辑,添加一个全局/静态标志位:

static bool lapCompletedFlag = false;

// 在循环开头重置标志(当车辆回到起点时)
if (graphic.normalizedCarPosition <= 0.001f) {
    lapCompletedFlag = false;
}

// 圈完成判断
if (!lapCompletedFlag && graphic.normalizedCarPosition >= 0.999f) {
    lapCompletedFlag = true;
    // 后续处理逻辑...
}

修改后的完整代码片段

while (true) {

//........code........

    // laptime
    float lapTimeInSeconds = static_cast<float>(graphic.iCurrentTime) / 1000.0f;
    printf("\rLAP: %.3f", lapTimeInSeconds);
    // save
    memcpy(&save_struct.lapTime_seconds, &lapTimeInSeconds, 4);
    memcpy(&save_struct.normalizedCarPosition, &graphic.normalizedCarPosition, 4);
    memcpy(&save_struct.gaz, &physics.gaz, 4);
    memcpy(&save_struct.brake, &physics.brake, 4);
    memcpy(&save_struct.speedKmh, &physics.speedKmh, 4);
    memcpy(&save_struct.steerAngle, &physics.steerAngle, 4);
    memcpy(&save_struct.gear, &physics.gear, 4);
    memcpy(&save_struct.carCoordiantes, &graphic.carCoordiantes, sizeof(save_struct.carCoordiantes));

    // write bytes into the file
    fwrite(&save_struct, sizeof(SaveStruct), 1, saveFile);

    // 提前保存圈速快照
    float finalLapTime = lapTimeInSeconds;
    // 用范围判断替代精确等于,避免错过时机
    if (graphic.normalizedCarPosition >= 0.999f && graphic.normalizedCarPosition <= 1.001f) {
        fclose(saveFile);
        printf("\nFINAL LAP TIME: %.3f\n", finalLapTime);
        uint8_t seconds = static_cast<int>(finalLapTime) % 60;
        uint8_t minutes = static_cast<int>(finalLapTime) / 60;
        uint16_t millisecond = static_cast<uint16_t>((finalLapTime - (minutes * 60 + seconds)) * 1000);
        std::string final_file_name = "laps/lap-" + std::to_string(lapCount) + "-" + std::to_string(minutes) + "-" + std::to_string(seconds) + "-" + std::to_string(millisecond) + ".lap";
        rename("laps/lap-not-completed.lap", final_file_name.c_str());
        lapCount++;
        saveFile = fopen("laps/lap-not-completed.lap", "wb");
    }

}

额外优化建议

  • 用static_cast替代C风格强制转换,提升代码可读性和类型安全性。
  • 确保共享内存的读取是线程安全的,如果游戏和你的程序是多线程,可能需要加锁保护共享内存的读取操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:35:32