cocos2d平臺遊戲移到windows平臺運行

1. 代碼文件格式由utf8不簽名改成utf8簽名格式

2. 用到中文的源程序頭加  #pragma execution_character_set("utf-8")


cocos2d-x從手機遊戲到PC端遊

        這幾天一直在想,cocos2d-x跨平臺這麼牛X,爲什麼沒有人用cocos2d-x來作PC的端遊呢,如果用cocos2d-x作2D的端遊,那豈不是windows,linux,Mac,ios,android全平臺通吃了。當然了,這只是cocos2d-x,但是如果我們使用的是cocos3d那豈不是,一個遊戲引擎,可以在任何平臺上運行,所有平臺通喫。並且是2D遊戲,3D遊戲都通喫的遊戲引擎,而且還使用的是GPU渲染的遊戲,而且遊戲運行的性能大家就可想而知了。

       想到這裏,自已便開始興奮的快要跳起來了。

       我們先來分析一下理論上的可行性。

       1.用過cocos2d-x的人都知道,cocos2d-x是使用的標準c++語法寫成。所以c++本身就是windows,linux,mac通行的。

       2.然後,我要說一下游戲使用的圖形渲染引擎,cocos2d-x使用的是OpenGL ES,之所以使用從OpenGL裁剪的OpenGL ES是因爲手機端使用完全的OpenGL性能有問題,但讓我們高興的是OpenGL ES的代碼可以完全運行與OpenGL顯卡。而且性能不比手機的GPU差。還有一個更好的消息就是OpenGL和OpenGL ES的協議正在被OpenGL組織設法合併爲一個協議。

      3.支持windows系統的顯卡硬件提供商因爲受到微軟的軟件協議管控,不能自行開發性能更高的顯示硬件,所以一般顯卡的生產商都會全力支持OpenGL協議,以顯示他們新硬件的性能。所以,幾乎所有可以跑windows系統的顯卡都可以找到OpenGL驅動。換句話說,就是windwos,linux,mac都支持OpenGL硬件協議。

   結合上邊的三條分析,我們沒有理由不相信cocos2d-x或者cocos3d-x不會成爲所有平臺通喫的遊戲開發引擎。

  下邊是對cocos2d-x引擎全屏顯示的一些修改。linux和Mac應該也會很方便。因爲你可以看到cocos2dx的cocos2dx\platform目錄下有很多操作系統相關的文件夾。如下圖:

cocos2d-x從手機遊戲到PC端遊 - ♂蘋果 - 眼睛想旅行
還有一些我不認識的系統。
    經過我一個上午的調試和找資料,我把vs2010下的一個cocos2d-x遊戲項目調成在windows上全屏顯示了。
要全屏顯示,要改以下三個地方:
1.cocos2dx\platform\win32目錄下的CCEGLView.cpp文件中的"bool CCEGLView::initGL()"前邊加入以下代碼:

HWND    hDesk;      RECT    rc;      hDesk   =    GetDesktopWindow();      GetWindowRect(    hDesk,   &rc    );      SetWindowLong(    m_hWnd,    GWL_STYLE,    WS_BORDER    );        SetWindowPos( m_hWnd,    HWND_TOPMOST,0,0, rc.right, rc.bottom,SWP_SHOWWINDOW);

 ShowWindow(hDesk,SW_SHOWMAXIMIZED);

加入後的樣子如下圖:(記得改完了,要再把cocos2dlib項目再編譯一下)

2.再修改你自已的cocos2d-x項目中的main.cpp:
把原來代碼中的
eglView->setFrameSize(480, 320);
改成下邊代碼

RECT rcWindow;  HWND xxtmp = eglView->getHWnd();  GetWindowRect(xxtmp,&rcWindow);  int w = (int)rcWindow.right;  int h = (int)rcWindow.bottom;  eglView->setFrameSize(w, h);

改過之後的效果如下圖:
cocos2d-x從手機遊戲到PC端遊 - ♂蘋果 - 眼睛想旅行
3.第三個要改地方是爲了讓我們的項目能動自適應顯示器的分辨率而沒有黑邊。要改的地方是在我們的AppDelegate.cpp中修改方法AppDelegate::applicationDidFinishLaunching()加入設置EGLView顯示方式的代碼。如下圖

