Skip to content

cocos2d x 3.3 008 核心概念和相关类 场景

cheyiliu edited this page Jan 19, 2015 · 4 revisions

场景概述

  • 继承自Node
  • It is a good practice to use a Scene as the parent of all your nodes
  • 场景跟Node的主要区别是场景默认锚点不同,其他基本和Node一样

主要API

创建

  • create createWithSize

相机

  • getCameras

光源

  • getLights

渲染

  • render

物理引擎

  • getPhysicsWorld createWithPhysics

走马观花看代码

1. 构造函数,
Scene::Scene()
#if CC_USE_PHYSICS
: _physicsWorld(nullptr)
#endif
{
    _ignoreAnchorPointForPosition = true;
//设置锚点为中心
    setAnchorPoint(Vec2(0.5f, 0.5f));
    
    //create default camera
    _defaultCamera = Camera::create();
    addChild(_defaultCamera);
    
// 添加事件监听器, 在Director::EVENT_PROJECTION_CHANGED发生时回调onProjectionChanged
    _event = Director::getInstance()->getEventDispatcher()->addCustomEventListener(Director::EVENT_PROJECTION_CHANGED, std::bind(&Scene::onProjectionChanged, this, std::placeholders::_1));
    _event->retain();
}


2. 析构
Scene::~Scene()
{
#if CC_USE_PHYSICS
    if (_physicsWorld)
    {
        g_physicsSceneCount--;
    }
    CC_SAFE_DELETE(_physicsWorld);
#endif

//取消注册的事件监听
    Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
    CC_SAFE_RELEASE(_event);
}

3. onProjectionChanged
void Scene::onProjectionChanged(EventCustom* event)
{
    if (_defaultCamera)
    {
//重新初始化
        _defaultCamera->initDefault();
    }
}

4. void Scene::render(Renderer* renderer)
render跟opengl紧密相关了, 不懂, 略
急需涨opengl相关的姿势。。。

5. update
void Scene::update(float delta)
{
//基类的update
    Node::update(delta);
    if (nullptr != _physicsWorld && _physicsWorld->isAutoStep())
    {
//物理引擎相关的update
        _physicsWorld->update(delta);
    }
}

6. 跟物理引擎相关的构建函数
Scene* Scene::createWithPhysics()
{
//两段构造
    Scene *ret = new (std::nothrow) Scene();
    if (ret && ret->initWithPhysics())
    {
        ret->autorelease();
        return ret;
    }
    else
    {
        CC_SAFE_DELETE(ret);
        return nullptr;
    }
}

bool Scene::initWithPhysics()
{
    bool ret = false;
    do
    {
        Director * director;
        CC_BREAK_IF( ! (director = Director::getInstance()) );
        
        this->setContentSize(director->getWinSize());
        CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this)));

//开启update(timer),每帧调用update
        this->scheduleUpdate();
        // success
        g_physicsSceneCount += 1;
        ret = true;
    } while (0);
    return ret;
}

void Scene::addChildToPhysicsWorld(Node* child)
{
    if (_physicsWorld)
    {
        std::function<void(Node*)> addToPhysicsWorldFunc = nullptr;
        addToPhysicsWorldFunc = [this, &addToPhysicsWorldFunc](Node* node) -> void
        {
            if (node->getPhysicsBody())
            {
//将node自己加入物理世界
                _physicsWorld->addBody(node->getPhysicsBody());
            }
        
//将childe加入物理世界    
            auto& children = node->getChildren();
            for( const auto &n : children) {
                addToPhysicsWorldFunc(n);
            }
        };
        
        addToPhysicsWorldFunc(child);
    }
}

小结

  • 场景继承自Node变有了Node的各自属性
  • 场景特有的属性有和物理引擎相关的PhysicsWorld, 和opengl相关的BaseLight Camera
  • 场景若启用了物理引擎,则他的物理引擎相关的更新代码在update函数
  • 场景默认锚点是他的中心
  • cocos官方建议'It is a good practice to use a Scene as the parent of all your nodes.'
Clone this wiki locally