2015.10.14 00:53



Eclipse 상으로 Project 를 불러온 이후에 (시작하기02 참고) Visual Studio 나 다른 개발 Tool 을 이용하여 Project 의 Root 폴더상에 Classes 의 코드를 수정 한 이후에 .so build를 해주어 .so 파일 생성을 한다.

ProjectName/proj.android 폴더 상에 존재하는 build_native.py 파일을 실행. (해당 Script 를 이용하기 위해서는 python 환경 설정 되어 있어야 합니다.)


정상적으로 so 빌드가 되지 않는 경우 (couldnt find "libcocos2dcpp.so" 에러 발생)

ProjectName/proj.android/jni 폴더에 Android.mk 파일에 Build Script 에서 Classes 폴더의 모든 CPP 파일이 정상 빌드 되도록 수정하여 야합니다. (시작하기02 참고)





신고


Posted by injunech
2015.10.12 01:51


이 글에서는 이클립스를 사용한 Cocos2d-x 3.2 프로젝트 빌드 및 발견된 빌드 문제 해결 방법을 다룹니다


커멘드창을 이용하지 않고 이클립스를 사용하는 이유는 다음과 같습니다:

  • 세팅이 된 다음엔 빌드 및 스마트폰에의 실행이 아주 쉽다

  • 이클립스를 통해 디버깅이 가능

  • 이클립스를 통해 개발이 가능

  • 최신 버전의 서브시스템에 (ndk10...)에 간단히 대응

    • 굳이 최신 버전을 고집할 필요는 없지만(ndk9로 충분. 대부분은 ndk9를 사용하는 것 같습니다)

    • 그러나 최신 버전을 고집하면 프로젝트의 생명주기가 길어지죠.

  • 빌드에 사용될 cocos 라이브러리, 안드로이드 라이브러리를 언제든 쉽게 수정 가능



빌드 환경



  • Intel 64bit CPU
  • Windows7 64bit
  • Visual Studio 2013
  • Python 2.7
  • cocos2d-x 3.2
  • ndk10
  • ant1.9.4
  • Eclipse Luna
  • Android API 10 (2.3.3)
  • Java7



시작하기 전에



cocos2d-x 3.2를 안드로이드에 맞추어 빌드하는 과정은 굉장히 손이 많이 가는 작업입니다.

아래의 과정 중 단 하나라도 놓치면 빌드에 성공할 수 없습니다.

인내심을 가지고 아래의 과정을 하나하나 밟아가세요.





이클립스에 프로젝트 추가





File-Import-Existing Projects into Workspace를 선택하고

프로젝트 위치는 해당 게임 프로젝트\proj.android를 선택하면 됩니다.


Copy projects into workspace 옵션은 사용하지 마세요! 소스코드는 언제든지 변경 가능해야 하니까요.





프로젝트 설정



Import된 프로젝트는 기본적으로 설정이 맞게되어 있지 않습니다.

이클립스 환경에 맞게 프로젝트를 변경하도록 합니다.


1. cocos2d-x Andoird Library Project 추가

**이 1번 과정은 딱 한번만 하면 됩니다. 다른 게임 프로젝트를 다루게 되더라도 반복할 필요 없습니다.


File-Import-Existing Projects into Workspace를 선택하고


프로젝트 위치는 cocos2d-x 설치 디렉토리\cocos\platform\android\java를 선택하면 됩니다.

예) C:\cocos2d-x\cocos\platform\android\java


Copy projects into workspace 옵션을 선택하세요! 코코스 엔진 원본 소스코드는 건드려봤자 좋을게 없겠죠.




2. 프로젝트 설정 변경


여러분이 작성한 게임 프로젝트를 선택하고 Properties로 들어갑니다.

그리고 아래의 스크린샷을 따라서 라이브러리 설정을 고칩니다.








3. 문제 있는 소스코드 변경


3-1> 엔진 오타 수정


프로젝트/cocos2d/cocos/3d/CCBundleReader.h의 tell()함수 부분을

long int tell(); 에서

ssize_t tell(); 로 변경하세요