pEGLView->setDesignResolutionSize(480,320, kResolutionExactFit);

kResolutionExactFit:這個參數表示自動拉申以適合屏幕大小。
還有幾個別的參數,這裏就不寫了,有要了解的,大家去網上搜,一搜一大把。
好了,這樣設置完之後,我們的cocos2d-x遊戲項目就在windows系統下變成像端遊一樣的全屏顯示了。接下來的事情就要看大家的主觀能動性和想象力了。
有興趣的,可以進我建的QQ羣:213571088
//================================

Cocos2d-x win32 版本,其中的HelloWorld演示項目的CPU佔用率一直很高,有時候高達100%,所以在一番排查後,發現是由於在主循環裏使用了 Sleep(0),它位於 cocos2dx\platform\win32\CCApplication.cpp,大致長像如下:

1
2
3
4
5
6
7
while( 1 ) {
if( 有消息 ) {
if( 時間到 ) 更新計時, call 主循環函數;
else Sleep(0);
}
// 其他跳出循環判斷代碼
}

也就是說,該循環除了執行 mainLoop 以外,花了大量時間在檢查消息和 Sleep(0) 上面。

並且,我還發現一個奇怪的現象(暫時還不清楚是爲什麼),即:

HelloCPP 項目的 AppDelegate.cpp 文件中有一行代碼:

1
2
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);

上面的 60 ,如果改大,不起任何作用,幀速始終是 60 不會變。但如果改到小於60,是可以起作用的。

於是,解決 CPU 佔用的思路,始於 “是否可以降低循環精度” 的念頭。

已知正常情況下,執行 Sleep(1) ,會睡大概 1/50 秒,這個時間並不精確也不準確,看上去無法滿足 60 fps 這個流暢度需求。不過,如果遊戲運行幀速不需要這麼高,比如 30 fps,則該方案大爲可行。

經實際測試,將 Sleep(0) 改成 Sleep(1), 再將上面代碼中的 60 改成 25, 效果非常顯著。但另一個問題來了:如果每遊戲循環做的事有點多,時間有點長,那麼遊戲將被拖慢。

原engine中,同步時間的代碼如下:

1
2
3
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart) {
nLast.QuadPart = nNow.QuadPart;

因爲每次在 nLast 中記錄 nNow 時間,並用時間差與設定間隔作比較,時間差往往會比設定間隔要大,如果是在不精確的 Sleep(1) 以及每循環負擔比較大的情況下,將導致每幀實際所花的時間,會超出設定間隔不少,從而拖慢遊戲速度(如果遊戲按幀步進計時的話)。

爲解決這個問題,我用的是時間對齊的方式。其實就是改了一下更新nLast 的表達式:

1
nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % m_nAnimationInterval.QuadPart);

這樣每幀的總消耗時間就相當的恆定了。

至於在保持 60 fps的情況下,也能讓 cpu佔用率在0%,可以修改 Sleep(1) 的精度。

通過查找資料,發現 Winmm.lib 庫中有timeBeginPeriod(1); timeEndPeriod(1); 函數可以用於該目的,令 Sleep(1) 的精度提升到1毫秒級別,遂動手改之:

1. 添加 Winmm.lib 庫的引用。我在這裏採取了在 CCApplication.cpp 頭部添加  #pragma   comment(lib, "Winmm.lib")  語句的方式。

2. 在 while(1) 代碼段的前後,分別放上 timeBeginPeriod(1); timeEndPeriod(1);  語句

這樣基本就搞定了。


//================================

網上搜到下面的參考資料,但可能因爲Cocos2d-x版本不同,已經不好按這種方式修改了。於是自己想到了解決辦法。

參考資料:

http://download.csdn.net/detail/chenzhizs/4813602


其實Win32想弄成全屏不難,兩個步驟搞定:1.去掉標題欄;2. 設置爲想要的分辨率。

1. 在CCEGLView.cpp的CreateWindowEx中,把WS_CAPTION 這個屬性註釋掉或刪掉,即可沒有標題欄。

