Cocos2d-x里面如何实现MVC(四)
来源:互联网 发布:淘宝筛选 编辑:程序博客网 时间:2024/06/07 01:43
Cocos2d-x里面如何实现MVC(四)
在上一篇文章中,我们使用cocos2d-x基于mvc做了一个简单了游戏架子,这个架子还非常简单,还有许多东西有待实现。
介绍模型
在上一篇博文中,我们介绍了view和controller。为了实现mvc模式,我们还需要添加一个model类来维护游戏的状态。我们的实现应该要包含下列这些类:
1 GameBoardView - 也就是View,
2 GameBoardController - 也就是Controller.
3 GameBoard – 也就是Model.
Model 实现
GameBoard 实现
我们在第一部分所描述的需求是这样子的:
。。。一个game board 是通过n行n列组成的,它会随着游戏难度有所变化。
因此,我们按照下面的编码方式来实现之:
Class GameBoard :
public
CCObject {
public
:
int
numberOfRows;
int
numberOfColums;
void
initGridSize(
int
aNumberOfRows,
int
aNumberOfColumns){
this
->numberOfColumns = aNumberOfColumns;
this
->numberOfRows = aNumberOfRows;
}
}
请注意,model是从CCbject继承过来的---因为model只需要关注game board model的状态就行了(当然,还有相应的更新状态的方法)---我们不应该把其它东西也放进来,比如继承到CCNode就不行,我们并不需要CCNode的东西,所以,为了纯粹性,我们这里继承到game board 。
GameBoardView 的实现
我们现在需要修改View,同时它包含一个model的引用,我们可以通过initWithGameBoard方法来初始化这个成员变量:
class
GameBoardView ::
public
CCLayer {
public
:
GameBoard *gameBoard;
void
initWithGameBoardModel(GameBoard *aGameBoard);
}
具体GameBoardView的实现细节如下:(为了演示方便,我们忽略了实际渲染每一个小方块的代码)
void
GameBoardView::initWithGameBoard(GameBoard *aGameBoard)
{
if
(gameBoard != NULL){
gameBoard->release();
gameBoard = NULL;
}
this
->gameBoard = aGameBoard;
this
->gameBoard->retain();
// render gameBoard background
CCSprite *gameBoardSprite = CCSprite::spriteWithFile(
"gameBoard.png"
);
gameBoardSprite->setAnchorPoint(ccp(0, 0));
this
->addChild(gameBoardSprite);
for
(
int
i=0; i<gameBoard->numberOfRows; i++)
for
(
int
j=0; j<gameBoard->numberOfColumns; j++)
{
// position and render game board spacse
}
}
GameBoardController
最后,我们要更新GameBoardController的init方法,因为view需要把GameBoard对象通过init方法注入进去,所以,我们在controller的init方法里面,就应该定义好model对象,然后传递给view。
virtual
bool
init(){
bool
bRet =
false
;
do
{
// 先调用超类的init方法
CC_BREAK_IF(! CCLayer::init());
GameBoard *gameBoard =
new
GameBoard();
gameBoard->initGridSize(7, 9);
view = GameBoardView::node();
view->initWithGameBoard(gameBoard);
this
->addChild(view, 0);
bRet =
true
;
}
while
(0)
beturn bRet;
}
处理touch事件
GameBoardView updates
我们的View虽然继承了CCLayer,但view本身是不应该处理用户的交互(touch事件)的,所以,我们需要定义一个代理(GameBoardViewDelegate)。(译者:为什么这里要定义代理呢?所谓代理代理,当然就是你不想做的事,找别人去做,这就是代理。所以,当你写代码的时候,你想保持类的简单性、重用性,你就可以把事件尽量都交给其它类去做,自己只管做好自己的事。也就是SRP,单一职责原则。如果一个类关注的点过多,做的事情太多。这些事情不管是你直接做的,还是调用别的对象去完成的。这都不行,自己做这些事,那就会使类的功能复杂化,维护不方便。而过多地调用其它对象来完成一些事情,表面上看起来好像不错,实际上是过度耦合了。我们编写类的原则应该是追求高内聚,低耦合的。可能你会说,用代理不也是交给别人做吗?没错,问的好。但是,代理是接口,我们是针对接口编程,所以它的重用性会非常好。因此,下次当你想写可扩展和可重用的代码的时候,不妨先想想代理这个东西吧。C++和java者是用接口实现的,而objc里面delegate是用protocol实现的,具体怎么转换的,比较一下应该就可以了。)
class
GameBoardViewDelegate
{
public
:
virtual
void
dealWithTouchesBegan(GameBoard *gameBoard,
int
row,
int
column) = 0;
};
我们还需要再修改一下GameBoardView的init方法,通过传送一个delegate进来处理touch事件。
void
initWithGameBoard(GameBoard *aGameBoard, GameBoardViewDelegate *aDelegate);
下面是touch事件的具体实现,记得先在初始化时setIsTouchEnable(true)哦^_^:
void
GameBoardView::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
CCTouch *touch = (CCTouch*) pTouches->anyObject();
if
(touch == NULL)
return
;
// 置换坐标,等效如下
//CCPoint location = touch->locationInView(touch->view());
//location = CCDirector::sharedDirector()->convertToGL(location);
CCPoint point =
this
->convertTouchToNodeSpace(touch);
// calculate row and column touched by the user and call a delegate method
int
row = 0;
int
column = 0;
// ...
this
->gameBoardViewDelegate->dealWithTouchesBegan(gameBoard, row, column);
}
GameBoardController 更新
GameBoardController将会负责处理用户touch事件,所以,我们需要让GameBoardController实现GameBoardViewDelegate接口:
class
GameBoardController :
public
CCLayer,
public
GameBoardViewDelegate
{
public
:
//...
virtual
void
dealWithTouchesBegan(GameBoard *gameBoard,
int
row,
int
column){
// do the game logic here and update view accordingly
}
// ...
};
还有最后一步,那就是修改view的init方法,把controller传递进去。
// initialize view
view->initWithGameBoard(gameBoard,
this
);
总结
在这篇文章中,我们实现了Model,同时还通过一些代码把view和controller联系起来了。同时,我们还在view和controller,以及用户touch事件之间建立了联系,这样controller类就可以来响应游戏里面的用户输入了。(译者:为什么费这么多劲,无非就是职责分离,这个非常重要!)。在接下来的文章里面,我们会谈到下面两个问题:
· 在Controller里面更新Model,
· 通知View关于Model的改变.
- Cocos2d-x里面如何实现MVC(四)
- Cocos2d-x里面如何实现MVC(四)
- Cocos2d-x里面如何实现MVC(四)
- Cocos2d-x里面如何实现MVC(六)
- Cocos2d-x里面如何实现MVC(五)
- Cocos2d-x里面如何实现MVC(三)
- Cocos2d-x里面如何实现MVC(二)
- Cocos2d-x里面如何实现MVC(一)
- Cocos2d-x里面如何实现MVC(一)
- Cocos2d-x里面如何实现MVC(二)
- Cocos2d-x里面如何实现MVC(三)
- Cocos2d-x里面如何实现MVC(五)
- Cocos2d-x里面如何实现MVC(六)
- Cocos2d-x里面如何实现MVC(完)
- cocos2d-x里面如何实现mvc
- Cocos2d-x里面如何实现MVC(一)
- Cocos2d-x里面如何实现MVC(二)
- Cocos2d-x里面如何实现MVC(三)
- MATLAB中矩阵与数组的区别,点运算符的运用
- Java字节码浅析(二)
- Cocos2d-x里面如何实现MVC(三)
- 如何在命令行下打开html文件和pdf文件
- NYOJ-220-推桌子
- Cocos2d-x里面如何实现MVC(四)
- java接口用法:向上转型和回调函数
- 操作系统面试题(二)
- Vector、ArrayList
- Cocos2d-x里面如何实现MVC(五)
- Cocos2d-x里面如何实现MVC(六)
- python与json
- java基础__代理、动态代理
- Cocos2d-x里面如何实现MVC(完)