cocos2d-x 3.x이상 버젼을 사용 하면서 작업시 

__Array 에서 인덱스 값을 갖고 올시 불편한 점이 많다.. 그래서 매크로를 만들어 놓고 작업을 하면됨


// Ref -> std::string

#define ccsf(...)        __String::createWithFormat(__VA_ARGS__)->getCString()

// Ref -> int

#define LMToInt(...)     ((__String*)(__VA_ARGS__))->intValue()

// Ref -> __String

#define LMToString(...)  (__String*)(__VA_ARGS__)


#define ccf(...)        __String::createWithFormat(__VA_ARGS__)



위 4개가 주로 이용 됨.


이상입니다.~


Shake.cpp


Shake.h



프로젝트에 추가 후 


사용 방법


    Shake *shake = Shake::actionWithDuration(0.5f, 30);

    this->runAction(shake);


이상입니다.


참고 : http://singleton.tistory.com/375



cocos2d-x 3.0이상에서 라벨사용시 폰트 자간 조절 하는 법



CCLabel.cpp


CCLabel.h


CCLabelTextFormatter.cpp


위3가지의 파일을 덮어 씌어 준 후 사용 하면 됩니다. 혹시 버젼이 변경 되어 다른 곳에서 에러가 날 시 


CCLabe.cpp 에 추가 Code


, _additionalKerning(0.0f)


void Label::setAdditionalKerning(float space)

{

    CCASSERT(_currentLabelType != LabelType::STRING_TEXTURE, "Not supported system font!");

    if (_additionalKerning != space)

    {

        _additionalKerning = space;

        _contentDirty = true;

    }

}


float Label::getAdditionalKerning() const

{

    CCASSERT(_currentLabelType != LabelType::STRING_TEXTURE, "Not supported system font!");

    

    return _additionalKerning;

}


CCLabel.h 에 추가 Code


    float _additionalKerning;


    void setAdditionalKerning(float space);

    /** Returns the additional kerning of this label

    @warning Not support system font

    @since v3.2.0

    */

    float getAdditionalKerning() const;


CCLabelTextFormatter.cpp 에 변경 Code

nextFontPositionX += charAdvance + kernings[i];

위 코드를 아래와 같이 변경

nextFontPositionX += charAdvance + kernings[i] + theLabel->_additionalKerning;


이상입니다.~


참고 : https://github.com/cocos2d/cocos2d-x/search?q=setAdditionalKerning&ref=cmdform




가끔 맥에서 키를 등록 할려고 하는데 

아래와 같은 에러가 발생 할때가 있다


'시스템 루트' 키체인을 수정할 수 없습니다.


이때는 당황하지 말고 드래그앤 드랍으로 키를 넣으면 된다~


^^ 이상입니다.~


버젼  : cocos2d-x 3.1


cocostudio 를 사용 하여 AnimationEditor 작업 후 파일을 Export 하면 3개의 파일이 생성 되는 것 까지는 생략 하겠습니다.


Size visibleSize = Director::getInstance()->getVisibleSize();


// 파일을 먼저 로딩 //

    cocostudio::ArmatureDataManager::getInstance()->addArmatureFileInfo("test.ExportJson");

     

// 애니메이션 생성 한후 //

    Armature *armature = cocostudio::Armature::create("test");

    armature->setPosition(Vec2(visibleSize.width / 2 , visibleSize.height / 2));

    armature->setScale(5.0f);

// 몇번째 애니메이션을 실행 할것인지 인덱스로 해도 되고 아니면 애니메이션 명으로 실행 해도

//    armature->getAnimation()->play("test");

    armature->getAnimation()->playWithIndex(1);