2. 在main.cpp中設置eglView->setFrameSize(1920, 1080);

這樣基本就可以了,應該在各版本中都可以用。



//================================

Cocos2d-x在windows下實現全屏(cocos2d-x+win32+fullScreen)

 2522人閱讀 評論(1) 收藏 舉報
 分類:
 

本人使用的cocos2dx版本爲cocos2d-x_v2.1.5b,之前查到一些解決全屏的辦法,但是這些方法對新版本已經不再適用,經過辛苦查詢,總算是皇天不負有心人,找到了新版本的解決辦法。參考原文:http://www.cocos2d-x.org/forums/6/topics/24432

方法如下:(親測可行)

1、在目錄cocos2dx\platform\win32下找到CCEGLView.hCCEGLView.cpp,用記事本打開,在CCEGLView.h中添加如下代碼

  1. bool enterFullscreen(int fullscreenWidth=0, int fullscreenHeight=0);  
  2. bool exitFullscreen(int windowX, int windowY, int windowedWidth, int windowedHeight, int windowedPaddingX, int windowedPaddingY);  
  3. int getFullscreenWidth();  
  4. int getFullscreenHeight();  

2、在CCEGLView.cpp中添加如下代碼

  1. int CCEGLView::getFullscreenWidth()  
  2. {  
  3.     return GetDeviceCaps(m_hDC, HORZRES);  
  4. }  
  5.   
  6. int CCEGLView::getFullscreenHeight()  
  7. {  
  8.     return GetDeviceCaps(m_hDC, VERTRES);  
  9. }  
  10.   
  11. bool CCEGLView::enterFullscreen(int fullscreenWidth, int fullscreenHeight)  
  12. {  
  13.     DEVMODE fullscreenSettings;  
  14.     bool isChangeSuccessful;  
  15.   
  16.     if(fullscreenWidth == 0 || fullscreenHeight == 0)  
  17.     {  
  18.         fullscreenWidth  = GetDeviceCaps(m_hDC, HORZRES);  
  19.         fullscreenHeight = GetDeviceCaps(m_hDC, VERTRES);  
  20.     }  
  21.   
  22.     int colourBits       = GetDeviceCaps(m_hDC, BITSPIXEL);  
  23.     int refreshRate      = GetDeviceCaps(m_hDC, VREFRESH);  
  24.   
  25.     EnumDisplaySettings(NULL, 0, &fullscreenSettings);  
  26.     fullscreenSettings.dmPelsWidth        = fullscreenWidth;  
  27.     fullscreenSettings.dmPelsHeight       = fullscreenHeight;  
  28.     fullscreenSettings.dmBitsPerPel       = colourBits;  
  29.     fullscreenSettings.dmDisplayFrequency = refreshRate;  
  30.     fullscreenSettings.dmFields           = DM_PELSWIDTH |  
  31.                                             DM_PELSHEIGHT |  
  32.                                             DM_BITSPERPEL |  
  33.                                             DM_DISPLAYFREQUENCY;  
  34.   
  35.     SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST);  
  36.     SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);  
  37.     SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, fullscreenWidth, fullscreenHeight, SWP_SHOWWINDOW);  
  38.     isChangeSuccessful = ChangeDisplaySettings(&fullscreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL;  
  39.     ShowWindow(m_hWnd, SW_MAXIMIZE);  
  40.   
  41.     resize(fullscreenWidth, fullscreenHeight);  
  42.   
  43.     return isChangeSuccessful;  
  44. }  
  45.   
  46. bool CCEGLView::exitFullscreen(int windowX, int windowY, int windowedWidth, int windowedHeight, int windowedPaddingX, int windowedPaddingY)  
  47. {  
  48.     bool isChangeSuccessful;  
  49.   
  50.     SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_LEFT);  
  51.     SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);  
  52.     isChangeSuccessful = ChangeDisplaySettings(NULL, CDS_RESET) == DISP_CHANGE_SUCCESSFUL;  
  53.     SetWindowPos(m_hWnd, HWND_NOTOPMOST, windowX, windowY, windowedWidth + windowedPaddingX, windowedHeight + windowedPaddingY, SWP_SHOWWINDOW);  
  54.     ShowWindow(m_hWnd, SW_RESTORE);  
  55.   
  56.     return isChangeSuccessful;  
  57. }  

