<COCOS2D-X>

1. HelloWorld 코드 간략 분석

CodeGrimie 2021. 1. 28. 23:21

Main.cpp 코드 간략 분석

다른 프로그램들과 동일하게 진입점의 기능을 하는 코드.

 

 

▼ cocos2d 네임스페이스 사용한다는 의미.

// main.cpp
USING_NS_CC

// CCPlatformMacros.h
#define USING_NS_CC                     using namespace cocos2d

 

▼ 윈도우 운영체제에서 제공하는 윈도우 창 전용 Main 함수로 진입한다.

int WINAPI _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{

}

 

▼ 싱글턴(Singleton)으로 구현되어있다.

AppDelegate app;
return Application::getInstance()->run();

 

싱글턴(Singleton)

단순하게 생각하자면 전역 클라스 하나를 생성하는 걸로 이해된다.

#include <cstdio>

// 싱글턴(Singleton)
// 전역처럼 접근이 가능해야 하고 프로젝트에 단 하나만 존재해야 한다.
class Singleton
{
public:
    static Singleton* GetInstance()
    {
        if (m_instancePtr == nullptr)
        {
            m_instancePtr = new Singleton;
        }
        return m_instancePtr;
    }

private:
    static Singleton* m_instancePtr;

public:
    int m_value;

private:
    // 단 하나만 존재해야 하기 때문에 생성자를 private로 선언해서 문법 단에서 선언을 막는다.
    Singleton() { m_value = 0; }

public:
    void SetValue(int value)
    {
        m_value = value;
    }

    void Print()
    {
        printf("Current m_value is %d\n", m_value);
    };

};

// 전역 객체 초기화
Singleton* Singleton::m_instancePtr = nullptr;

int main()
{
    Singleton::GetInstance()->m_value = 1000;
    Singleton::GetInstance()->Print();
    Singleton::GetInstance()->m_value = 2000;
    Singleton::GetInstance()->Print();

    return (0);
}

 

AppDelegate 간략 분석

게임의 기본적인 데이터들을 정의하고 생성한다.게임을 렌더링 하기 위한 OpenGL 컨텍스트를 생성하고 화면 크기, 해상도를 설정할 수 있다.

 

콜백 함수

 

OpenGL 컨텍스트 속성 설정

void AppDelegate::initGLContextAttrs()
{
    // set OpenGL context attributes: red,green,blue,alpha,depth,stencil,multisamplesCount
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8, 0};

    GLView::setGLContextAttrs(glContextAttrs);
}

기본적으로 RGBA 각각 8비트, 깊이 버퍼 24비트, 스텐실 버퍼 8비트, 멀티샘플링 카운트 0비트를 할당한다.

 

Director Cocos2D-X는 Director를 통해서 게임을 관리한다.게임 생성부터 종료까지 생명주기는 물론이고 렌더링을 비롯한 게임에서 사용되는 부분들을 관리한다.게임의 관리자로서 단 하나만 존재하기 때문에 싱글턴으로 구현되어있다.

 

// 스마트 포인터auto scene = HelloWorld::createScene();

 

CREATE_FUNC()은 매크로로 정의되어 있다.아래의 기이이인 코드를 한줄로 작성할 수 있도록 한 것.

 

게으른 초기화(Lazy Initialize)..?

 

안드로이드 빌드 설정 이슈 정리

기본 HelloWorld 코드가 모바일 기기에서 정상적으로 보이지 않는 이슈가 발생했다.

화면의 크기는 정상적으로 확대가 되었지만 이미지가 원래 리소스 사이즈 그대로 출력되서 너무 작게 나온다.

안드로이드 Landscape/Portrait 변경

처음에는 이방향이 다르게 나오는 이슈라고 생각했다.

결과적으로는 전혀 상관없는 이슈였지만 아무튼 안드로이드에서 가로/세로 화면을 수정할 수 있다는 것을 배웠다.

 

AndroidManifest.xml에서 수정한다.

android:screenOrientation="landscape"

안드로이드 화면 해상도 비율대로 확대

당연한 거였지만 게임 내에서 화면 해상도에 비례해서 확대해야 한다는 걸 깨달았다.

그런데 왜 PC에서 구동한 게임이 안드로이드로 빌드하면 해상도에 비례해서 콘텐츠의 크기가 커지지 않는걸까?

(PC보다 모바일이 더 해상도가 높은 아이러니.)

 

Appdelegate.cpp 에서 비율 조건문 코드를 주석처리 하면 된다.

// Set the design resolution
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);
auto frameSize = glview->getFrameSize();

//// if the frame's height is larger than the height of medium size.
//if (frameSize.height > mediumResolutionSize.height)
//{        
//    director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));
//}
//// if the frame's height is larger than the height of small size.
//else if (frameSize.height > smallResolutionSize.height)
//{        
//    director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));
//}
//// if the frame's height is smaller than the height of medium size.
//else
//{        
//    director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));
//}

아이러니한 상황인데 해상도 크기에 따라 종횡비를 설정하는 코드를 주석 처리하면 정상 작동한다.

 

MIN 매크로를 사용해서 가로 비율과 세로 비율 중 작은 비율에 따라 확대를 해주는데

결정적인 문제는 정상적으로 작동하지 않는다.

 

▼ Director에게 콘텐츠 종횡비 비율을 전달한다.

void Director::setContentScaleFactor(float scaleFactor)
{
    if (scaleFactor != _contentScaleFactor)
    {
        _contentScaleFactor = scaleFactor;
        _isStatusLabelUpdated = true;
    }
}

 

▼ 그 종횡비를 화면 크기에 곱해준다.

Size Director::getWinSizeInPixels() const
{
    return Size(_winSizeInPoints.width * _contentScaleFactor, _winSizeInPoints.height * _contentScaleFactor);
}

코드 구조 상으로는 크게 문제가 되어보이지 않는데

모바일 기기에서 보면 화면 크기만 확대될 뿐 실제 내부 컨텐츠들은 하나도 확대 되지 않았다.