cococos 2 dx 3.0用std::bind置換CC_CALLBACK_N
8305 ワード
cococos 2 dx 3.0バージョンでは、コールバック関数は基本的に4つのCC_CALLBACK_N関数の代わりに、Nはコールバック関数のパラメータ個数を表す
1.まず、これらのCC_を見てみましょう.CALLBACK_Nの使い方
例えばactionのコールバック、CC_CALLBACK_0
またはactionパラメータ付きコールバック:CC_CALLBACK_1,ここでpSenderは動作の実行者sprite 2である.
またはボタンのコールバック関数:CC_CALLBACK_1
またはtouch関数:CC_CALLBACK_2
2.上のCallFuncとCallFucnNを見つけましたか.はい、まずLOLに行ってから書きます.
お帰りなさい.まず血を返させて、うん、それから...
一般的には、
CallFuncはパラメータを持たないために使用され、CallFuncNはノードパラメータを持つために使用され、Node*ノードパラメータは動作の実行者であるCCCallFuncNDはCallFuncNより1つ多くのパラメータを持ち、任意のタイプのパラメータであってもよい void*、使い方は以下の通りです
実際には、2つのパラメータを持つ関数のこのコードを呼び出します.
このように書くこともできます.
実は上のCC_CALLBACK_0ああCC_CALLBACK_1ああ、このように書くことができます.いろいろな書き方があります.
なぜならCC_CALLBACK_Nには可変パラメータマクロがあります##_VA_ARGS__.
はい、少し乱れているのではないでしょうか.覚えられなくても大丈夫です.私もよく覚えていません.具体的にCCを見てみましょう.CALLBACK_Nはいったい神馬の遊びだ
std::bind、###_を見たのではないでしょうか.VA_ARGS__、std::placeholders::_1など、これらはすべて神馬の遊びです.
まず説明します.
##__VA_ARGS__可変パラメータマクロstd::placeholders::1はパラメータプレースホルダで、最初のパラメータを表します.
じゃあstd::bindは神馬です.焦らないでコードを見てみましょう.
出力結果を見てみましょう.
もう一度説明します.
std::function --> グローバル関数/クラス静的メンバー関数にバインドstd::bind --> クラスにバインドされた非静的メンバー関数
ここまで来るとおおらかな感じがするのではないでしょうか.はは、bind関数の使い方を知って、std::bindを使ってCC_を置き換えることができます.CALLBACK_N書き方
3.std:bind関数を使用してCC_を置換CALLBACK_N:
例えばCC_を置き換えるCALLBACK_0
たとえば、パラメータ付きのCC_を置き換えます.CALLBACK_1
たとえば2つのパラメータを呼び出すと...
ははは、これではっきりしたでしょう.のもう二度と混乱しない.の
1.まず、これらのCC_を見てみましょう.CALLBACK_Nの使い方
例えばactionのコールバック、CC_CALLBACK_0
auto animation = Animation::create();
auto animate = Animate::create(animation);
CallFunc* animateDone = CallFunc::create(CC_CALLBACK_0(PlaneLayer::removePlane,this));
auto sequence = Sequence::create(animate,animateDone,NULL);
sprite1->runAction(sequence);
void PlaneLayer::removePlane(){
//.....
}
またはactionパラメータ付きコールバック:CC_CALLBACK_1,ここでpSenderは動作の実行者sprite 2である.
auto actionMove = MoveTo::create(randomDuration, Point(0, 0));
auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyLayer::enemy1MoveFinished,this));
auto sequence = Sequence::create(actionMove,actionDone,NULL);
sprite2->runAction(sequence);
void EnemyLayer::enemy1MoveFinished(Node* pSender){
Sprite* sprite2 = (Sprite*)pSender;
}
またはボタンのコールバック関数:CC_CALLBACK_1
auto pauseNormal = Sprite::create("game_pause_nor.png");
auto pausePressed = Sprite::create("game_pause_pressed.png");
auto menuItem = MenuItemSprite::create(pauseNormal,pausePressed,NULL,CC_CALLBACK_1(ControlLayer::menuPauseCallback,this));
menuItem->setPosition(Point::ZERO);
auto menuPause = Menu::create(menuItem,NULL);
menuPause->setPosition(Point::ZERO);
//
void ControlLayer::menuPauseCallback(Object* pSender)
{
//....
}
またはtouch関数:CC_CALLBACK_2
//
virtual bool onTouchBegan(Touch *touch, Event *unused_event);
virtual void onTouchMoved(Touch *touch, Event *unused_event);
virtual void onTouchEnded(Touch *touch, Event *unused_event);
virtual void onTouchCancelled(Touch *touch, Event *unused_event);
auto dispatcher = Director::getInstance()->getEventDispatcher();
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan,this);
listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved,this);
listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded,this);
listener->setSwallowTouches(true);//
dispatcher->addEventListenerWithSceneGraphPriority(listener,this);
2.上のCallFuncとCallFucnNを見つけましたか.はい、まずLOLに行ってから書きます.
お帰りなさい.まず血を返させて、うん、それから...
一般的には、
CallFuncはパラメータを持たないために使用され、CallFuncNはノードパラメータを持つために使用され、Node*ノードパラメータは動作の実行者であるCCCallFuncNDはCallFuncNより1つ多くのパラメータを持ち、任意のタイプのパラメータであってもよい void*、使い方は以下の通りです
auto animation = AnimationCache::getInstance()->animationByName("Enemy1Blowup");
auto animate = Animate::create(animation);
CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
auto sequence = Sequence::create(animate, animateDone,NULL);
Sprite* m_sprite = enemy1->getSprite();
m_sprite ->runAction(sequence);
void EnemyLayer::removeEnemy1(Node* pTarget, void* data){
Sprite* m_sprite = (Sprite*) pTarget; //node
Enemy* enemy1 = (Enemy*)data; // enemy1
//...
}
実際には、2つのパラメータを持つ関数のこのコードを呼び出します.
CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
このように書くこともできます.
// 1
CCCallFuncN* animateDone = CCCallFuncN::create(CC_CALLBACK_1(EnemyLayer::removeEnemy1,this,enemy1));
// 2
CCCallFunc* animateDone = CCCallFunc::create(CC_CALLBACK_0(EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));
// 3, std::bind
CCCallFuncN* animateDone = CCCallFuncN::create(std::bind(&EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));
実は上のCC_CALLBACK_0ああCC_CALLBACK_1ああ、このように書くことができます.いろいろな書き方があります.
なぜならCC_CALLBACK_Nには可変パラメータマクロがあります##_VA_ARGS__.
はい、少し乱れているのではないでしょうか.覚えられなくても大丈夫です.私もよく覚えていません.具体的にCCを見てみましょう.CALLBACK_Nはいったい神馬の遊びだ
// new callbacks based on C++11
#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 ##__VA_ARGS__)
std::bind、###_を見たのではないでしょうか.VA_ARGS__、std::placeholders::_1など、これらはすべて神馬の遊びです.
まず説明します.
##__VA_ARGS__可変パラメータマクロstd::placeholders::1はパラメータプレースホルダで、最初のパラメータを表します.
じゃあstd::bindは神馬です.焦らないでコードを見てみましょう.
#include <iostream>
#include <functional>
using namespace std;
typedef std::function<void ()> fp;
void g_fun()
{
cout<<"g_fun()"<<endl;
}
class A
{
public:
static void A_fun_static()
{
cout<<"A_fun_static()"<<endl;
}
void A_fun()
{
cout<<"A_fun()"<<endl;
}
void A_fun_int(int i)
{
cout<<"A_fun_int() "<<i<<endl;
}
void A_fun_int_double(int i,int p)
{
cout<<"A_fun_int_double ()"<<i<<","<<p<<endl;
}
// , this , bind
void init()
{
//
fp fp1=std::bind(&A::A_fun,this);
fp1();
}
void init2()
{
typedef std::function<void (int)> fpi;
//
fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);// std::placeholders::_1
f(5);
}
void init3(){
typedef std::function<void (int,double)> fpid;
//
fpid f=std::bind(&A::A_fun_int_double,this,std::placeholders::_1,std::placeholders::_2);
f(5,10);
}
};
int main()
{
//
fp f2=fp(&g_fun);
f2();
//
fp f1=fp(&A::A_fun_static);
f1();
A().init();
A().init2();
A().init3();
return 0;
}
出力結果を見てみましょう.
g_fun()
A_fun_static()
A_fun()
A_fun_int() 5
A_fun_int_double ()5,10
もう一度説明します.
std::function --> グローバル関数/クラス静的メンバー関数にバインドstd::bind --> クラスにバインドされた非静的メンバー関数
ここまで来るとおおらかな感じがするのではないでしょうか.はは、bind関数の使い方を知って、std::bindを使ってCC_を置き換えることができます.CALLBACK_N書き方
3.std:bind関数を使用してCC_を置換CALLBACK_N:
例えばCC_を置き換えるCALLBACK_0
auto animation = Animation::create();
auto animate = Animate::create(animation);
//CallFunc* animateDone = CallFunc::create(CC_CALLBACK_0(PlaneLayer::removePlane,this));
CallFunc* animateDone = CallFunc::create(std::bind(&PlaneLayer::removePlane,this));//
auto sequence = Sequence::create(animate,animateDone,NULL);
sprite1->runAction(sequence);
void PlaneLayer::removePlane(){
//.....
}
たとえば、パラメータ付きのCC_を置き換えます.CALLBACK_1
auto actionMove = MoveTo::create(randomDuration, Point(0, 0));
//auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyLayer::enemy1MoveFinished,this));
auto actionDone = CallFuncN::create(std::bind(&EnemyLayer::enemy1MoveFinished,this,enemy1));//
auto sequence = Sequence::create(actionMove,actionDone,NULL);
sprite2->runAction(sequence);
void EnemyLayer::enemy1MoveFinished(Node* pSender){
Sprite* sprite2 = (Sprite*)pSender;
}
たとえば2つのパラメータを呼び出すと...
auto animation = AnimationCache::getInstance()->animationByName("Enemy1Blowup");
auto animate = Animate::create(animation);
//CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
CCCallFuncN* animateDone = CCCallFuncN::create(std::bind(&EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));//
auto sequence = Sequence::create(animate, animateDone,NULL);
Sprite* m_sprite = enemy1->getSprite();
m_sprite ->runAction(sequence);
void EnemyLayer::removeEnemy1(Node* pTarget, void* data){
Sprite* m_sprite = (Sprite*) pTarget; //node
Enemy* enemy1 = (Enemy*)data; // enemy1
//...
}
ははは、これではっきりしたでしょう.のもう二度と混乱しない.の