2017年12月20日 星期三

1220 VS2013 使用ramDisk


1. 下載軟體 SoftPerfect RAMDISK 3.4.8

4.0 版取消免費版, home license開始要收費
download 3.4.8免費版要快手,不知majorgeeks幾時推送4.0
http://www.majorgeeks.com/files/details/softperfect_ram_disk.html
3.4.8 另一個download mirror
http://filehippo.com/download_softperfect-ram-disk/71289/

2. 建立RAMDDISK !並且掛載至系統上 範例教學
http://wuhsiublog.blogspot.tw/2015/07/softperfect-ram-disk.html


3. 利用軟體建立 windows 系統暫儲檔

記得暫存檔路徑一定要有目錄
例如 R:\temp

2017年12月8日 星期五

1208 Cocos2dx - Sprite 更換圖片的方法

http://cocos2dx.logdown.com/tags/%E6%9B%B4%E6%8F%9B%E5%9C%96%E7%89%87

自己程式用到的方式有

刪除舊檔
TextureCache::getInstance()->removeTextureForKey(avatarFileName); //檔名加路徑
//增加至CACHE中
SpriteFrameCache* cache = SpriteFrameCache::getInstance();
auto pNewSprite = Sprite::create(avatarFileName); //開檔載入
if (pNewSprite != nullptr)
{
auto pFrame = pNewSprite->getSpriteFrame();
cache->addSpriteFrame(pFrame, stInfo.FileName);
}

新檔案載入

//將大頭照載入cache 中
SpriteFrameCache* cache = SpriteFrameCache::getInstance();
auto pFrame = cache->getSpriteFrameByName(avatar);
if (pFrame == nullptr)
{ //檢查是否已經在cahce
auto pNewSprite = Sprite::create(fileName); //開檔載入
if (pNewSprite != nullptr)
{
TextureCache::getInstance()->removeTextureForKey(avatar);
//cache->addSpriteFramesWithFile(fileName);
pFrame = pNewSprite->getSpriteFrame();
cache->addSpriteFrame(pFrame, avatar);
}
}
if (pFrame != nullptr)
{
logFile(LOG_DEBUG, "Image name %s (%p)", avatar.c_str(), pFrame);
spritePersion->setSpriteFrame(pFrame);
return true;
}

 參考文件資料

網路上常見的兩種方法

基本上網路上的做法為更換掉 Sprite 中的Texture, 或者將 SpriteFrame 中的DisplayFrame 換掉。
但必須得說, 這些做法都相對麻煩, 而且就效率來說與新建一張Sprite的成本, 差距不大。
於是有些時候我會採用下面的做法。

新建一張Sprite, 將裡面的Texture貼回需要替換的Sprite


Sprite *newSprite = Sprite::create("newImage.png");  
oldSprite->setTexture(newSprite->getTexture());

  • 限制: 更換Sprite 的 Texture時, 需要注意如果是更新有相同名稱的圖檔時, 需要先將舊有的 Cache清除, 不然使用相同名稱時, 會取成舊有Cache中的 Texture檔
      Director::getInstance()->getTextureCache()->removeTextureForKey("photo.png");
    

筆者: 好處是不需要額外處理 Texture中的許多細節, 缺點則是多了一個 create 的呼叫, 在有許多圖檔建立時, App會變得很慢, 所以這種作法請千萬不要在需要一次更換很多圖檔時使用。

2017年8月23日 星期三

0823 cocos2d-x 手機連線 相關資料

http://qiankanglai.me/2014/12/02/cocos2dx-assetsmanager/
基於cocos2d-x 3.x版本修改的Assets Manager,加幾行代碼就能實現斷線續傳功能…so easy



