refactor(构建系统): 移除示例项目中的冗余资源打包逻辑
refactor(文档): 更新节点系统教程避免双重引用问题 fix(四叉树): 修复碰撞检测中的缓冲区越界问题 refactor(空间索引示例): 使用 getChildren() 替代私有 vector 存储节点 style(精灵批处理): 调整代码格式和初始化顺序
This commit is contained in:
parent
010e48753c
commit
1b72a1c992
|
|
@ -53,8 +53,8 @@ void main() {
|
|||
)";
|
||||
|
||||
GLSpriteBatch::GLSpriteBatch()
|
||||
: vao_(0), vbo_(0), ibo_(0), currentTexture_(nullptr), currentIsSDF_(false),
|
||||
vertexCount_(0), drawCallCount_(0), spriteCount_(0), batchCount_(0) {
|
||||
: vao_(0), vbo_(0), ibo_(0), vertexCount_(0), currentTexture_(nullptr),
|
||||
currentIsSDF_(false), drawCallCount_(0), spriteCount_(0), batchCount_(0) {
|
||||
}
|
||||
|
||||
GLSpriteBatch::~GLSpriteBatch() { shutdown(); }
|
||||
|
|
@ -111,7 +111,8 @@ bool GLSpriteBatch::init() {
|
|||
|
||||
glBindVertexArray(0);
|
||||
|
||||
E2D_LOG_INFO("GLSpriteBatch initialized with capacity for {} sprites", MAX_SPRITES);
|
||||
E2D_LOG_INFO("GLSpriteBatch initialized with capacity for {} sprites",
|
||||
MAX_SPRITES);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -140,18 +141,17 @@ void GLSpriteBatch::begin(const glm::mat4 &viewProjection) {
|
|||
batchCount_ = 0;
|
||||
}
|
||||
|
||||
bool GLSpriteBatch::needsFlush(const Texture& texture, bool isSDF) const {
|
||||
bool GLSpriteBatch::needsFlush(const Texture &texture, bool isSDF) const {
|
||||
if (currentTexture_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 检查是否需要刷新:纹理改变、SDF 状态改变或缓冲区已满
|
||||
return (currentTexture_ != &texture) ||
|
||||
(currentIsSDF_ != isSDF) ||
|
||||
return (currentTexture_ != &texture) || (currentIsSDF_ != isSDF) ||
|
||||
(vertexCount_ + VERTICES_PER_SPRITE > MAX_VERTICES);
|
||||
}
|
||||
|
||||
void GLSpriteBatch::addVertices(const SpriteData& data) {
|
||||
void GLSpriteBatch::addVertices(const SpriteData &data) {
|
||||
// 计算变换后的顶点位置
|
||||
glm::vec2 anchorOffset(data.size.x * data.anchor.x,
|
||||
data.size.y * data.anchor.y);
|
||||
|
|
@ -172,10 +172,14 @@ void GLSpriteBatch::addVertices(const SpriteData& data) {
|
|||
// v0(左上) -- v1(右上)
|
||||
// | |
|
||||
// v3(左下) -- v2(右下)
|
||||
Vertex v0{transform(0, 0), glm::vec2(data.texCoordMin.x, data.texCoordMin.y), color};
|
||||
Vertex v1{transform(data.size.x, 0), glm::vec2(data.texCoordMax.x, data.texCoordMin.y), color};
|
||||
Vertex v2{transform(data.size.x, data.size.y), glm::vec2(data.texCoordMax.x, data.texCoordMax.y), color};
|
||||
Vertex v3{transform(0, data.size.y), glm::vec2(data.texCoordMin.x, data.texCoordMax.y), color};
|
||||
Vertex v0{transform(0, 0), glm::vec2(data.texCoordMin.x, data.texCoordMin.y),
|
||||
color};
|
||||
Vertex v1{transform(data.size.x, 0),
|
||||
glm::vec2(data.texCoordMax.x, data.texCoordMin.y), color};
|
||||
Vertex v2{transform(data.size.x, data.size.y),
|
||||
glm::vec2(data.texCoordMax.x, data.texCoordMax.y), color};
|
||||
Vertex v3{transform(0, data.size.y),
|
||||
glm::vec2(data.texCoordMin.x, data.texCoordMax.y), color};
|
||||
|
||||
vertexBuffer_[vertexCount_++] = v0;
|
||||
vertexBuffer_[vertexCount_++] = v1;
|
||||
|
|
@ -196,50 +200,52 @@ void GLSpriteBatch::draw(const Texture &texture, const SpriteData &data) {
|
|||
spriteCount_++;
|
||||
}
|
||||
|
||||
void GLSpriteBatch::drawBatch(const Texture& texture, const std::vector<SpriteData>& sprites) {
|
||||
void GLSpriteBatch::drawBatch(const Texture &texture,
|
||||
const std::vector<SpriteData> &sprites) {
|
||||
if (sprites.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 如果当前有未提交的批次且纹理不同,先刷新
|
||||
if (currentTexture_ != nullptr && currentTexture_ != &texture) {
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
currentTexture_ = &texture;
|
||||
currentIsSDF_ = sprites[0].isSDF; // 假设批量中的精灵 SDF 状态一致
|
||||
|
||||
|
||||
// 分批处理,避免超过缓冲区大小
|
||||
size_t index = 0;
|
||||
while (index < sprites.size()) {
|
||||
size_t remainingSpace = (MAX_VERTICES - vertexCount_) / VERTICES_PER_SPRITE;
|
||||
size_t batchSize = std::min(sprites.size() - index, remainingSpace);
|
||||
|
||||
|
||||
for (size_t i = 0; i < batchSize; ++i) {
|
||||
addVertices(sprites[index + i]);
|
||||
spriteCount_++;
|
||||
}
|
||||
|
||||
|
||||
index += batchSize;
|
||||
|
||||
|
||||
// 如果还有更多精灵,刷新当前批次
|
||||
if (index < sprites.size()) {
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
batchCount_++;
|
||||
}
|
||||
|
||||
void GLSpriteBatch::drawImmediate(const Texture& texture, const SpriteData& data) {
|
||||
void GLSpriteBatch::drawImmediate(const Texture &texture,
|
||||
const SpriteData &data) {
|
||||
// 立即绘制,不缓存 - 用于需要立即显示的情况
|
||||
flush(); // 先提交当前批次
|
||||
|
||||
|
||||
currentTexture_ = &texture;
|
||||
currentIsSDF_ = data.isSDF;
|
||||
addVertices(data);
|
||||
spriteCount_++;
|
||||
|
||||
|
||||
flush(); // 立即提交
|
||||
}
|
||||
|
||||
|
|
@ -270,7 +276,8 @@ void GLSpriteBatch::flush() {
|
|||
|
||||
// 更新 VBO 数据 - 只更新实际使用的部分
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount_ * sizeof(Vertex), vertexBuffer_.data());
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount_ * sizeof(Vertex),
|
||||
vertexBuffer_.data());
|
||||
|
||||
// 绘制
|
||||
glBindVertexArray(vao_);
|
||||
|
|
@ -280,7 +287,7 @@ void GLSpriteBatch::flush() {
|
|||
|
||||
drawCallCount_++;
|
||||
batchCount_++;
|
||||
|
||||
|
||||
// 重置状态
|
||||
vertexCount_ = 0;
|
||||
currentTexture_ = nullptr;
|
||||
|
|
|
|||
|
|
@ -248,9 +248,12 @@ void QuadTree::collectCollisions(
|
|||
if (!current)
|
||||
continue;
|
||||
|
||||
// 确保 ancestorEnd 不超过当前 buffer 大小
|
||||
size_t validAncestorEnd = std::min(item.ancestorEnd, collisionBuffer_.size());
|
||||
|
||||
// 检测当前节点对象与祖先对象的碰撞
|
||||
for (const auto &[obj, bounds] : current->objects) {
|
||||
for (size_t i = item.ancestorStart; i < item.ancestorEnd; ++i) {
|
||||
for (size_t i = item.ancestorStart; i < validAncestorEnd; ++i) {
|
||||
const auto &[ancestorObj, ancestorBounds] = collisionBuffer_[i];
|
||||
if (bounds.intersects(ancestorBounds)) {
|
||||
collisions.emplace_back(ancestorObj, obj);
|
||||
|
|
@ -277,10 +280,15 @@ void QuadTree::collectCollisions(
|
|||
}
|
||||
|
||||
// 恢复祖先列表(模拟递归返回)
|
||||
if (stack.empty() ||
|
||||
(stack.back().ancestorStart != oldSize &&
|
||||
stack.back().ancestorEnd != collisionBuffer_.size())) {
|
||||
// 只有当栈顶元素的祖先范围与当前不同时,才需要恢复
|
||||
if (stack.empty()) {
|
||||
collisionBuffer_.resize(oldSize);
|
||||
} else {
|
||||
const auto& nextItem = stack.back();
|
||||
// 如果下一个节点的祖先范围与当前不同,则需要恢复到其祖先起始位置
|
||||
if (nextItem.ancestorStart != oldSize) {
|
||||
collisionBuffer_.resize(oldSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -528,6 +528,42 @@ void GameOverLayer::initPanel(int score, float screenHeight) {
|
|||
- 引擎会自动在渲染前调用
|
||||
- 如果需要强制更新变换,可以手动调用
|
||||
|
||||
7. **避免双重引用**:
|
||||
- 节点通过 `addChild()` 添加到场景后,由场景统一管理
|
||||
- **不要**额外存储 `shared_ptr` 到 vector 中,避免双重引用问题
|
||||
- 使用 `getChildren()` 访问子节点,配合 `dynamic_cast` 筛选特定类型
|
||||
|
||||
```cpp
|
||||
// ❌ 错误:双重引用
|
||||
class BadScene : public Scene {
|
||||
private:
|
||||
std::vector<Ptr<Sprite>> sprites_; // 不要这样做!
|
||||
public:
|
||||
void createSprite() {
|
||||
auto sprite = Sprite::create(texture);
|
||||
addChild(sprite);
|
||||
sprites_.push_back(sprite); // 双重引用!
|
||||
}
|
||||
};
|
||||
|
||||
// ✅ 正确:通过 getChildren() 访问
|
||||
class GoodScene : public Scene {
|
||||
public:
|
||||
void createSprite() {
|
||||
auto sprite = Sprite::create(texture);
|
||||
addChild(sprite); // 场景统一管理
|
||||
}
|
||||
|
||||
void updateSprites() {
|
||||
for (const auto& child : getChildren()) {
|
||||
if (auto sprite = dynamic_cast<Sprite*>(child.get())) {
|
||||
// 处理 sprite
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- [04. 资源管理](./04_Resource_Management.md) - 深入了解资源加载
|
||||
|
|
|
|||
|
|
@ -64,8 +64,10 @@ public:
|
|||
Scene::onUpdate(dt);
|
||||
|
||||
// 清除之前的碰撞状态
|
||||
for (auto& box : boxes_) {
|
||||
box->setColliding(false);
|
||||
for (const auto& child : getChildren()) {
|
||||
if (auto box = dynamic_cast<CollidableBox*>(child.get())) {
|
||||
box->setColliding(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用场景的空间索引查询所有碰撞
|
||||
|
|
@ -82,11 +84,16 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Ptr<CollidableBox>> boxes_;
|
||||
void createBox(float x, float y) {
|
||||
auto box = makePtr<CollidableBox>(50.0f, 50.0f, Color(0.3f, 0.7f, 1.0f, 0.8f));
|
||||
box->setPosition(Vec2(x, y));
|
||||
addChild(box); // 通过 addChild 管理节点生命周期
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**注意**:节点通过 `addChild()` 添加到场景后,由场景统一管理生命周期。不要额外存储 `shared_ptr` 到 vector 中,避免双重引用问题。
|
||||
|
||||
## 空间索引策略
|
||||
|
||||
### 切换策略
|
||||
|
|
@ -123,18 +130,19 @@ public:
|
|||
Scene::onEnter();
|
||||
|
||||
// 创建100个碰撞节点
|
||||
createNodes(100);
|
||||
createPhysicsNodes(100);
|
||||
|
||||
E2D_LOG_INFO("创建了 {} 个碰撞节点", nodes_.size());
|
||||
E2D_LOG_INFO("空间索引已启用: {}", isSpatialIndexingEnabled());
|
||||
}
|
||||
|
||||
void onUpdate(float dt) override {
|
||||
Scene::onUpdate(dt);
|
||||
|
||||
// 更新所有节点位置
|
||||
for (auto& node : nodes_) {
|
||||
node->update(dt, screenWidth_, screenHeight_);
|
||||
// 更新所有物理节点位置(通过 getChildren() 访问)
|
||||
for (const auto& child : getChildren()) {
|
||||
if (auto node = dynamic_cast<PhysicsNode*>(child.get())) {
|
||||
node->update(dt, screenWidth_, screenHeight_);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用空间索引进行碰撞检测
|
||||
|
|
@ -150,8 +158,10 @@ public:
|
|||
private:
|
||||
void performCollisionDetection() {
|
||||
// 清除之前的碰撞状态
|
||||
for (auto& node : nodes_) {
|
||||
node->setColliding(false);
|
||||
for (const auto& child : getChildren()) {
|
||||
if (auto node = dynamic_cast<PhysicsNode*>(child.get())) {
|
||||
node->setColliding(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用引擎自带的空间索引进行碰撞检测
|
||||
|
|
@ -180,9 +190,25 @@ private:
|
|||
E2D_LOG_INFO("切换到四叉树策略");
|
||||
}
|
||||
}
|
||||
|
||||
// 获取物理节点数量
|
||||
size_t getPhysicsNodeCount() const {
|
||||
size_t count = 0;
|
||||
for (const auto& child : getChildren()) {
|
||||
if (dynamic_cast<PhysicsNode*>(child.get())) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**关键改进**:
|
||||
- 使用 `getChildren()` 代替私有 vector 存储节点引用
|
||||
- 通过 `dynamic_cast` 筛选特定类型的子节点
|
||||
- 避免双重引用,简化生命周期管理
|
||||
|
||||
## 关键要点
|
||||
|
||||
1. **必须调用 `setSpatialIndexed(true)`** - 启用节点的空间索引
|
||||
|
|
|
|||
|
|
@ -72,20 +72,5 @@ target("collision_demo")
|
|||
print("Warning: romfs directory not found at " .. romfs)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 打包时将资源复制到 package 目录
|
||||
after_package(function (target)
|
||||
local target_dir = path.directory(target:targetfile())
|
||||
local assets_dir = path.join(target_dir, "assets")
|
||||
local package_dir = target:packagedir()
|
||||
if os.isdir(assets_dir) and package_dir then
|
||||
local package_assets = path.join(package_dir, "assets")
|
||||
if not os.isdir(package_assets) then
|
||||
os.mkdir(package_assets)
|
||||
end
|
||||
os.cp(path.join(assets_dir, "**"), package_assets)
|
||||
print("Copied assets to package: " .. package_assets)
|
||||
end
|
||||
end)
|
||||
end
|
||||
target_end()
|
||||
|
|
|
|||
|
|
@ -73,20 +73,5 @@ target("flappy_bird")
|
|||
print("Warning: romfs directory not found at " .. romfs)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 打包时将资源复制到 package 目录
|
||||
after_package(function (target)
|
||||
local target_dir = path.directory(target:targetfile())
|
||||
local assets_dir = path.join(target_dir, "assets")
|
||||
local package_dir = target:packagedir()
|
||||
if os.isdir(assets_dir) and package_dir then
|
||||
local package_assets = path.join(package_dir, "assets")
|
||||
if not os.isdir(package_assets) then
|
||||
os.mkdir(package_assets)
|
||||
end
|
||||
os.cp(path.join(assets_dir, "**"), package_assets)
|
||||
print("Copied assets to package: " .. package_assets)
|
||||
end
|
||||
end)
|
||||
end
|
||||
target_end()
|
||||
|
|
|
|||
|
|
@ -72,20 +72,5 @@ target("hello_world")
|
|||
print("Warning: romfs directory not found at " .. romfs)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 打包时将资源复制到 package 目录
|
||||
after_package(function (target)
|
||||
local target_dir = path.directory(target:targetfile())
|
||||
local assets_dir = path.join(target_dir, "assets")
|
||||
local package_dir = target:packagedir()
|
||||
if os.isdir(assets_dir) and package_dir then
|
||||
local package_assets = path.join(package_dir, "assets")
|
||||
if not os.isdir(package_assets) then
|
||||
os.mkdir(package_assets)
|
||||
end
|
||||
os.cp(path.join(assets_dir, "**"), package_assets)
|
||||
print("Copied assets to package: " .. package_assets)
|
||||
end
|
||||
end)
|
||||
end
|
||||
target_end()
|
||||
|
|
|
|||
|
|
@ -72,20 +72,5 @@ target("push_box")
|
|||
print("Warning: romfs directory not found at " .. romfs)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 打包时将资源复制到 package 目录
|
||||
after_package(function (target)
|
||||
local target_dir = path.directory(target:targetfile())
|
||||
local assets_dir = path.join(target_dir, "assets")
|
||||
local package_dir = target:packagedir()
|
||||
if os.isdir(assets_dir) and package_dir then
|
||||
local package_assets = path.join(package_dir, "assets")
|
||||
if not os.isdir(package_assets) then
|
||||
os.mkdir(package_assets)
|
||||
end
|
||||
os.cp(path.join(assets_dir, "**"), package_assets)
|
||||
print("Copied assets to package: " .. package_assets)
|
||||
end
|
||||
end)
|
||||
end
|
||||
target_end()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
#include <cmath>
|
||||
#include <extra2d/extra2d.h>
|
||||
#include <iomanip>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
using namespace extra2d;
|
||||
|
||||
|
|
@ -106,19 +103,15 @@ public:
|
|||
setBackgroundColor(Color(0.05f, 0.05f, 0.1f, 1.0f));
|
||||
|
||||
// 创建100个碰撞节点
|
||||
createNodes(100);
|
||||
createPhysicsNodes(100);
|
||||
|
||||
// 加载字体
|
||||
loadFonts();
|
||||
|
||||
E2D_LOG_INFO("创建了 {} 个碰撞节点", nodes_.size());
|
||||
E2D_LOG_INFO("空间索引已启用: {}", isSpatialIndexingEnabled());
|
||||
}
|
||||
|
||||
void onExit() override {
|
||||
// 先清理 nodes_ 向量
|
||||
nodes_.clear();
|
||||
|
||||
// 显式移除所有子节点,确保在场景析构前正确清理空间索引
|
||||
// 这必须在 Scene::onExit() 之前调用,因为 onExit() 会将 running_ 设为 false
|
||||
removeAllChildren();
|
||||
|
|
@ -131,9 +124,11 @@ public:
|
|||
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// 更新所有节点位置
|
||||
for (auto &node : nodes_) {
|
||||
node->update(dt, screenWidth_, screenHeight_);
|
||||
// 更新所有物理节点位置
|
||||
for (const auto &child : getChildren()) {
|
||||
if (auto node = dynamic_cast<PhysicsNode *>(child.get())) {
|
||||
node->update(dt, screenWidth_, screenHeight_);
|
||||
}
|
||||
}
|
||||
|
||||
auto updateEndTime = std::chrono::high_resolution_clock::now();
|
||||
|
|
@ -149,7 +144,8 @@ public:
|
|||
collisionEndTime - updateEndTime)
|
||||
.count();
|
||||
|
||||
stats_.nodeCount = nodes_.size();
|
||||
// 统计物理节点数量
|
||||
stats_.nodeCount = getPhysicsNodeCount();
|
||||
|
||||
// 获取当前使用的空间索引策略
|
||||
stats_.strategyName = getSpatialManager().getStrategyName();
|
||||
|
|
@ -310,9 +306,9 @@ private:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief 创建指定数量的节点
|
||||
* @brief 创建指定数量的物理节点
|
||||
*/
|
||||
void createNodes(size_t count) {
|
||||
void createPhysicsNodes(size_t count) {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_real_distribution<float> posX(50.0f, screenWidth_ - 50.0f);
|
||||
|
|
@ -326,38 +322,70 @@ private:
|
|||
auto node = makePtr<PhysicsNode>(20.0f, color, static_cast<int>(i));
|
||||
node->setPosition(Vec2(posX(gen), posY(gen)));
|
||||
addChild(node);
|
||||
nodes_.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取物理节点数量
|
||||
*/
|
||||
size_t getPhysicsNodeCount() const {
|
||||
size_t count = 0;
|
||||
for (const auto &child : getChildren()) {
|
||||
if (dynamic_cast<PhysicsNode *>(child.get())) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取所有物理节点
|
||||
*/
|
||||
std::vector<PhysicsNode *> getPhysicsNodes() const {
|
||||
std::vector<PhysicsNode *> nodes;
|
||||
for (const auto &child : getChildren()) {
|
||||
if (auto node = dynamic_cast<PhysicsNode *>(child.get())) {
|
||||
nodes.push_back(node);
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 添加节点
|
||||
*/
|
||||
void addNodes(size_t count) {
|
||||
size_t currentCount = nodes_.size();
|
||||
size_t currentCount = getPhysicsNodeCount();
|
||||
if (currentCount + count > 5000) {
|
||||
E2D_LOG_WARN("节点数量已达上限(5000)");
|
||||
return;
|
||||
}
|
||||
createNodes(count);
|
||||
E2D_LOG_INFO("添加 {} 个节点,当前总数: {}", count, nodes_.size());
|
||||
createPhysicsNodes(count);
|
||||
E2D_LOG_INFO("添加 {} 个节点,当前总数: {}", count, getPhysicsNodeCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 移除节点
|
||||
*/
|
||||
void removeNodes(size_t count) {
|
||||
if (count >= nodes_.size()) {
|
||||
count = nodes_.size();
|
||||
auto physicsNodes = getPhysicsNodes();
|
||||
if (count >= physicsNodes.size()) {
|
||||
count = physicsNodes.size();
|
||||
}
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
// 从后往前移除指定数量的节点
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
removeChild(nodes_.back());
|
||||
nodes_.pop_back();
|
||||
// 找到最后一个物理节点对应的子节点并移除
|
||||
for (auto it = getChildren().rbegin(); it != getChildren().rend(); ++it) {
|
||||
if (dynamic_cast<PhysicsNode *>(it->get())) {
|
||||
removeChild(*it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
E2D_LOG_INFO("移除 {} 个节点,当前总数: {}", count, nodes_.size());
|
||||
E2D_LOG_INFO("移除 {} 个节点,当前总数: {}", count, getPhysicsNodeCount());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -385,8 +413,10 @@ private:
|
|||
*/
|
||||
void performCollisionDetection() {
|
||||
// 清除之前的碰撞状态
|
||||
for (auto &node : nodes_) {
|
||||
node->setColliding(false);
|
||||
for (const auto &child : getChildren()) {
|
||||
if (auto node = dynamic_cast<PhysicsNode *>(child.get())) {
|
||||
node->setColliding(false);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用引擎自带的空间索引进行碰撞检测
|
||||
|
|
@ -442,7 +472,6 @@ private:
|
|||
Color(1.0f, 0.2f, 0.2f, 0.9f));
|
||||
}
|
||||
|
||||
std::vector<Ptr<PhysicsNode>> nodes_;
|
||||
PerformanceStats stats_;
|
||||
float screenWidth_ = 1280.0f;
|
||||
float screenHeight_ = 720.0f;
|
||||
|
|
@ -473,8 +502,7 @@ private:
|
|||
// 程序入口
|
||||
// ============================================================================
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
Logger::init();
|
||||
Logger::setLevel(LogLevel::Debug);
|
||||
|
||||
|
|
|
|||
|
|
@ -72,20 +72,5 @@ target("spatial_index_demo")
|
|||
print("Warning: romfs directory not found at " .. romfs)
|
||||
end
|
||||
end)
|
||||
|
||||
-- 打包时将资源复制到 package 目录
|
||||
after_package(function (target)
|
||||
local target_dir = path.directory(target:targetfile())
|
||||
local assets_dir = path.join(target_dir, "assets")
|
||||
local package_dir = target:packagedir()
|
||||
if os.isdir(assets_dir) and package_dir then
|
||||
local package_assets = path.join(package_dir, "assets")
|
||||
if not os.isdir(package_assets) then
|
||||
os.mkdir(package_assets)
|
||||
end
|
||||
os.cp(path.join(assets_dir, "**"), package_assets)
|
||||
print("Copied assets to package: " .. package_assets)
|
||||
end
|
||||
end)
|
||||
end
|
||||
target_end()
|
||||
|
|
|
|||
Loading…
Reference in New Issue