왜 그런지 모르겠지만 cocos2d-x 3.2자체에 문제가 있네요. 반환형이 잘못되어 있습니다 --;



3-2> 자동 CPP 소스파일 추적 및 추가

프로젝트/jni/Android.mk 파일을 수정합니다

LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp
부분을

FILE_LIST := $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES += hellocpp/main.cpp


로 변경합니다.


Classes폴더 안에 있는 모든 cpp파일을 자동으로 빌드 시에 포함시키도록 변경하는 것입니다.

물론 LOCAL_SRC_FILES부분을 늘려나가도 되겠지만 그런 바보같은 수고를 할 사람은 없겠죠.




4. 실행


에뮬레이터가 아닌 실제 안드로이드 스마트폰을 사용하시는 걸 추천합니다

Ctrl+B를 눌러 빌드하시고

프로젝트 우클릭->Run AS->Android Application을 누릅니다




5. 끝!


이제 여러분이 개발한 게임이 안드로이드에서 실행되는걸 볼 수 있습니다

끝없이 해결해야할 게임버그는 잠시 잊으시고 행복해 하셔도 좋습니다.





PLUS+

혹시 Visual Studio에서는 잘됐는데 다른 플랫폼에서 한글이 깨지거나

빌드 도중 error: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security] 메시지가 발생하면

아래의 추가 문제 해결을 참조하세요




추가 문제 해결



1. 로그로 인해 발생하는 빌드 에러 해결

error: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security] 에러 해결 방법입니다.


프로젝트/jni/Application.mk 파일의


APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -std=c++11 -fsigned-char

APP_LDFLAGS := -latomic

부분을


APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -std=c++11 -fsigned-char

APP_CPPFLAGS += -Wno-error=format-security

APP_LDFLAGS := -latomic

로 변경하세요


[문제가 생긴 이유]




2. 한글 깨짐 해결


Visual Studio에서는 잘만 출력되던 한글이 다른 플랫폼(안드로이드,IOS)에서 깨진다면

파일의 저장 형식이 잘못되었을 확률이 높습니다.


STEP1>

Visual Studio에서 한글이 들어있는 소스코드를 띄웁니다. 그리고 나서 파일->고급 저장 옵션을 열어

인코딩

유니코드(서명 있는 UTF-8)

줄 끝

Unix

로 설정하세요.



STEP2>

또한 이클립스 프로젝트의 Properties을 아래와 같이 설정합니다.



출처 : http://makerj.tistory.com/156



----------------------------------



위 작업을 완료 한 뒤에 추가로 발생 하는 아래와 같은 에러는

다음 방법으로 해결 ㅎ


1) cannot find : cocod2d-x libcocos2dcpp.so

2) The import org.cocos2dx.lib cannot be resolved





1) cannot find : cocod2d-x libcocos2dcpp.so


NDK 빌드

일단 명령프롬프트(윈도우버튼 > 프로그램파일검색 창에서 cmd)를 엽니다. 다음과 같이 cd 명령을 수행해서 앞서 새로 만든 프로젝트의 proj.android폴더로 이동합니다.(역시 폴더 이름은 각자의 것에 맞게)

이제 NDK 빌드를 하기 위해 파이썬 스크립트를 수행합니다.

> build_native.py

그럼 컴파일이 쫙쫙쫙 수행됩니다. 빌드 후 메시지가 다음과 같이 나오며 proj.android\libs\armeabi에libcocos2dcpp.so 파일이 생성되면 NDK 빌드가 완료 된 것입니다.


설정 파일 변경

이제 libcocos2dcpp.so를 Java와 연결하고 빌드하여 APK 파일을 생성하면 됩니다. 그 전에 설정 좀 바꿔줘야 할 것이 있습니다.

일단 AndroidManifest파일의 수정이 필요합니다. 안드로이드 프로젝트의 속성 파일이라고 생각하시면 됩니다. proj.android 디렉터리에 있는 AndroidManifest.xml 파일을 문서편집기로 열어 다음과 같이 sdk 버젼이 9로만 되어 있는 것을 

