2026-03-02 04:50:28 +08:00
|
|
|
|
#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_) {
|
2026-03-16 18:38:45 +08:00
|
|
|
|
if (comp.get() != transform_ && comp->isEnabled()) {
|
2026-03-02 04:50:28 +08:00
|
|
|
|
comp->update(dt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& child : children_) {
|
|
|
|
|
|
child->update(dt);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Node::render() {
|
|
|
|
|
|
if (!visible_) return;
|
|
|
|
|
|
|
2026-03-16 18:38:45 +08:00
|
|
|
|
if (children_.empty() && components_.size() == 1) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-02 04:50:28 +08:00
|
|
|
|
for (auto& comp : components_) {
|
2026-03-16 18:38:45 +08:00
|
|
|
|
if (comp.get() != transform_ && comp->isEnabled()) {
|
2026-03-02 04:50:28 +08:00
|
|
|
|
comp->render();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& child : children_) {
|
|
|
|
|
|
child->render();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace extra2d
|