bool AssetsManager::downLoad()
{
// Create a file to save package.
const string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
- FILE *fp = fopen(outFileName.c_str(), "wb");
+ ssize_t outFileLength = 0;
+ FILE *fp = fopen(outFileName.c_str(), "rb");
+ if(fp)
+ {
+ fseek(fp, 0, SEEK_END);
+ outFileLength = ftell(fp);
+ fclose(fp);
+ }
+
+ fp = fopen(outFileName.c_str(), "ab");

然後在下面設置curl的地方




curl_easy_setopt(_curl, CURLOPT_FOLLOWLOCATION, 1 );
+ if(outFileLength > 0)
+ curl_easy_setopt(_curl, CURLOPT_RESUME_FROM, outFileLength);
res = curl_easy_perform(_curl);

Android – 判斷手機是否連上網路 (ConnectivityManager)

通常手機在開發網路的應用程式時, 常會定時的去取資料回來 但…倘若目前手機無法對外連線, 則這段動作就會造成手機效能無謂的耗損、與電力的浪費 所以在開發網路型的應用程式時, 首先要做的第一個功課, 便是 「判斷手機目前是否已連線"
而 Android 系統的手機, 目前是否連上網路? 以什麼方式連上網路? (WIFI / 3G…)? 目前網路是否故障中(Failover)? 目前手機是否在漫遊中(Roaming)? 這些相關的資訊, 都存在於 ConnectivityManager 這個類別當中 而使用的方式只需要去向系統取回這個服務即可
1
2
ConnectivityManager CM = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = CM.getActiveNetworkInfo();
而當中要注意到的地方, 是在 NetworkInfo 這段, 倘若你的手機目前不在網路的服務範圍, 也就是說沒有任何方式可以連出去網路 則 CM.getActiveNetworkInfo() 取回的 Reference 會是 Null, 忘了做此判斷的話, 手機則會立刻罷工給你看 (NullPointerException) 而比較常見需要取得的資料如下:
1
2
3
4
5
6
7
info.getTypeName();     // 目前以何種方式連線 [WIFI]
info.getState();        // 目前連線狀態 [CONNECTED]
info.isAvailable();     // 目前網路是否可使用 [true]
info.isConnected();     // 網路是否已連接 [true]
info.isConnectedOrConnecting(); // 網路是否已連接 或 連線中 [true]
info.isFailover();      // 網路目前是否有問題 [false]
info.isRoaming();       // 網路目前是否在漫遊中 [false]
除此之外, 也必需替應用程式設定權限, 不然手機一樣會罷工給你看 (SecurityException) 設定權限的方式則是在 AndroidManifest.xml 裡頭新增底下的權限
1
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

2017年8月18日 星期五

0818 cocos2d-x 如何取得手機型號跟其他資訊(android)

//範例程式碼
proj.android-studio\app\src\org\cocos2dx\cpp\AppActivity.java

增加
import android.os.Build;   // 主機版名稱 String board = Build.BOARD;
public class AppActivity extends Cocos2dxActivity {    
    private static String deviceInfo; //回傳手機型號跟系統版本
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        deviceInfo = this.getDeviceInfo();
    }  
        public static String findDeviceInfo() {
        return deviceInfo;
    }
    /**
     * Get Android node and Android version
     * */
    public String getDeviceInfo()
    {
        TelephonyManager manager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
  String model = Build.MODEL; //手機型號
String phoneNum = manager.getLine1Number();//本機電話號碼
String sdkVersion = Build.VERSION.SDK;//SDK版本號
String osVersion = Build.VERSION.RELEASE;//Firmware/OS 版本號
return "Phone:" +model + "  OS:" + osVersion;

    }
   
     
}

///參考文章
http://www.cocos2dev.com/?p=208

今天要獲取用戶反饋意見,我默認將用戶的手機號碼上傳了,結果發現並不是所有的手機能拿到本機號碼。找了下發現原是用戶的SIM卡沒有寫入本機號碼導致的。
Android獲取本機號碼:
TelephonyManager phoneMgr = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String phoneNum = phoneMgr.getLine1Number(); 
AndroidManifest.xml中添加權限:
<uses-permission android:name=」android.permission.READ_PHONE_STATE」 />
剛才也說了,手機號碼不是所有的都能獲取。只是有一部分可以拿到。這個是由於移動運營商沒有把手機號碼的數據寫入到sim卡中。
手機型號 Build.MODEL
String MODEL The end-user-visible name for the end product.
sdk版本 Build.VERSION.SDK
String SDK This constant is deprecated. Use SDK_INT to easily get this as an integer.
frimware版本號(系統版本號) Build.VERSION.RELEASE
String RELEASE The user-visible version string.
獲取手機的其他信息:
private void getPhoneStatus(){
TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);      
String model = Build.MODEL; //手機型號
String phoneNum = phoneMgr.getLine1Number();//本機電話號碼
String sdkVersion = Build.VERSION.SDK;//SDK版本號
String osVersion = Build.VERSION.RELEASE;//Firmware/OS 版本號
}
Build中包括 硬件廠商,硬件編號,序列號等很多信息。調用方法也很簡單,和上面類似的。
下面是Google提供的參考表:
StringBOARDThe name of the underlying board, like 「goldfish」.
StringBOOTLOADERThe system bootloader version number.
StringBRANDThe brand (e.g., carrier) the software is customized for, if any.
StringCPU_ABIThe name of the instruction set (CPU type + ABI convention) of native code.
StringCPU_ABI2The name of the second instruction set (CPU type + ABI convention) of native code.
StringDEVICEThe name of the industrial design.
StringDISPLAYA build ID string meant for displaying to the user
StringFINGERPRINTA string that uniquely identifies this build.
StringHARDWAREThe name of the hardware (from the kernel command line or /proc).
StringHOST
StringIDEither a changelist number, or a label like 「M4-rc20」.
StringMANUFACTURERThe manufacturer of the product/hardware.
StringMODELThe end-user-visible name for the end product.
StringPRODUCTThe name of the overall product.
StringRADIOThe radio firmware version number.
StringSERIALA hardware serial number, if available.
StringTAGSComma-separated tags describing the build, like 「unsigned,debug」.
longTIME
StringTYPEThe type of build, like 「user」 or 「eng」.
StringUNKNOWNValue used for when a build property is unknown.
StringUSER