<uses-sdk android:minSdkVersion="9"/>

다음과 같이 target을 14로, min을 10으로 바꾸어줍시다.

<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/>

여기서 가리키는 SdkVersion은 앞서 ADT에서 설치했던 API 레벨을 의미합니다. 수정 전에 입력되어 있던 9는 전설속에만 존재하는 API고, 우린 전설을 믿지 않으니 수정해 주는겁니다. 기왕이면 target SDK를 구글에서 권장하는 14레벨로 설정합니다. API14는 4.0 아이스크림샌드위치인데 그럼 그 이하 버젼은 지원을 안하는 것이냐!? 그건 걱정하지 맙시다. 하위 OS 호환성을 위해서 targetSdkVersion과 minSdkVersion이 따로 있습니다. 최소 지원 SDK 값을 10으로 지정해줘서 2.3.3 생강빵 이상에서 돌아가게 해줍니다. 사실상 현존하는 최소 버젼은 API8 2.2 프로요이긴 하지만 target을 14로 설정하면 8의 설정과 충돌나는 부분이 있어서 애석하게도 사용하지 못합니다. 2.2 프로요는 아직 점유율이 2.7%나 되서 버리기에는 조금 아깝긴합니다. 하지만 타겟을 4.0 아이스크림샌드위치로 설정해야 태블릿에서 검색 가능하기때문에 살을 내주고 뼈를 취하는게 낫습니다.



2) The import org.cocos2dx.lib cannot be resolved



proj.android/src 폴더에 들어가 보시면 org/cocos2dx   폴더가 있을겁니다 이 내부가 비어 있는건 아닌지 확인해 보세요.

원래 create-android-project.sh를 실행했을때 이부분이 자동으로 채워져야 하는데 생성이 되지 않는 경우가 있습니다. 이런경우엔 수동으로 복사해 주면 되는데요.

 cocos2d-x-3.6/cocos/platform/android/java/src/에 들어가보시면 같은 구조의 디렉토리가 존재합니다.   이안에 있는 org 폴더를 통채로 복사해서 proj.android/src/ 에 그대로 복사해 붙여 넣은후 eclipse 에서 f5버튼으로 reflash 한후에 다시 빌드


신고


Posted by injunech
2015.10.12 01:33


Cocos2D-x 3.2에는 파이썬 스크립트 project-creator가 사라졌습니다 ㅠㅠ

따라서 콘솔 명령으로 생성해야 합니다.


 > Project name : GAME01 

 > Package name : com.cij.game01

 > Project directory : C:\Workspace\COCOS2D_Proejct\

 

라고 가정하고 생성하는 예시입니다


C:\cocos2d-x-3.6\tools\cocos2d-console\bin>

위와 같이 cocos2d-x 설치한 폴더 경로 내에 consol 폴더 내부 bin 에서 커맨드 창 실행하고 다음과 같은 명령어로 프로젝트를 생성 합니다.

python cocos.py new GAME02 -p com.cij.game01 -l cpp -d C:\Workspace\COCOS2D_Proejct\


위 방법은 cocos 에서 제공하는 Python 스크립트를 이용하여 프로젝트 생성하는 방법이며 다음 방법으로도 생성 가능합니다. (cocos 설치 폴더 환경 설정 완료 이후.)

cocos new GAME01 -p com.cij.game01 -l cpp -d C:\Workspace\COCOS2D_Proejct\

 

# 명령어 의미

'cocos new 게임이름 ?p 패키지명 ?l 사용할언어 ?d 프로젝트저장경로'



에러가 발생하지 않았다면 새 프로젝트 생성에 성공한 것입니다.



프로젝트 폴더 내의 proj.win32안에 있는 Visual Studio Solution파일을 실행하면 이제 Visual Studio에서 제작이 가능해집니다.



신고


Posted by injunech
2015.08.23 22:46


1. Node

cocos2d-x의 기본 단위

거의 모든 객체들은 이 Node클래스를 상속받는다. 이것만 잘 알아도 cocos2d-x의 많은 부분을 알수 있다.

