SDL版Chrome恐龙克隆:角色触地逻辑异常问题求助
问题分析与修复方案
核心问题梳理
你的代码存在三个关键错误,直接导致角色触地逻辑异常:
- OnFloor的Setter方法逻辑错误,无法正确修改成员变量状态
- Update阶段强制将Y轴位置设为0,导致角色粘在屏幕顶部
- 碰撞检测仅设置触地状态,未处理非碰撞时的状态重置,且缺少碰撞后的位置修正
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
相关产品推荐
相关产品推荐