2017年8月16日 星期三

0816 cocos2d-x 開啟網址

http://jslim.net/blog/2014/09/24/cocos2d-x-v3-open-url/
You can invoke Application::getInstance()->openURL("your url"). e.g.
MyScene.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
switch (Application::getInstance()->getTargetPlatform()) {
case Application::Platform::OS_IPAD:
case Application::Platform::OS_IPHONE:
Application::getInstance()->openURL("http://www.apple.com");
break;
case Application::Platform::OS_ANDROID:
Application::getInstance()->openURL("http://www.google.com");
break;
default:
break;
}

2017年7月5日 星期三

0714 cocos2d-x 3.15 如何增加複製到系統剪貼簿

參考 http://blog.csdn.net/mydreamremindme/article/details/49229205

  1.1 程式碼增加
  #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
bool PageMain::copyToClipboard(const std::string &content)
{
return copyToClipboardJNI(content.c_str());
}
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
bool PageMain::copyToClipboard(const std::string &content)
{
if (OpenClipboard(NULL))
{
EmptyClipboard();
HGLOBAL clipbuffer;
char* buffer;
const char* str = content.c_str();
const int length = strlen(str);
clipbuffer = GlobalAlloc(GMEM_DDESHARE, length + 1);
buffer = (char*)GlobalLock(clipbuffer);
strcpy(buffer, str);
GlobalUnlock(clipbuffer);
SetClipboardData(CF_TEXT, clipbuffer);
CloseClipboard();
return true;
}
return false;
}
#endif

1.2  增加對應的函數 讓C呼叫
cocos2d-x\cocos\platform\android\jni\Java_org_cocos2dx_lib_Cocos2dxHelper.cpp

extern bool copyToClipboardJNI(const char* content)
{
JniMethodInfo t;
bool ret = false;
if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxHelper", "copyToClipboard", "(Ljava/lang/String;)Z"))
{
jstring stringArg = t.env->NewStringUTF(content);
ret = t.env->CallStaticBooleanMethod(t.classID, t.methodID,stringArg);
t.env->DeleteLocalRef(t.classID);
t.env->DeleteLocalRef(stringArg);
}
return ret;
}
1.3 撰寫JAVA 的程式碼
cocos2d-x\cocos\platform\android\java\src\org\cocos2dx\lib\Cocos2dxHelper.java
1.3.1 宣告
在 public class Cocos2dxHelper { 增加一行
//example in line 94
private static android.content.ClipboardManager clipboardmanager = null;
1.3.2 設定對應函數
在     public static void init(final Activity activity) { 增加一行
//example in line 167 Cocos2dxBitmap.setContext(activity); 之上
Cocos2dxHelper.clipboardmanager = (android.content.ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE);//獲取剪貼板服務
1.3.3 JAVA與C的接口
在 public static void init(final Activity activity) 函數之後 增加下列函數
//example in line 195 找地方寫函數就對了
public static boolean copyToClipboard(String content){
        clipboardmanager.setText(content);
        System.out.println("come here");
        return true;
    }

2017年6月3日 星期六

0603 cocos2dx 3.0 之 用std::bind替換CC_CALLBACK_N

http://www.cnblogs.com/fzll/p/3954604.html



在cocos2dx 3.0 版本中,回調函數基本上由4個CC_CALLBACK_N 函數代替,N代表回調函數的參數個數

1.先讓我們來看看這些CC_CALLBACK_N怎麼用


比如action的回調 ,CC_CALLBACK_0

  1. auto animation = Animation::create();  
  2. auto animate = Animate::create(animation);  
  3. CallFunc* animateDone = CallFunc::create(CC_CALLBACK_0(PlaneLayer::removePlane,this));  
  4. auto sequence = Sequence::create(animate,animateDone,NULL);  
  5. sprite1->runAction(sequence);  
  6.   
  7. void PlaneLayer::removePlane(){  
  8.     //.....  
  9. }  

或者action帶一個參數的回調:CC_CALLBACK_1,在這裡,pSender就是動作的執行者sprite2

  1. auto actionMove = MoveTo::create(randomDuration, Point(0, 0));  
  2. auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyLayer::enemy1MoveFinished,this));  
  3. auto sequence = Sequence::create(actionMove,actionDone,NULL);  
  4. sprite2->runAction(sequence);  
  5.   
  6. void EnemyLayer::enemy1MoveFinished(Node* pSender){  
  7.     Sprite* sprite2 = (Sprite*)pSender;  
  8. }  