http://www.cocos2d-x.org/reference/native-cpp/V3.0alpha0/d3/d82/classcocos2d_1_1_node.html

Node의 멤버들..

-position : 위치 값,

-scale : 크기 배율값,

-rotation : 회전 각도,

-anchor point : 앵커 포인터(위치값의 기준 점을 설정 0~1까지 float),

-size : width, height,

-visible : 보이는지 여부,

-z-order : 출력시 위에 보이느냐 아래 보이느냐를 결정하는 수치

node->setPosition(Point(0, 0));
//대부분의 속성값은 get / set으로 사용가능

부모자식관계

Node의 가장 중요한 특징은 부모자식관계라고 생각한다. 클래스 상속과는 별개의 영역이며, 햇갈려서는 안된다.

자식은 부모의 영역안에서 상대적인 좌표로 이동, 회전, 스케일된다. 예를 들어 부모노드가 100, 100 좌표에 위치한다면, 그 자식인 노드의 좌표값이 0, 0 이라도 부모노드의 상대적 좌표값이 적용되어 실제로 전체화면에서는 100, 100 좌표에 있는 것 처럼 보인다.

반대로 여러 자식들을 가지고 있는 부모노드의 위치 스케일 등을 변경하면 그 안에 들어있는 모든 자식노드들의 값이 한꺼번에 변경된다. 이 때문에 부모 노드는 자식 노드를 담는 컨테이너로 사용되기도 한다.

parent->setPosition(Point(100, 100)); // 부모를 100, 100위치에 놓는다.
auto child = Node::create(); //자식을 만든다.
child->setPosition(Point(0,0));//자식을 0,0에 놓는다.
parent->addChild(child) //자식이 100, 100자리에 그려진걸 보고서 당황하지 않는다.

스마트 포인터

Node를 상속받는 모든 클래스들은 CREATE_FUNC(ClassName)으로 등록하면, ClassName::create()하는 것만으로 자동으로 메모리를 할당하고 알아서 해제가 된다.

새로운 인스턴스 생성할때, virtual bool init()이라는 함수를 자동으로 호출하므로 반드시 init함수의 형태를 구현해두어야한다.

기본적으로 레퍼런스 카운트 방식을 사용한다. addChild(node)하면 알아서 카운트가 1이 증가하고, removeChild(node)하면 카운트가 1줄어든다. 카운트가 0이되면 사라진다.

만약 할당한 메모리를 유지하고 싶다면, 인스턴스 객체에 node.retain()을 걸어주면 수동으로 카운트가 1 증가한다. 반대로 node.release()를 걸어주면 수동으로 카운트가 1 줄어든다. 하지만 메모리 릭이 발생하지 않도록 주의해서 관리해야한다.

스케쥴

http://injakaun.tistory.com/102

노드를 상속받은 클래스들은 스케쥴을 통해 게임 루프를 처리해주는 스케쥴러에 특정 함수를 등록할 수 있다. 스케쥴로 등록한 함수는 게임 루프시마다 호출된다. 주로 각 객체의 update함수들이 등록되어 루프할때마다 호출된다.

schedule( schedule_selector( GameLayer::update ) , 0.1f );
//schedule_selector의 인자로 함수포인터를 넘겨주는데, 반드시 앞에 어떤 클래스의 함수인지를 써줘야한다.
//그리고 뒤에 이 함수가 실행되는 딜레이를 적어준다.
scheduleUpdate(); //귀찮으면 이걸 쓴다. 대신 update함수는 노드에서 제공하는 형식을 맞춰줘야한다.

무작정 스케쥴업데이트를 사용하면 업데이트 순서가 꼬일 수 있으니 주의하자. 자식노드의 업데이트를 부모노드의 업데이트에 몰아서 한큐에 처리하는 방식으로 꼬임 문제를 해결하였다. sheduleUpdateWithPriority를 사용하는 것도 방법이 될 수 있을 거라 생각한다.

