1. 程式人生 > >cocos2d-x面試題(一)

cocos2d-x面試題(一)

(一)執行順序相關:
執行順序:

我們知道Cocos2d-x程式的執行順序是從AppDelegate這個類開始,在其中做一些必要的初始化並建立執行第一個場景,之後有一個主迴圈來維持遊戲每一幀的迴圈,並在此期間執行遊戲的相關邏輯。當遊戲結束時,會呼叫導演類的end方法,將會執行遊戲的清理工作,並結束了OpenGL檢視的執行。不同的平臺會有不同的封裝,PC端由OpenGL封裝,移動端則由OpenGLEx,最後退出遊戲程序,結束了整個遊戲的執行

(二)各種類:

①導演(Director) 
它將提供當前執行所需一切必備的資訊,如幀率,與上一幀間隔的時間;螢幕解析度以及用於迴圈執行的時間表等等,而最重要的功能是管理當前的遊戲場景。導演類將是Cocos2d-x
中最關鍵的一個類。 ②場景(Scene) 它則主要側重於定義不同場景的用途,如開始介面,遊戲關卡,設定選項介面等等,每一場景都有自己相應的佈景或者角色。但是它往往不直接顯示場景的內容,而將依賴場景中的圖層,每一個場景往往有多個圖層。 ③圖層(Layer) 它主要用於佈置場景,如遊戲中遠處的森林和近處的山丘將會使用一個圖層,近處的怪物和英雄可能會使用一個圖層,再近處的一些裝飾和遮擋也會使用一個圖層。甚至一些更加複雜的遊戲,充當背景的圖層還不只一個。如多個背景錯開,還設定上不同的移動速度,可以形成場景的生動效果,從而提升遊戲的吸引力。 ④精靈(Sprite) 它和所有顯示物件一樣都繼承與Node物件,它是最最最常用的顯示物件。它可以載入資源圖片並展示在螢幕上,在遊戲或電影裡,精靈就像電影裡的演員;它可以充當玩家控制角色,也可以充當程式控制角色。還有食物,樹木,寶貝等等,都可以用精靈來充當。 ⑤動作(Action) 在遊戲中,無論是玩家操作的英雄的各種行為,敵方怪物的各種行為,還是其他怪物的一些變化,基本都是由一些單獨的動作疊加來完成的。如控制精靈的旋轉,移動和縮放,還有一些複雜的物件,如跳遠,貝塞爾曲線和改變顏色等等。 總而言之,一個導演可以管理多個場景,每個場景代表遊戲中的一個關卡或一個介面,一個場景中可以包含多個佈景,有的可能代表背景,有的可能代表前景,背景可能不止一個。一個佈景可以包含多個精靈,精靈可以是玩家控制的英雄,可以是敵方的怪物。精靈根據遊戲情節的需要可以單獨執行某一段動作,連續執行一系列動作,或者執行多個動作,如跑步的同時進行旋轉等等。

(三)工具相關:
工具:
你常用的Cocos2d-x相關的工具有哪些呢?

在這裡我們想到的有Cocos studio,TiledMap,ParticleEditor(粒子編輯器),Flash,PS等等 
①Cocos Studio 
Cocos Studio是一款功能強大的編輯器,即介面編輯,場景編輯,動畫製作,3D場景編輯,圖集合並等功能為一體,可以快速的釋出資源,可以說是遊戲開發一站式解決方案,運用低成本、高效率;高效能,一次製作,多終端平臺共享的特性;並且它有豐富的外掛,素材庫,使遊戲開發更加靈活更加便捷。 
②TiledMap 
地圖編輯器,採用的是傳統畫素遊戲所使用的固定方格的拼接方式,可以使用極少的紋理製作豐富的場景,新版本的Cocos2d-x
支援老版本TiledMap的菱形格式的地圖。 ③ParticleEditor 粒子編輯器,提供了豐富的粒子特效,大部分情況下只需要修改它提供的模板就能達到自己想要的效果,最終可以儲存成*.plist檔案格式,Cocos2d-x對它的支援非常的不錯 ④Flash、PS 這就不多說了,這些都是美術必備的軟體,由於Flash製作動畫的功能強大、歷史悠久,使用它製作動畫效率非常高,因此我們常常會使用Flash製作動畫,匯出成cocos2d-x所支援的格式。這樣,我們的動畫不僅製作效率,還與遊戲引擎進行接耦,對不同的平臺,只要做出一個相應的匯出外掛即可 CocoStudio是一套基於Cocos2D-X引擎的工具集,包括UI編輯器、動畫編輯器、場景編輯器和資料編輯器。UI編輯器和動畫編輯器主要面向美術,而場景編輯器和資料編輯器面則面向遊戲策劃,這四個工具合在一起構成了一套完整的遊戲開發體系,幫助開發者進一步降低開發難度、提高開發效率、減少開發成本。 UI編輯器:支援目前Cocos2D-X的所有控制元件,同時支援多解析度適配、碎圖合併以及自定義UI。 動畫編輯器:支援骨骼關鍵幀動畫、序列幀動畫,同時支援碎圖合併、Flash動畫直接匯入等。 資料編輯器:把策劃用的Excel數值表分解,然後轉化成Cocos2D-X可以識別的格式。 場景編輯器:可以整合我們之前CocoStudio其他編輯器的資源,編輯當前的遊戲場景,實時演示,所見即所得。同時也支援第三方的工具模式