// 애니메이션 속도 조절 가능 RPG 게임 2배속 기능 참고

    armature->getAnimation()->setSpeedScale(0.1f);

    

    

    //애니메이션 시작 중간 끝났을때 콜백 받을수 있음

    armature->getAnimation()->setMovementEventCallFunc(CC_CALLBACK_0(LobbyScene::animationEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

    

    // 프레임당 이벤트 메서드가 있을시 콜백 받음

    armature->getAnimation()->setFrameEventCallFunc(CC_CALLBACK_0(LobbyScene::onFrameEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));

    

    this->addChild(armature);


======= call back func ======

void ********::onFrameEvent(Bone *bone, const std::string& evt, int originFrameIndex, int currentFrameIndex)

{

    CCLOG("(%s) emit a frame event (%s) at frame index (%d).", bone->getName().c_str(), evt.c_str(), currentFrameIndex);

    

    if((__String::createWithFormat("%s",evt.c_str()))->isEqual(StringMake("fire"))) {

        log("Event Start");

    }

    

    if(strcmp(evt.c_str(),"event")) {

        log("Event Start");

    }

}


void ************::animationEvent(Armature *armature, MovementEventType movementType, const std::string& movementID)

{

    if (movementType == LOOP_COMPLETE)

    {

        if (movementID == "test1")

        {

            log("test complete");

        }

    }

}


이상입니다.~


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

또한 지금 작업 하고 있는 프로젝트에서 따로 h파일을 하나 생성 하여 cocos2d관련 h파일을 다 포함 하여 작업을 진행 중입니다. 


test.h


#include "cocos2d.h"

#include "cocostudio/CocoStudio.h"


#if(CC_PLATFORM_ANDROID == CC_TARGET_PLATFORM)

#include "extensions/cocos-ext.h"

#elif(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

#include "cocos-ext.h"

#endif


using namespace cocos2d;

using namespace std;

using namespace extension;

using namespace cocostudio;


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

이 상태에서 각 코코스 및 코코스 스튜디오를 작업 하실때 #include "test.h" 만 추가 하셔서 사용 하시면 됩니다.


참고 : http://plming.tistory.com/52


include <iostream>

using namespace std;

class Animal;

class AnimalDelegate{
public:
    virtual void onSound(Animal* pSender)=0;
    virtual void onWalk(Animal* pSender)=0;
};

class Animal{
private:
    AnimalDelegate* delegate;

public:

    Animal(){
        this->delegate = NULL;
    }

    void setDelegate(AnimalDelegate* delegate){
        this->delegate = delegate;
    }

    void sound(){
        if(this->delegate){
            this->delegate->onSound(this);
        }
    }

    void walk(){
        if(this->delegate){
            this->delegate->onWalk(this);
        }
    }
};



//개 : Delegate를 내부에 직접 구현
class Dog:public Animal, public AnimalDelegate{
public:
    Dog(){
        this->setDelegate(this);
    }

    void onSound(Animal* pSender){
        cout << "Dog: 멍멍!" << endl;
    }

    void onWalk(Animal* pSender){
        cout << "Dog: 개가 걷는다" << endl;
    }
};

//고양이 Delegate
class CatDelegate:public AnimalDelegate{
public:
    void onSound(Animal* pSender){
        cout << "Cat: 야옹~" << endl;
    }

    void onWalk(Animal* pSender){
        cout << "Cat: 고양이가 걷는다" << endl;
    }
};

//고양이
class Cat:public Animal{};


void main(){

    Dog dog;
    Cat cat;

    dog.sound();
    dog.walk();
    
    CatDelegate cdel;

    cat.setDelegate(&cdel);
    cat.sound();
    cat.walk();
    
    getchar();
}


예전에는 

this->setTouchEnabled(false)  이였는데 ...


3.0으로 넘어 오면서 


화면의 모든 터치이벤트 멈춤

Director::getInstance()->getEventDispatcher()->setEnabled(false);

하나의 타켓(클래스)의 터치이벤트 멈춤

Director::getInstance()->getEventDispatcher()->pauseEventListenersForTarget(this);

다시시작

Director::getInstance()->getEventDispatcher()->resumeEventListenersForTarget(this);

[출처] touchevent|작성자 웅디베어



참고 하세요.



cocos2d-x 3.x 버젼에서 안드로이드 터미널 빌드시 


make: *** No rule to make target 

make: *** Waiting for unfinished jobs....

Traceback (most recent call last):

  File "./build_native.py", line 166, in <module>

    build(opts.ndk_build_param,opts.android_platform,opts.build_mode)

  File "./build_native.py", line 153, in build

    do_build(cocos_root, ndk_root, app_android_root,ndk_build_param,sdk_root,android_platform,build_mode)

  File "./build_native.py", line 89, in do_build

    raise Exception("Build dynamic library for project [ " + app_android_root + " ] fails!")


위와 같은 내용의 오류가 나올때가 있습니다.

해결 방법은


proj.android / obj 의 폴더를 모두 지우고 다시 빌드 하면 


정상 작동 합니다.



혹시 유니티 프로젝트 빌드시 


Error CS0241: 기본 매개 변수 지정자를 사용할 수 없습니다. (CS0241) (Assembly-CSharp-Editor)


위와 같은 에러가 나오게 된다면 


해결 방법


 Tools -> Options에서 제일 밑에 있는 Unity -> Debugger에서 Build project in MonoDevelop를 체크 해제하고 빌드하시면 됩니다. 또한 이것은 Windows 환경에서만 발생하고 Mac에서는 발생하지 않는 에러입니다.



이상입니다.

// iOSInAppPlugin.h


#import <StoreKit/StoreKit.h>

@interface iOSInAppPlugin : NSObject<
///< 상품 정보를 얻어올  쓰는 딜리게이트
SKProductsRequestDelegate,
///< 상품 구매 관련 옵저버
SKPaymentTransactionObserver>

+ (iOSInAppPlugin*) sharediOSInAppPlugin;
- (BOOL) initInApp;
- (void) requestProductData:(NSString*)strProductId;

- (void) completeTransaction:(SKPaymentTransaction*)transaction;
- (void) restoreTransaction:(SKPaymentTransaction*)transaction;
- (void) failedTransaction:(SKPaymentTransaction*)transaction;

- (void) restoreCompletedTransactions;

@end




// iOSInAppPlugin.m


#import "iOSInAppPlugin.h"

extern "C"
{
    void iOSInAppInit()
    {
        [[iOSInAppPlugin sharediOSInAppPlugininitInApp];
    }
    void iOSBuyItem(const char* pszProductId)
    {
        NSString* strProductId = [NSString stringWithUTF8String:pszProductId];
        [[iOSInAppPlugin sharediOSInAppPluginrequestProductData:strProductId];
    }
    void iOSRestoreCompletedTransactions()
    {
        [[iOSInAppPlugin sharediOSInAppPluginrestoreCompletedTransactions];
    }
}

@implementation iOSInAppPlugin

+ (iOSInAppPlugin*) sharediOSInAppPlugin
{
    static iOSInAppPlugin* pInstance;
    if(pInstance == NULL)
    {
        pInstance = [[iOSInAppPlugin allocinit];
    }
    return pInstance;
}

- (BOOL) initInApp
{
    ///< 인앱 결제 시스템을 사용 가능한지 체크
    if( [SKPaymentQueue canMakePayments] == NO )
        return NO;
    
    ///< Product 결제 진행에 필요한 딜리게이트 등록
    [[SKPaymentQueue defaultQueueaddTransactionObserver:self];
    
    NSLog(@"InAppPurchase init OK");
    return true;
}

///< 아이템 정보 요청
- (void) requestProductData:(NSString*)strProductId
{
    ///< iTunes Connect 설정한 Product ID
    NSSet* productIdentifiers = [NSSet setWithObject:strProductId];
    SKProductsRequest* request = [[SKProductsRequest alloc]initWithProductIdentifiers:productIdentifiers];
    request.delegate = self;
    [request start];
    NSLog(@"requestProductData %@", strProductId);
}

///< 아이템 정보 요청 결과 callback
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSLog@"InAppPurchase didReceiveResponse" );
    forSKProduct* product in response.products )
    {
        if( product != nil )
        {
            NSLog(@"InAppPurchase Product title: %@", product.localizedTitle);
            NSLog(@"InAppPurchase Product description: %@", product.localizedDescription);
            NSLog(@"InAppPurchase Product price: %@", product.price);
            //product.priceLocale
            NSLog(@"InAppPurchase Product id: %@", product.productIdentifier);
            
            ///< 구매 요청
            
            SKPayment* payment = [SKPayment paymentWithProduct:product];
            //payment.quantity = 10;
            [[SKPaymentQueue defaultQueueaddPayment:payment];
        }
    }
    
    [request release];
    
    for (NSString *invalidProductId in response.invalidProductIdentifiers)
    {
        NSLog(@"InAppPurchase Invalid product id: %@", invalidProductId);
    }
}

///< 새로운 거래가 발생하거나 갱신될  호출된다.
- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray*)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
                ///< 서버에 거래 처리중
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"InAppPurchase SKPaymentTransactionStatePurchasing");
                break;
                ///< 구매 완료
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction:transaction];
                break;
                ///< 거래 실패 또는 취소
            case SKPaymentTransactionStateFailed:
                [self failedTransaction:transaction];
                break;
                ///< 재구매
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction:transaction];
                break;
        }
    }
}