unschedule을 통해서 스케쥴러에서 제외시킬 수 있고, pause와 resume을 통해 잠시 멈췄다가 다시 수행하게 할 수 있다. scheduleOnce를 잘쓰면 괜히 여러번 호출할 필요없이 한번만 불러오게 할 수도 있다.

*removeChild이나 changeScene을 하면 그 안에 있던 객체는 retain을 해서 남아있더라도 그 객체에서 shedule된 함수들이 스케쥴러에서 제외된다. 제외된 함수들은 다시 스케쥴러에 넣어주지 않는한 루프에 호출되지 않는다.

2.Node의 상속자들

cocos2d::Scene / cocos2d::Layer / cocos2d::Sprite

Director

디렉터는 Node의 상속자는 아니지만 다른 상속자들과 밀접한 관련이 있기에 미리 언급하고 넘어간다. 디렉터는 cocos2d-x 내부에 있는 싱글톤 클래스로 화면을 관리하는 역할을 담당한다. 주로 화면에 출력할 Scene을 선택하고 전환하는 역할로 사용되었다. 추가로 다양한 씬 전환기법도 제공한다.

http://injakaun.tistory.com/98

Director::runWithScene(menuScene); //일단 디렉터로 씬하나 띄워야 뭐가 실행된다.
Director::getInstance()->replaceScene(gameScene); //적당히 조건에 맞게 씬을 변경한다.
//replaceScene을 하면 기존에 있던 씬은 제거(refCount--)된다. 추가로 업데이트들도 스케쥴에서 제외되므로 주의한다.

Scene

씬은 cocos2d-x에서 가장 기본이 되는 화면이다. Node의 상속자들의 부모자식관계망에서 제일 꼭대기에 위치한다. Scene에는 직접 스프라이트같은걸 붙이지는 않는다. 세부적인 화면 형태는 Layer에서 결정하고, 그런 Layer들을 모아서 한번에 출력하는 컨테이너로 Scene을 사용하는게 편리하다.

Layer

Layer도 Scene이랑 크게 다를것은 없으나 Scene과는 달리 여러개가 동시에 한 화면에 올릴 수 있기 때문에 각 분류에 따라 만들어지는 경향이 있다. 우리 프로젝트에서도 UI, Game, Background Layer들로 나누어서 각각 자신의 처리를 할 수 있게 하였다. 그리고 각 레이어들의 z축 값을 다르게 줘서 특정 레이어를 위에 특정 레이어를 아래 배치할 수도 있다.

auto gameLayer = Layer::create(); //게임 레이어를 만들어줍니다.
auto uiLayer = Layer::create(); //UI레이어도 만들어요
auto gameScene = Scene::create(); //게임이 돌아가느 화면인 게임씬을 만들고
gameScene->addChild(gameLayer, 1); //게임 레이어를 게임씬에 붙입니다. z축 값을 1로줘서 
gameScene->addChild(uiLayer, 2); //z축 값을 2 로 줘서 들어간 ui레이어는 항상 게임레이어보다 위에 출력됩니다.
Director::runWithScene(gameScene); //이걸 디렉터한테 실행시킵니다.

Sprite

실제 이미지가 올라가는 대부분의 노드가 Sprite이다. Sprite도 다른 Sprite를 자식노드로 가질 수 있기 때문에, 플레이어스프라이트에 장비스프라이트를 자식 노드로 붙여 계속 플레이어를 따라다니는 것처럼 만들어 줄 수 있다.

그리고 스프라이트는 여러장의 이미지들을 계속 변경하는 에니메이션을 추가하여 실제 움직이는 객체처럼 만들어 줄 수도 있다.

신고


Posted by injunech
2015.07.12 13:27


Cocose2d-x 를 Android (eclipse) 개발 환경에서 Class 추가 필요 없이 자동으로 Classes 폴더를 읽어서 넣는 방법입니다.


자신의 프로젝트 > proj.android > jni > Android.mk


아래 부분과 같이 변경한다.


FILE_LIST := $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp)

LOCAL_SRC_FILES := hellocpp/main.cpp $(FILE_LIST:$(LOCAL_PATH)/%=%) 

신고


Posted by injunech

티스토리 툴바