(四)記憶體管理相關
請描述cocos2dx的記憶體管理機制和原理,怎麼判斷cocos2dx程式碼是否有記憶體洩露

cocos2dx基於引用計數管理記憶體,所有繼承自CCObject的物件都將獲得引用計數的能力,可通過呼叫retain成員函式用於引用計數值,呼叫release減少引用計數值,當計數值減為0時銷燬物件.
在程式中過載mallocfreenewdelete
void* MyMalloc()
{
 printf("malloc");
 return malloc();
}
void MyFree(void* fp)
{
 printf("free");
 free(fp);
}

new delete和malloc free的聯絡與區別

mallocfree是C語言標準函式庫中的兩個函式,new/delete是C++語言中兩個運算子。
malloc/freenew/delete都是用來申請動態記憶體的。
new 不止是分配記憶體,而且會呼叫類的建構函式,同理delete會呼叫類的解構函式,而malloc則只分配記憶體,不會進行初始化類成員的工作,同樣free 也不會呼叫解構函式。
malloc得到的指標無型別,new出來的指標是帶有型別資訊的。
對於非內部資料型別的物件而言,光用maloc/free無法滿足動態物件的要求。物件在建立的同時 要自動執行建構函式,物件在消亡之前要自動執行解構函式。由於malloc/free是庫函式而不是運算子,不在編譯器控制權限之內,不能夠把執行建構函式和解構函式的任務強加於malloc/free。
如果用free釋放“new建立的動態物件”,那麼該物件因無法執行解構函式而可能導致程式出錯。如 果用delete釋放“malloc申請的動態記憶體”,理論上講程式不會出錯,但是該程式的可讀性很差。所以new/delete 必須配對使用,malloc/free也一樣

autorelease和release的區別?

release 會立馬對物件進行引用計數減一操作,如果當前物件的引用計數小於0,則會進行釋放。
autorelease 則會將該物件放入到自動釋放池中,當一幀結束的時候會執行release操作進行引用計數減一操作,如果當前物件的引用計數小於0,則會進行釋放。

有哪些操作會導致記憶體洩露,如果發生記憶體洩露如何處理?

 回答:在堆上分配動態記憶體和釋放動態記憶體的方法是 newdelete,在申請記憶體之後,如果不使用了就需要delete掉,不然就會造成記憶體的溢位。解決辦法:使用vld、memwatch載入到專案中,除錯

cocos2dx資料儲存用過哪些

答案:CCUserDefault和SQList
CCUserDefalt存在的的問題
沒有記錄和表的概念
你會發現,如果要設定多存檔,必須自己操作,而且程式碼會變得複雜,容易出錯。
對於簡單的遊戲可以使用CCUserDefalt,但是對於複雜遊戲,可以考慮使用SQLite。
SQLite存在的問題
沒有資料型別安全
比如,如果你錯寫把一個Integer按Bool讀取,是沒有錯誤提示的
沒有存檔資料完整性的校驗

(五)優化相關

簡述CCSpriteframeCache CCSpriteBatchNode?

回答:CCSpriteFrameCache 快取了所有CCSpriteFrame. 可以一下方式獲取特定frame並設定給Sprite. 前提是檔案已經快取
CCSpriteBatchNode 中的所有CCSprite只會被渲染1次,因此可以提高遊戲的FPS。
限制:加入到CCSpriteBatchNode 中的CCSprite必須使用同一張紋理圖