3、如何使用

main.cpp中添加

  1. // Create the application instance  
  2.     AppDelegate app;  
  3.     CCEGLView* eglView = CCEGLView::sharedOpenGLView();  
  4.   
  5.     // Set the frame size to the full screen value  
  6.     //eglView->setFrameSize(eglView->getFullscreenWidth(), eglView->getFullscreenHeight());  
  7.   
  8.     eglView->enterFullscreen(0, 0);  
  9.   
  10.     int ret = CCApplication::sharedApplication()->run();  

這樣就能夠實現全屏了!


//================================
這個問題我解決了 確實很簡單  showCursor(False)    就可以隱藏當前的鼠標,如果要自定義鼠標格式就自己做個精靈,然後再鼠標移動事件裏面移動即可。 但是要主要鼠標事件 裏面獲取的座標不是 遊戲裏面的座標。而是以windows 標準 的座標。 所以需要轉化一下。 

//============================

某些時候,我們可能需要把pc上面的Flash動畫拿到Cocos2d-x上面使用。

解決方案:
第一:
若你的.fla源文件中不帶有骨骼動畫,則你可以使用
TexturePacker結合AnimatePacker來解決這個問題。
a.把.fla文件導出爲.swf
b.把.swf文件直接丟到TexturePacker中,它會自動幫你解析出所有的幀,並導出爲.plist文件,它附帶一張.png圖
c.把.plist文件丟到AnimatePacker中,它也會自動幫你解析出所有的幀,然後根據需要,製作你動畫,AnimatePacker不知道怎麼使用的,可以看我
前面的文章

這樣你的Falsh動畫就能轉移到Cocos2d-x使用了。

這種方案在b這個步驟的時候經常會遇到一個問題,就是你丟進去的.swf文件只能幫你解析出來一幀,接下來我們來分析這種情況。
出現這種情況的原因:大部分的Flash動畫都是比較複雜的,它包含了多套的動畫方案,而且它們一般都不是設計在主場景中的,而是綁定在各個元件中的,主場景中只是丟了一張圖片。這樣就帶來了問題了,因爲TexturePacker只會解析你主場景中的幀動畫,所以,你就只解析到了一張圖片。

那這個問題我們要怎麼解決呢?跟TexturePacker的作者商量一下吧。能不能把元件中的幀動畫也解析了呢。或許以後可以,但是至少目前是不行的。所以,我們能做的就是如下:

a.在Flash cs6中文件->新建->ActionScript 3.0,新建一個.fla文件,假設我們命名爲new.fla

b.選中原.fla文件中元件裏面綁定的幀動畫,右鍵複製幀,黏貼到new.fla的主場景中,你可以把所有元件中的動畫都黏貼到new.fla中,這不會影響我們之後的讀取。都完成之後,右鍵另存爲new.swf。

c.然後把new.swf文件丟到TexturePacker中,怎麼樣,是不是所有幀都出來了?而且一樣的幀TexturePacker還會自動幫你合併到一起,可以減少生成的.png圖片大小。導出爲.plist文件,附帶一張.png圖。

d.把.plist文件丟到AnimatePacker中,它也會自動幫你解析出所有的幀,然後根據需要,製作你動畫。
470F5A523EC65FC072AA8CD12665B8B123DA7C0099293_800_172.jpg 

這種方案或許比較繁瑣,但是是目前我能實現的不帶骨骼動畫的.fla文件的移植到Cocos2d-x中使用的方法。接下來介紹一下帶骨骼動畫的.fla文件又是如何導出爲Cocos2d-x可以使用的文件

第二:
第二個方案我們是要使用到的一個工具叫
Flash2Cocos2d-x,至於安裝方面問題,也可以看看我前面的文章

當我們的.fla文件中不帶骨骼數據的時候,我們使用的上面的方案。我也嘗試使用Flash2Cocos2d-x來導出,但是在Import選項上面時,第一個和第二個都沒有反映,第三個提示不包含骨骼數據,或許這個工具只能用來導出骨骼動畫吧!

