Extra2D/src/scene/node.cpp

208 lines
4.2 KiB
C++
Raw Normal View History

#include <scene/node.h>
#include <scene/components/transform_component.h>
namespace extra2d {
Node::Node() {
// 自动添加 TransformComponent
auto transform = makePtr<TransformComponent>();
transform_ = transform.get();
components_.push_back(transform);
transform_->onAttach(this);
}
Node::~Node() {
// 先分离所有组件
for (auto& comp : components_) {
comp->onDetach();
}
components_.clear();
// 移除所有子节点
removeAllChildren();
// 从父节点移除
if (parent_) {
parent_->removeChild(this);
}
}
void Node::addChild(Ptr<Node> child) {
if (!child || child.get() == this) return;
// 从原父节点移除
if (child->parent_) {
child->parent_->removeChild(child.get());
}
child->parent_ = this;
children_.push_back(child);
}
void Node::removeChild(Node* child) {
if (!child) return;
for (auto it = children_.begin(); it != children_.end(); ++it) {
if (it->get() == child) {
child->parent_ = nullptr;
children_.erase(it);
return;
}
}
}
void Node::removeFromParent() {
if (parent_) {
parent_->removeChild(this);
}
}
void Node::removeAllChildren() {
for (auto& child : children_) {
child->parent_ = nullptr;
}
children_.clear();
}
// ========================================
// 变换便捷接口
// ========================================
void Node::setPosition(const Vec2& pos) {
if (transform_) {
transform_->setPosition(pos);
}
}
void Node::setPosition(float x, float y) {
setPosition(Vec2(x, y));
}
Vec2 Node::getPosition() const {
return transform_ ? transform_->getPosition() : Vec2(0, 0);
}
void Node::setRotation(float rot) {
if (transform_) {
transform_->setRotation(rot);
}
}
float Node::getRotation() const {
return transform_ ? transform_->getRotation() : 0.0f;
}
void Node::setScale(const Vec2& scale) {
if (transform_) {
transform_->setScale(scale);
}
}
void Node::setScale(float scale) {
setScale(Vec2(scale, scale));
}
void Node::setScale(float x, float y) {
setScale(Vec2(x, y));
}
Vec2 Node::getScale() const {
return transform_ ? transform_->getScale() : Vec2(1, 1);
}
void Node::setSize(const Vec2& size) {
if (transform_) {
transform_->setSize(size);
}
}
void Node::setSize(float width, float height) {
setSize(Vec2(width, height));
}
Vec2 Node::getSize() const {
return transform_ ? transform_->getSize() : Vec2(100, 100);
}
void Node::setAnchor(const Vec2& anchor) {
if (transform_) {
transform_->setAnchor(anchor);
}
}
void Node::setAnchor(float x, float y) {
setAnchor(Vec2(x, y));
}
Vec2 Node::getAnchor() const {
return transform_ ? transform_->getAnchor() : Vec2(0.5f, 0.5f);
}
Transform Node::getWorldTransform() const {
return transform_ ? transform_->getWorldTransform() : Transform();
}
Mat4 Node::getWorldMatrix() const {
return transform_ ? transform_->getWorldMatrix() : Mat4();
}
// ========================================
// 生命周期
// ========================================
void Node::onEnter() {
// 通知所有组件
for (auto& comp : components_) {
// 组件没有 onEnter可以在这里扩展
}
// 递归通知子节点
for (auto& child : children_) {
child->onEnter();
}
}
void Node::onExit() {
// 递归通知子节点
for (auto& child : children_) {
child->onExit();
}
// 通知所有组件
for (auto& comp : components_) {
// 组件没有 onExit可以在这里扩展
}
}
void Node::update(float dt) {
for (auto& comp : components_) {
if (comp.get() != transform_ && comp->isEnabled()) {
comp->update(dt);
}
}
for (auto& child : children_) {
child->update(dt);
}
}
void Node::render() {
if (!visible_) return;
if (children_.empty() && components_.size() == 1) {
return;
}
for (auto& comp : components_) {
if (comp.get() != transform_ && comp->isEnabled()) {
comp->render();
}
}
for (auto& child : children_) {
child->render();
}
}
} // namespace extra2d