1 回答

TA貢獻1797條經驗 獲得超6個贊
Cocos2d本身并不是基于mvc的理念來設計的,但是,這并不防礙在自己的游戲開發中使用mvc。實現方式肯定是多種多樣的,在此是怎么在cocos2d里面實現mvc的,同時,在最后,會寫一個簡單的游戲demo,當然,里面使用的是cocos2d+mvc。
現有問題
cocos2d里面有這樣一些類,CCSprite,CCLayer,CCScene,所有這些,都是CCNode的子類?;旧希蠹以谑褂胏ocos2d開發游戲的時候,都會采用下面的步驟來實現游戲邏輯:
通過應用程序代理類來初始化第一個CCScene(即AppDelegate里面的第一個CCScene),
CCScene里面實例化一個或者多個CCLayer,并把它們當作孩子添加進去。
CCLayer 里面實例化一個或者多個CCSprite,也調用addChild添加進去
CCScene 處理用戶輸入(比如touch事件和加速計的改變),同時更新CCLayer和CCSpirte的屬性,比如更改CCSprite的position,讓sprite運行一個或多個actioin等。
CCScene里在運行一個游戲循環(game loop,一般是1/60更新一次),然后CCLayer和CCSprite就在這個game loop里面做一些更新和游戲邏輯。
這個過程看起來非常簡單,而且也可以很快地做出游戲來。這也是為什么cocos2d這么流行的原因,它實在是太簡單了。但是,當你的游戲邏輯越來越復雜的時候,你的代碼會變得越來越難以維護。這里面最突出的問題就是,CCScene這個類負責的事情太多了---同時要處理用戶交互,還有負責游戲邏輯(邏輯層)和畫面顯示(表示層)。(譯者:根據SoC的原則,這顯然是不合理的,我們應該把職責分離開來,這樣代碼才更容易維護。同時SRP(單一職責原則)也是這么要求的,一個類只負責一件事情)
模型(Model)
MVC它會把一個系統劃分為以下幾個組件:
Model ,它負責與領域相關的邏輯處理代碼,也可以說是邏輯層,或者領域層。
View ,只負責界面顯示。
Controller ,它負責處理用戶交互。
讓我們先從model開始。Model代表了游戲邏輯。因為我現在正在制作一個platform游戲,所以,我講的一些東西也是與platform游戲相關聯的。我的游戲里面的model包含下面一些類(當然,僅僅是一部分類)
Player,
包含一些屬性,比如:player的位置、當前速度(x軸速度、y軸速度)等。
包含一些與player有關的處理邏輯,比如:run,walk,jmup等。
包含一個update方法,該方法會被游戲主循環每一幀刷新時所調用,它主要負責更新player model。
Platform,
包含一些屬性,比如:platform位置、寬度、高度等。
包含一些與platform有關的處理邏輯,比如:傾塌等
包含一個update方法,該方法會被游戲主循環每一幀刷新時所調用,它主要負責更新patform的model。
GameModel,
包含一些游戲世界的屬性,比如重力等。
包含一些方法來執行游戲邏輯。
包含一個update方法,該方法會在每一幀刷新的時候被game loop所調用,然后它就可以更新自己的狀態,同時還會觸發游戲世界里面的其它對象也相應地更新自己的狀態。
你可能會問:有些屬性你完全沒有必要重復定義,你可以直接從CCSprite里面得到,比如position、width、height等。我想說:有對有錯。說對呢,是因為它們確實差不多,可以拿來就用。說不對呢,那是因為,model有可能使用一些不同的計量單位,比如米,而不是像素。(比如box2d這樣的,就不是使用像素作為單位)。在我的model里面,我使用的是米,當然,你也可以使用英尺,或者其它單位。渲染引擎對于model來說是透明的,model完全不用關心。
視圖(View)
根據mvc的原則,view應該只負責界面顯示。它實際上也是在cocos2d里面實現mvc時,最簡單的一個。如果你有一個model,你可以使用CCLayer,然后添加一些CCSprite或者其它coocs2d類來處理顯示問題。把model和view分開的好處就是,你沒必要把model的屬性直接映射到view的屬性上面去。比如,你的玩家在x軸方向上移動,但是,你想讓它總是在距離屏幕左邊10px的位置。這時候,你就可以移動CCLayer了,而不是真的在移動sprite。當把model對象顯示出來的時候,你必須考慮單位,如果你使用的是米作為計量單位,你在渲染的時候必須轉化為像素。(你可以像box2d里面一樣,定義一個PTM_RATIO)那么你的model怎么和view打交道呢?你可以從controller里面得到view,或者你可以把game model制作成一個單例,然后使用靜態方法來處理它。
控制器(Controller)
controlller負責把view和model聯系起來。它的主要職責就是處理用戶輸入。由于我們需要實例化model和view,我發現在controller里面來做非常合適。我是把controller類繼承到CCScene類,然后我們需要建立一個初始的controller類,它由appDelegate來實例化。然而,這里會有一個問題,touch事件是由CCLayer來處理的,而它在我的設計里面的角色是view。而我又不想讓view來處理用戶輸入,所以,我需要傳遞一個view的引用給controller(不是直接傳遞,而是通過delegate),然后通過delegate來執行controller的touch事件處理代碼,以此來處理view里面的touch事件。好了,現在我的controller類就能夠處理來自view的用戶事件了。然后,它可以根據用戶的輸入來操作model,要么通過修改model的屬性,或者調用model的方法。再更新完model之后,我們的view也需要得到通知并更新。所有這些,我都在game loop里面完成,實際上它就是一個controller。controller的職責只是負責調用view的update方法,然后剩下的就交給view去完成即可。
- 1 回答
- 0 關注
- 681 瀏覽
添加回答
舉報