或者按鈕的回調函數:CC_CALLBACK_1

  1. auto pauseNormal = Sprite::create("game_pause_nor.png");  
  2. auto pausePressed = Sprite::create("game_pause_pressed.png");  
  3.       
  4. auto menuItem = MenuItemSprite::create(pauseNormal,pausePressed,NULL,CC_CALLBACK_1(ControlLayer::menuPauseCallback,this));  
  5. menuItem->setPosition(Point::ZERO);  
  6. auto menuPause = Menu::create(menuItem,NULL);  
  7. menuPause->setPosition(Point::ZERO);  
  8.   
  9. //回調函數  
  10. void ControlLayer::menuPauseCallback(Object* pSender)  
  11. {  
  12.     //....  
  13. }  

或者touch函數:CC_CALLBACK_2

  1. //單點觸摸    
  2. virtual bool onTouchBegan(Touch *touch, Event *unused_event);     
  3. virtual void onTouchMoved(Touch *touch, Event *unused_event);     
  4. virtual void onTouchEnded(Touch *touch, Event *unused_event);     
  5. virtual void onTouchCancelled(Touch *touch, Event *unused_event);  
  6.   
  7.   
  8. auto dispatcher = Director::getInstance()->getEventDispatcher();  
  9. auto listener = EventListenerTouchOneByOne::create();  
  10. listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan,this);  
  11. listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved,this);  
  12. listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded,this);  
  13. listener->setSwallowTouches(true);//不向下傳遞觸摸  
  14. dispatcher->addEventListenerWithSceneGraphPriority(listener,this);  



2.發現了上面的CallFunc和CallFucnN了沒有,恩,先去LOL一把再接著寫。。


回來了。讓我先回口血,恩,接著寫...

一般來說:

CallFunc用於 不帶參數的
CallFuncN 用於創建 帶一個Node節點參數的,Node*節點參數是動作的執行者
CCCallFuncND 比CallFuncN多了一個參數,可以是任意類型的參數  void *,用法看下面

  1. auto animation = AnimationCache::getInstance()->animationByName("Enemy1Blowup");  
  2. auto animate = Animate::create(animation);  
  3. CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);  
  4. auto sequence = Sequence::create(animate, animateDone,NULL);  
  5. Sprite* m_sprite = enemy1->getSprite();  
  6. m_sprite ->runAction(sequence);  
  7.   
  8.   
  9. void EnemyLayer::removeEnemy1(Node* pTarget, void* data){  
  10.     Sprite* m_sprite = (Sprite*) pTarget; //node節點為動作的執行者  
  11.     Enemy* enemy1 = (Enemy*)data;         //我們傳的自定義數據enemy1  
  12.     //...  
  13. }  

其實上面調用帶兩個參數的函數的這句代碼:
  1. CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);  

