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

SDL版Chrome恐龙克隆:角色触地逻辑异常问题求助

问题分析与修复方案

核心问题梳理

你的代码存在三个关键错误,直接导致角色触地逻辑异常:

  1. OnFloor的Setter方法逻辑错误,无法正确修改成员变量状态
  2. Update阶段强制将Y轴位置设为0,导致角色粘在屏幕顶部
  3. 碰撞检测仅设置触地状态,未处理非碰撞时的状态重置,且缺少碰撞后的位置修正

1. 修复Player类的OnFloor Setter

最初的Setter因参数与成员变量重名,修改的是临时参数而非类成员;后续版本直接强制设为true,完全丧失了Setter的动态赋值作用。正确实现如下:

// Player.h 中的OnFloor Setter
void setOnFloor(bool onFloor) {
    this->onFloor = onFloor; // 用this->明确区分成员变量与参数
}

同时在Player的start()方法中初始化状态,避免随机初始值干扰:

void Player::start() {
    onFloor = false;
    // 其他初始化逻辑(如纹理、初始位置等)
}

2. 修正GameScene的Update逻辑

你原本在else分支强制将Y设为0,这是角色粘在顶部的直接原因。触地时应保持角色当前位置,而非强制重置:

void GameScene::update()
{
    Scene::update();

    // 先默认标记为未触地,碰撞检测后覆盖状态
    player->setOnFloor(false);
    floorCollision();

    // 重力逻辑:仅未触地时执行下落
    if (!player->getOnFloor()) {
        player->setY(player->getY() + 2);
    }
    // 触地时不修改Y值,保持当前位置
}

3. 完善碰撞检测逻辑

当前碰撞检测仅在碰撞时设置触地状态,未处理角色陷入地面的问题,也未重置非碰撞时的状态。修改后的逻辑:

void GameScene::floorCollision()
{
    for (int i = 0; i < objects.size(); i++)
    {
        Floor* floor = dynamic_cast<Floor*>(objects[i]);
        if (floor != NULL)
        {
            int collision = checkCollision(
                player->getX(), player->getY(), player->getWidth(), player->getHeight(),
                floor->getX(), floor->getY(), floor->getWidth(), floor->getHeight()
            );

            if (collision == 1)
            {
                std::cout << "!" << std::endl;
                player->setOnFloor(true);
                // 修正位置:让角色底部刚好贴合地面顶部,避免陷入
                player->setY(floor->getY() - player->getHeight());
                break;
            }
        }
    }
}

额外说明

  • 确保checkCollision函数返回值1确实代表玩家从上方与地面发生垂直碰撞,若碰撞检测包含多方向逻辑,需调整判断条件。
  • 后续添加跳跃逻辑时,只需在玩家触地时响应输入,将onFloor设为false并给Y轴赋予向上的速度即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:02:00