Extra2D/examples/flappy_bird/pipe.cpp

114 lines
3.4 KiB
C++

// ============================================================================
// Pipe.cpp - 水管类实现
// ============================================================================
#include "Pipe.h"
#include "ResLoader.h"
#include "BaseScene.h"
namespace flappybird {
Pipe::Pipe() {
scored = false;
// 注意:不要在构造函数中创建子节点
// 因为此时 weak_from_this() 还不能使用
}
void Pipe::onEnter() {
Node::onEnter();
// 在 onEnter 中创建子节点,此时 weak_from_this() 可用
if (!topPipe_ && !bottomPipe_) {
// 使用游戏逻辑高度
float screenHeight = GAME_HEIGHT;
// 获取地面高度
auto landFrame = ResLoader::getKeyFrame("land");
float landHeight = landFrame ? landFrame->getRect().size.height : 112.0f;
// 随机生成水管高度
// 范围:与屏幕顶部最小距离不小于 100 像素
// 与屏幕底部最小距离不小于地面上方 100 像素
float minHeight = 100.0f;
float maxHeight = screenHeight - landHeight - 100.0f - gapHeight_;
float height = static_cast<float>(extra2d::randomInt(static_cast<int>(minHeight), static_cast<int>(maxHeight)));
// 创建上水管
auto topFrame = ResLoader::getKeyFrame("pipe_above");
if (topFrame) {
topPipe_ = extra2d::Sprite::create(topFrame->getTexture(), topFrame->getRect());
topPipe_->setAnchor(extra2d::Vec2(0.5f, 1.0f)); // 锚点设在底部中心
topPipe_->setPosition(extra2d::Vec2(0.0f, height - gapHeight_ / 2.0f));
addChild(topPipe_);
}
// 创建下水管
auto bottomFrame = ResLoader::getKeyFrame("pipe_below");
if (bottomFrame) {
bottomPipe_ = extra2d::Sprite::create(bottomFrame->getTexture(), bottomFrame->getRect());
bottomPipe_->setAnchor(extra2d::Vec2(0.5f, 0.0f)); // 锚点设在顶部中心
bottomPipe_->setPosition(extra2d::Vec2(0.0f, height + gapHeight_ / 2.0f));
addChild(bottomPipe_);
}
}
}
Pipe::~Pipe() = default;
extra2d::Rect Pipe::getBoundingBox() const {
// 返回整个水管的边界框(包含上下两根)
extra2d::Vec2 position = pos();
// 水管宽度约为 52
float pipeWidth = 52.0f;
float halfWidth = pipeWidth / 2.0f;
// 使用游戏逻辑高度
float screenHeight = GAME_HEIGHT;
return extra2d::Rect(
position.x - halfWidth,
0.0f,
pipeWidth,
screenHeight
);
}
extra2d::Rect Pipe::getTopPipeBox() const {
if (!topPipe_) return extra2d::Rect();
extra2d::Vec2 position = pos();
extra2d::Vec2 topPos = topPipe_->pos();
// 上水管尺寸
float pipeWidth = 52.0f;
float pipeHeight = 320.0f;
return extra2d::Rect(
position.x - pipeWidth / 2.0f,
position.y + topPos.y - pipeHeight,
pipeWidth,
pipeHeight
);
}
extra2d::Rect Pipe::getBottomPipeBox() const {
if (!bottomPipe_) return extra2d::Rect();
extra2d::Vec2 position = pos();
extra2d::Vec2 bottomPos = bottomPipe_->pos();
// 下水管尺寸
float pipeWidth = 52.0f;
float pipeHeight = 320.0f;
return extra2d::Rect(
position.x - pipeWidth / 2.0f,
position.y + bottomPos.y,
pipeWidth,
pipeHeight
);
}
} // namespace flappybird