- (void) completeTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"InAppPurchase completeTransaction");
    NSLog(@"InAppPurchase Transaction Identifier : %@", transaction.transactionIdentifier );
    NSLog(@"InAppPurchase Transaction Data : %@", transaction.transactionDate );
    ///< 구매 완료  아이템 인벤등 게임쪽  처리 진행
    /* 빌트 인 모델
    const char* pszProductId = [[[transaction payment] productIdentifier] UTF8String];
    UnitySendMessage("iOSManager", "ResultBuyItem", pszProductId);
     */
   
    NSString* strReceipt = [[NSString alloc]initWithBytes:transaction.transactionReceipt.byteslength:transaction.transactionReceipt.length encoding:NSUTF8StringEncoding];
    
    UnitySendMessage("iOSManager""ResultBuyItem", [strReceipt UTF8String]);

    // Remove the transaction from the payment queue.
    [[SKPaymentQueue defaultQueuefinishTransaction:transaction];
}

- (void) restoreTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"InAppPurchase restoreTransaction");
    const char* pszRestoreProductId = [transaction.originalTransaction.payment.productIdentifier UTF8String];
    UnitySendMessage("iOSManager""ResultRestoreItem", pszRestoreProductId);
    [[SKPaymentQueue defaultQueuefinishTransaction:transaction];
}