我們還可以這樣子寫:
  1. //寫法1  
  2. CCCallFuncN* animateDone = CCCallFuncN::create(CC_CALLBACK_1(EnemyLayer::removeEnemy1,this,enemy1));  
  3. //寫法2  
  4. CCCallFunc* animateDone = CCCallFunc::create(CC_CALLBACK_0(EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));  
  5. //寫法3,用std::bind  
  6. 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到底是神馬玩意

  1. // new callbacks based on C++11  
  2. #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)  
  3. #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)  
  4. #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)  
  5. #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是神馬,不急我們先看一段代碼

  1. #include <iostream>  
  2. #include <functional>  
  3. using namespace std;  
  4.   
  5. typedef std::function<void ()> fp;  
  6. void g_fun()  
  7. {  
  8.     cout<<"g_fun()"<<endl;  
  9. }  
  10. class A  
  11. {  
  12. public:  
  13.     static void A_fun_static()  
  14.     {  
  15.         cout<<"A_fun_static()"<<endl;  
  16.     }  
  17.     void A_fun()  
  18.     {  
  19.         cout<<"A_fun()"<<endl;  
  20.     }  
  21.     void A_fun_int(int i)  
  22.     {  
  23.         cout<<"A_fun_int() "<<i<<endl;  
  24.     }  
  25.   
  26.     void A_fun_int_double(int i,int p)  
  27.     {  
  28.         cout<<"A_fun_int_double ()"<<i<<","<<p<<endl;  
  29.     }  
  30.   
  31.     //非靜態類成員,因為含有this指針,所以需要使用bind  
  32.     void init()  
  33.     {  
  34.         //綁定不帶參數的函數  
  35.         fp fp1=std::bind(&A::A_fun,this);  
  36.         fp1();  
  37.     }  
  38.   
  39.     void init2()  
  40.     {  
  41.         typedef std::function<void (int)> fpi;  
  42.         //綁定帶一個參數的函數  
  43.         fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);//參數要使用佔位符 std::placeholders::_1表示第一個參數  
  44.         f(5);  
  45.     }  
  46.   
  47.     void init3(){  
  48.         typedef std::function<void (int,double)> fpid;  
  49.         //綁定帶兩個參數的函數  
  50.         fpid f=std::bind(&A::A_fun_int_double,this,std::placeholders::_1,std::placeholders::_2);  
  51.         f(5,10);  
  52.     }  
  53. };  
  54. int main()  
  55. {  
  56.     //綁定到全局函數  
  57.     fp f2=fp(&g_fun);  
  58.     f2();  
  59.   
  60.     //綁定到類靜態成員函數  
  61.     fp f1=fp(&A::A_fun_static);  
  62.     f1();  
  63.   
  64.     A().init();  
  65.     A().init2();  
  66.     A().init3();  
  67.     return 0;  
  68. }  

然後看一下輸出結果:
  1. g_fun()  
  2. A_fun_static()  
  3. A_fun()  
  4. A_fun_int() 5  
  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

  1. auto animation = Animation::create();  
  2. auto animate = Animate::create(animation);  
  3. //CallFunc* animateDone = CallFunc::create(CC_CALLBACK_0(PlaneLayer::removePlane,this));  
  4. CallFunc* animateDone = CallFunc::create(std::bind(&PlaneLayer::removePlane,this));//替換  
  5. auto sequence = Sequence::create(animate,animateDone,NULL);  
  6. sprite1->runAction(sequence);  
  7.   
  8. void PlaneLayer::removePlane(){  
  9.     //.....  
  10. }  


比如我們要替換帶一個參數的CC_CALLBACK_1

  1. auto actionMove = MoveTo::create(randomDuration, Point(0, 0));  
  2. //auto actionDone = CallFuncN::create(CC_CALLBACK_1(EnemyLayer::enemy1MoveFinished,this));  
  3. auto actionDone = CallFuncN::create(std::bind(&EnemyLayer::enemy1MoveFinished,this,enemy1));//替換  
  4. auto sequence = Sequence::create(actionMove,actionDone,NULL);  
  5. sprite2->runAction(sequence);  
  6.   
  7. void EnemyLayer::enemy1MoveFinished(Node* pSender){  
  8.     Sprite* sprite2 = (Sprite*)pSender;  
  9. }  

再比如調用兩個參數的...

  1. auto animation = AnimationCache::getInstance()->animationByName("Enemy1Blowup");  
  2. auto animate = Animate::create(animation);  
  3. //CCCallFuncND* animateDone = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);  
  4. CCCallFuncN* animateDone = CCCallFuncN::create(std::bind(&EnemyLayer::removeEnemy1,this,enemy1->getSprite(),enemy1));//替換  
  5. auto sequence = Sequence::create(animate, animateDone,NULL);  
  6. Sprite* m_sprite = enemy1->getSprite();  
  7. m_sprite ->runAction(sequence);  
  8.   
  9.   
  10. void EnemyLayer::removeEnemy1(Node* pTarget, void* data){  
  11.     Sprite* m_sprite = (Sprite*) pTarget; //node節點為動作的執行者  
  12.     Enemy* enemy1 = (Enemy*)data;         //我們傳的自定義數據enemy1  
  13.     //...  
  14. }  


哈哈,這下子很清楚了吧。。再也不會混亂了。。

cocos2dx-lua 建立滑鼠監聽

重要關鍵字  EVENT_MOUSE_SCROLL addEventListenerWithSceneGraphPriority      if IsPc() then --建立滑鼠監聽         local listener = cc.EventListenerMouse...