Cocos2d-x 입문 여행[4]장면

6192 단어
우리가 전에 장면도(Scene Graph)의 개념을 말했는데, 계속하기 전에 네가 먼저 알아야 한다.
  • 장면 맵은 장면 내 노드 대상의 렌더링 순서를 결정한다
  • 렌더링할 때 z-order 값이 큰 노드 대상은 나중에 그리고 값이 작은 노드 대상은 먼저 그린다
  • HelloWorld


    Hello World 장면이 어떻게 시작되었는지 기억나세요?우리 프로젝트의 App Delegate를 돌아봐.cpp, applicationDidFinishLaunching()의 끝으로 스크롤:
    // create a scene. it's an autorelease object
    auto helloWorldscene = HelloWorld::createScene();
    // run
    director->runWithScene(helloWorldscene);

    Ctrl+마우스 왼쪽 단추 선택createScene()에서 정의를 보면 이 함수가HelloWorldScnen에서 보입니다.H 내 주장, HelloWorldScnen.cpp 내 정의
    // HelloWorldScnen.h
    static cocos2d::Scene* createScene();
    
    // HelloWorldScnen.cpp
    Scene* HelloWorld::createScene()
    {
        return HelloWorld::create();
    }

    우리는 이 함수를 통해HelloWorld 장면의 대상을 얻을 수 있다
    그 다음은 장면의 초기화, 메뉴, 요정 등 대상의 세트가 모두 이곳에서 진행됩니다.
    bool HelloWorld::init()
    {
        ...
    }

    마지막으로 우리는 리셋 함수를 보았다
    void HelloWorld::menuCloseCallback(Ref* pSender)
    {
        //Close the cocos2d-x game scene and quit the application
        Director::getInstance()->end();
    }

    C++ 기초가 약한 학생은 리셋의 개념을 이해하지 못할 수도 있지만 이 함수가 HelloWorld 장면에서 닫기를 누르면 단추를 누르고 창을 닫는 기능을 실현한다는 것을 알기만 하면 된다.

    SecondScene


    이제 HelloWorld 코드를 보고 SecondScene을 만듭니다.
    HelloWorld와 마찬가지로 우선 SecondScene이 필요합니다.h 선언을 저장하고 SecondScene을 저장합니다.cpp 저장 정의
    VS 내에 새 파일을 만들 때 반드시Class 폴더에 저장해야 합니다. 그렇지 않으면include 'xxxxx' 를 직접 저장할 수 없습니다. (모든 악의 VS 기본 저장 경로는Class가 아닙니다)
    프로젝트 디렉토리의 Class로 수정

    SecondScene.h


    우선 처음부터 끝까지 매크로 보호
    #ifndef __SECOND_SCENE_H__
    #define __SECOND_SCENE_H__
    
    #endif // __SECOND_SCENE_H__

    그리고 나서
    #include "cocos2d.h"

    지금부터 우리는 약간의 변화를 해야 한다. SecondScene이 Scene이 아니라 Layer를 계승하도록 하자
    class SecondScene : public cocos2d::Layer {
    public:
        static cocos2d::Scene* createScene();
        virtual bool init();
        CREATE_FUNC(SecondScene);
        // 
    };

    실제로 이전의 코코스 실례 프로젝트에서 Hello World는 모두 Layer로부터 계승된 것이었는데, 왠지 지금은 바뀌었지만, 이 기회를 빌려 Layer와 Scene의 차이점을 소개하겠습니다.

    SecondScene.cpp


    일단은 인클로드. 저희가 전에 썼던 SecondScene.h, 편의를 위해 우리도 HelloWorld와 같다using namespace cocos2d너는 아마 Hello World를 보았을 거야.cpp에는 USING_NS_CC라고 쓰여 있지만, 사실 효과는 같다
    다음은creatSceen () 함수를 정의합니다.HelloWorld::createScene () 와는 약간 다릅니다.
    Scene* SecondScene::createScene() {
        // Scene scene
        auto scene = Scene::create();
        // SecondScene layer
        auto SecondScene = SecondScene::create();
        // layer scene 
        scene->addChild(layer);
        // scene
        return scene;
    }

    이해하기는 매우 간단하다. 우선 우리는 Scene 클래스의 대상scene를 만들고 SecondScene 클래스의 대상layer를 만들었다.
    이제 초기화 함수를 쓸 수 있어요.
    bool SecondScene::init() {
        auto visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
        Label* label = Label::create("Second Test", "fonts/Marker Felt.ttf", 24);
        label->setPosition(
            Vec2(
                origin.x + visibleSize.width / 2,
                origin.y + visibleSize.height - label->getContentSize().height
            )
        );
        
        this->addChild(label);  //  z-order=0
    
        return true;
    }
    

    우리는 너무 많은 것을 넣지 않고 label에 가입해서 Second Scene 장면이라는 것을 알게 하면 된다. 지금 우리는 프로그램의 입구인 App Delegate로 간다.cpp에서 HelloWorld 장면을 시작하는 두 줄 코드를 기억하십니까? SecondScene 장면을 시작하는 것으로 바꾸겠습니다.using namespace cocos2dAppDelegate에 먼저 가입하는 것을 잊지 마세요.cpp)
    // create a scene. it's an autorelease object
    auto helloWorldscene = HelloWorld::createScene();
    // run
    director->runWithScene(helloWorldscene);
    

    ... 로 바꾸다
    auto secondScene = SecondScene::createScene();
    director->runWithScene(secondScene);
    

    테스트를 실행하려면 다음과 같이 하십시오.
    문제없다

    장면 전환


    다음은 AppDelegate.cpp 복원 (Crtl + Z) 을 사용하면 프로그램이 실행될 때HelloWorld 장면에서 시작하고, 리셋 함수를 사용하여SecondScene로 전환합니다.
    HelloWorld에서 Second로 전환해야 하기 때문에 HelloWorld 장면에 리셋 이벤트를 추가해야 합니다. 마침 HelloWolrd에 닫기 단추가 있는 리셋이 있습니다. 코드를 바꾸면 됩니다. (여기서 중요한 것은 어떻게 전환하는지 보여주는 것입니다. 정말 게으른 것이 아닙니다)
    추적#include "SecondScene.h":HelloWorld::menuCloseCallback()를 바꾸다
    Director::getInstance()->replaceScene(
        SecondScene::createScene()
    );
    

    테스트를 실행하고 의외의 사고가 발생하지 않도록HelloWorld 오른쪽 아래에 있는 닫기 버튼을 누르면 순식간에 Second로 전환됩니다

    애니메이션 전환


    코코스에는 장면을 전환하는 애니메이션이 많이 내장되어 있다. 예를 들어
    Director::getInstance()->replaceScene(
        TransitionSlideInT::create(
            3.0f, SecondScene::createScene()
        )
    );
    

    실행하면 Second가 3초 안에 위에서 HelloWorld를 부드럽게 전환합니다
    다른 전환 애니메이션은 군더더기 없이 Actions와 또 다른 묘미를 지니고 있으니 각자 시험해 보자

    장면 스택


    우리는 이전에 모두 Replace Scene을 사용하여 장면 전환을 했다. Replace Scene는 이전 장면을 방출할 수 있다. (간단하게 말하면 삭제해서 메모리를 차지하지 않고 다시 만들고 싶으면 하나만 만들 수 있다) 메모리 자원을 절약할 수 있지만 때때로 우리는 장면이 방출되기를 원하지 않는다. 어떡하지?
    코코스는 추진Director::getInstance()->END과 팝업pushScene() 두 가지 방법을 제공하여 일련의 장면을 창고에 저장하고 수요에 따라 팝업(방출)과 새로운 장면을 추진한다.
    창고는 하나의 데이터 구조로 간단하게 하나의 탄창으로 이해할 수 있으며 창고에 대해 두 가지 조작이 있다.
  • 입고(push), 총알 장착
  • 출고(pop), 총알
  • 총알은 항상 맨 위에 먼저 발사된다(pop시 창고 꼭대기의 원소가 가장 먼저 창고에서 나온다), 즉'선진후출'
    새로 장면에 가입할 때 사용popScene하면 신구 장면은 장면 창고에 저장되고 신구는 상구재하(즉 낡은 장면이 풀리지 않았다는 뜻)pushScene()는 새로운 장면을 풀고 낡은 장면은 원래의 위치로 튀어나와 옛 장면을 표시한다.
    장면 초기화 함수에 x초를 기다리는 코드를 쓸 수 있습니다. (사고방식을 바꾸면 타이머를 쓸 수 있습니다.) 팝을 검증한 후에 표시된 옛 장면이 새로 만들어진 것이 아닙니다.
    bool HelloWorld::init()
    {
        ... 
            
        for(int i = 0; i <19999999; i++)//     
            
        ...
    }
    

    너의 기발한 생각을 발휘하고, 또 어떤 방법이 있는지 스스로 실험해 보아라

    레이어 및 장면


    이것은 이해하기 쉽다. 네가 했던 2d 게임이나 포토샵의 도층 인터페이스를 생각해 보자. 한 장면에 여러 층이 있을 수 있다.
    장면 내의 레이어 생성은 간단합니다.
    Layer* layer2 = Layer::create();
    

    물론 한 층은 반드시 장면에 추가해야만 효력이 발생하며, 층은 장면을 떠나 독립적으로 존재할 수 없다
    이후의 학습에서 우리는 층의 작용을 한층 더 체득할 것이다

    좋은 웹페이지 즐겨찾기