所以,你也可以把這個方案當作Flash2Cocos2d-x的一點資料吧。

大體步驟如下:
打開.fla文件,窗口->其他面板->SkeletonSWFPanel,打開面板,點擊import(默認爲All library items),若你有封裝了骨骼信息的.swf文件,也可以選擇第三項。waiting......然後所有的骨骼信息就都出來了。

9CAC2EC3D8D998F1D336552EA09B4613008E212D32834_522_169.JPEG 

F8B35C0ADCED9E414F92BCBD3CE6D4925303524CD5DE7_229_109.JPEG 

4916420D48A1D017D7A5AC306B47ED219F20AF6220553_800_614.jpg 

至於具體的這個工具怎麼做骨骼動畫,可以參考
作者的文章
然後Export導出文件, 60379CCFA834F4A5D869645186DBAD450EE2E098ED3AC_213_133.JPEG 
這邊有4個選項,第一個會直接導出一張封裝了骨骼信息的PNG圖片,第二個導出帶有骨骼信息的swf動畫,第三個暫時不明白,第四個導出許多單張的PNG圖片和XML文件。據論壇上面使用過這個工具的朋友說(這個方案本人沒在Cocos2d-x中引用過),一般都是使用第四個選項,然後再使用TexturePacker工具,把所有的單張圖片生成圖片集.plist文件,這樣需要放入到Cocos2d-x 資源文件夾中的文件就有.png .plist .xml 3個文件,跟第一種方案最後是一樣的。但是它們在Cocos2d-x中引用需要使用不同的類庫(關於類庫在cocos2d-x2.0.4中報錯的問題,應該改一下類的路徑就可以了)。這邊需要用到的類庫就是在下載的工具裏面的Flash2Cocos2d-X子文件夾中的類(大概有40+,是不是全部需要用到,我沒實踐過)。


最後在代碼方面的實現:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// step 1: add your skeleton xml file 
//CCConnectionData::sharedConnectionData()->addData("knight.xml"); 
CCConnectionData::sharedConnectionData()->addData("zombie.xml"); 

// step2: add plist and png to cache 
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("zombie.plist""zombie.png"); 

// step 3: create a CCSpriteBatchNode 
//CCSpriteBatchNode *batchNode = CCSpriteBatchNode::create("knight.png"); 
CCSpriteBatchNode *batchNode = CCSpriteBatchNode::create( "zombie.png" ); 

// step 4: create a armature just need armature name, plist, picture, and a CCSpriteBatchNode 
// armature = CCArmature::create("Knight_f/Knight", "Knight_f/Knight", "knight.plist", "knight.png", batchNode); 
armature = CCArmature::create("Zombie_f/Zombie""Zombie_f/Zombie", batchNode); 

armature->getDisplay()->setPosition(ccp(size.width/2, size.height/2)); 
armature->getDisplay()->setScale( 1 ); 

// step 5: play the animation 
armature->getAnimation()->playTo("stand");



這個工具對於骨骼動畫的支持還是挺好的,很期待作者繼續更新。

當然我們也可以使用CocosBuilder來做骨骼動畫,在CocosBuilder做骨骼動畫的時候,遇到了一個骨骼動畫和Cocos2d-x裏面的action結合出現action只運行固定時間的異常,比如我action設置的是2s,但是它只運行0.5s就停止了,至於這個問題是什麼導致的,暫時還沒解決,以後解決了會在我的博客上面補上。如果有哪位朋友懂的,麻煩指導一下!

總結一下:
第一:PC上面的不帶骨骼動畫的.fla文件我們導出爲.swf文件後,結合TexturePacker和AnimatePacker來開發
第二:帶骨骼動畫的.fla文件或者是分裝了骨骼信息的.png和.swf文件,我們可以使用Flash2Cocos2d-x結合TexturePacker來開發。
第三:製作骨骼動畫可以使用Flash2Cocos2d-x,也可以使用Cocosbuilder來製作,關於使用Cocosbuilder如何製作骨骼動畫,可以看我前面的博客。

原文鏈接:
http://momowing.diandian.com/post/2012-11-22/40042074075

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章