減少記憶體開銷的方法有哪些?圖片壓縮方法有哪些?

回答:及時釋放,減少洩露,重用資源,plist,延遲載入,分部載入等。
調整載入圖片的方式,改變圖片的格式,.pvr,pngquant壓縮圖片 、32點陣圖片改為16圖片載入

cache的機制原理

回答:把新加進記憶體的資源做一個hashmap儲存,每一個資源加一個key。每次載入資源的時候,先查詢資源是否存在,存在直接返回,否則載入進記憶體。

場景切換的記憶體處理過?

回答:先構建新場景,然後顯示新場景,然後釋放舊場景。
但是在新場景onEnter,舊場景onExit的時候,會呼叫舊場景的cleanup,清理schedule相關部分。

說一下CCAction和CCActionMessager

CCAction是動作的基類,主要使用CCFiniteTimeAction有限次動作執行,就是按時間順序執行一系列動作,執行完後動作結束;
CCFiniteTimeAction又分為CCActionInstanse(瞬時動作的基類)和CCActionInterval(延時動作的基類)。CCActionInstanse:沒什麼特別,跟CCActionInterval主要區別是沒有執行過程,動作瞬間就執行完成了;CCActionInterval:執行需要一定的時間(或者說一個過程)。我們用的最多的就是延時動作,下面對它進行單獨介紹。
CCActionMessage是管理所有Action的單例,一般情況下並不直接使用這個單例,而是使用CCNode的介面,但是假如你想操作的目標不是CCNode的子類或者你想暫停/恢復行動就要使用到CCActionMessager

cocos2dx中,觸控的優先順序的規則

this->mTouchPriporty
Layer 優先順序越小越高越先響應事件

同等優先順序下,後新增的Layer先響應事件

(六)螢幕適配相關
cocos2d-x的螢幕適配解決方案?

回答:pEGLView->setDesignResolutionSize(480, 320, kResolutionNoBorder);第三個引數,
kResolutionExactFit:會靠拉伸來填滿螢幕,舉例來說背景圖會變形來填充螢幕,因為1024:768=1.3480:320=1.5,寬高比不同,圖片也就無法等比縮放來填滿螢幕,只能變形了。
kResolutionNoBorder: 看不到黑邊,實際就是寬高等比縮放,但縮放比例取寬比和高比之中大的那一個。
kResolutionShowAll:全部顯示,可以理解為保證內容都顯示在螢幕之內,實際也是寬高等比縮放,但縮放比例取寬比和高比之中小的那一個

(七)其他
列舉幾種多執行緒的同步機制

 臨界區, 事件, 互斥量,訊號量

說一說同步與互斥的區別

互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源
  

是不是一個父類寫了virtual函式,如果子類覆蓋他的函式不加virtual也能實現多型?

是的,virtual會被隱形的繼承的

如何判斷一段程式是由C編譯的還是由C++編譯的?

如果是要你的程式碼在編譯時發現編譯器型別,就判斷_cplusplus或_STDC_巨集,通常許多編譯器還有其他編譯標誌巨集,

#ifdef __cplusplus
       cout<<"c++";
#else
       cout<<"c";
#endif

簡述陣列與指標的區別,引用和指標的區別

陣列時連續分配一串單元,數目開始定義的時候就必須固定下來,看起來整潔,但是寫的程式是死程式,容易浪費記憶體
指標存放一個地址值,表示指向某一個單元,可以用指標來索引單元。陣列可以完成棧,堆,樹等等的操作,它在程式設計時候的好處是非常的靈活,在構建思路的時候有很大的靈活性

指標是一個實體,而引用僅是個別名;
引用使用時無需解引用(*),指標需要解引用;
引用只能在定義時被初始化一次,之後不可變;指標可變;
引用“從一而終” ^_^
引用沒有 const,指標有 constconst 的指標不可變;
引用不能為空,指標可以為空;
“sizeof 引用”得到的是所指向的變數(物件)的大小,而“sizeof 指標”得到的是指標本身(所指向的變數或物件的地址)的大小;
sizeof(T) == sizeof(T&) 恆為真,但是當引用作為類成員名稱時,其佔用空間與指標相同4個位元組(沒找到標準的規定)。
指標和引用的自增(++)運算意義不一樣;