- (void) failedTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"InAppPurchase failedTransaction.");
    const char* pszResult = 0;
    if( transaction.error.code != SKErrorPaymentCancelled )
    {
        pszResult = "faileIAP";
        NSLog(@"InAppPurchase failedTransaction SKErrorDomain - %d", transaction.error.code );
    }
    else
    {
        pszResult = "cancelIAP";
        NSLog(@"InAppPurchase failedTransaction SKErrorPaymentCancelled");
    }
    UnitySendMessage("iOSManager""ResultBuyItem", pszResult);
    [[SKPaymentQueue defaultQueuefinishTransaction:transaction];
}

// 비소모성 아이템 복원 요청
- (void) restoreCompletedTransactions
{
    [[SKPaymentQueue defaultQueuerestoreCompletedTransactions];
}

@end



// iOSManager.cs


using UnityEngine;

using System.Runtime.InteropServices;

public class iOSManager : MonoBehaviour 
{
static iOSManager _instance;
private string strLog = "Unity3D iOS In App Purchase Sample";
public string strPostMsg = string.Empty;
[DllImport("__Internal")]
private static extern void iOSInAppInit();
[DllImport("__Internal")]
private static extern void iOSBuyItem(string strProductId);
[DllImport("__Internal")]
private static extern void iOSRestoreCompletedTransactions();
public static iOSManager GetInstance()
{
if( _instance == null )
{
_instance = new GameObject("iOSManager").AddComponent<iOSManager>();
}
return _instance;
}
public void InAppInit()
{
iOSInAppInit();
}

public void BuyItem(string strProductId)
{
iOSBuyItem(strProductId);
}
public void ResultBuyItem(string strResult)
{
// strResult is transaction.transactionReceipt or faileIAP or cancelIAP.
SetLog("ResultBuyItem " + strResult);
}
public void RestoreCompletedTransactions()
{
iOSRestoreCompletedTransactions();
}
public void ResultRestoreItem(string strRestoreItemId)
{
SetLog("ResultRestoreItem " + strRestoreItemId);
}

public void SetLog(string _strLog)
{
strLog = _strLog;
}
public string GetLog()
{
return strLog;
}
}

출처 : http://westwoodforever.blogspot.kr/2013/10/unity3d-integration-ios-in-app-purchase.html#links


+ Recent posts