网站首页 > 开源技术 正文
本文基于前面两篇文章,如果您还没有看过,建议先阅读下面两篇文章:
更新Model
当用户从工具箱中选一个小工具,然后把它放置到game board上面去时,我们需要编码响应这些事件。在上一篇文章中,我们已经实现了GameBoardViewDelegate的touchedAtRow方法。我们还需要给这个协议再添加一个接口方法。如下所示:
class GameBoardViewDelegate
{
public:
virtual void touchAtGrid(GameBoard *gameBoard, int row, int column) = 0;
virtual void touchWithToolBoxItemAtIndex(GameBoard *gameBoard, int index) = 0;
};
我们需要修改touch事件处理器,这样就可以判断我们到底是触摸了工具箱还是game board。
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);
// 下面假设游戏区与工具区8:2来划分宽度
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCRect *gameBoardRectangle = new CCRect(0, 0, size.width*0.8, size.height);
CCRect *toolBoxRectangle = new CCRect(size.width*0.8, 0, size.width*0.2, size.height);
if(CCRect::CCRectContainsPoint(*gameBoardRectangle, point)){
// calculate row and column touched by the user and call a delegate method
int row = 0;
int column = 0;
// ...
this->gameBoardViewDelegate->touchAtGrid(gameBoard, row, column);
} else if (CCRect::CCRectContainsPoint(*toolBoxRectangle, point)){
int index = 0;
// calculate toolbox item index based on a touch coordinate
this->gameBoardViewDelegate->touchWithToolBoxItemAtIndex(gameBoard, index);
}
}
在controller类里面处理touch事件是非常简单的,我们只需要持有一个model的引用,然后基于touch事件来调用model的方法就行了。我们的接口看起来和下面差不多,只是省略掉了一些实现细节:
class GameBoard : public CCObject
{
public:
// ...
GamePiece* getGamePieceFromToolBoxItemAtIndex(int index);
public:
// ...
int selectedToolBoxItemIndex;
};
然后,我们在GameBoardController里面完全实现GameBoardViewDelegate的两个方法。
void GameBoardController::touchAtGrid(GameBoard *gameBoard, int row, int column)
{
// if the toolbox item is selected move item from toolbox to game board
if(gameBoard->selectedToolBoxItemIndex != -1){
GamePiece *gamePiece = gameBoard->getGamePieceFromToolBoxItemAtIndex(gameBoard->selectedToolBoxItemIndex);
gameBoard->putGamePiece(gamePiece, row, column);
}
}
void GameBoardController::touchWithToolBoxItemAtIndex(GameBoard *gameBoard, int index) {
// keep the toolbox selection state in the Model
gameBoard->selectedToolboxItemIndex = index;
}
到目前为止,我们实现了,用户可以点击工具箱中的小工具,然后把它们放置到game board中的一个小方块上面,同时model类在中间起了桥梁作用。
通知view关于model的改变
为了在view里面反映出model的状态更改,我们可以在model有变化的时候给view发送通知消息,然后view就可以根据不同的消息来作出不同的响应了。和我们在实现view通过controller一样,这里我们也定义了一个GameBoardDelegate,用来通知view model的变化。
class GameBoardDelegate
{
public:
virtual void didPutGamePiece(GamePiece *gamePiece, int row, int column) = 0;
};
class GameBoard : public CCObject
{
// ...
public:
void setGameBoardDelegate(GameBoardDelegate *aGameBoardDelegate);
private:
GameBoardDelegate *gameBoardDelegate;
};
void GameBoard::putGamePiece(GamePiece *gamePiece, int row, int column)
{
// ...
// store game piece
// notify that the game piece was put on a gameboard
this->gameBoardDelegate->didPutGamePiece(gamePiece, row, column);
}
void GameBoard::setGameBoardDelegate(GameBoardDelegate *aGameBoardDelegate)
{
this->gameBoardDelegate = aGameBoardDelegate;
}
在GameBoardView里面实现GameBoardDelegate的时候,当我们需要在game board上面放置一个小工具的时候,我们定义了一个CCSprite。
class GameBoardView :
public CCLayer, public GameBoardDelegate
{
// ...
};
void GameBoardView::initWithGameBoard(GameBoard *aGameBoard, GameBoardViewDelegate *aDelegate)
{
// ...
this->gameBoard = aGameBoard;
this->gameBoard->retain();
this->gameBoard->setGameBoardDelegate(this);
this->gameBoardViewDelegate = aDelegate;
// ...
}
void GameBoardView::didPutGamePiece(GamePiece *gamePiece, int row, int column)
{
// create CCSprite and put it on a game board at corresponding position
CCSprite *gamePieceSprite = CCSprite::spriteWithFile("CloseNormal.png");
// ...
this->addChild(gamePieceSprite, 1);
}
总结
现在框架中所有的部分都联系起来了,model、view和controller三者组成了著名的MVC模式
· View接收touch事件,然后把事件传递给controller,
· Controller 响应用户的touch事件,然后更新model
· model 更新它自身的状态, 处理游戏逻辑,然后告诉view它改变了哪些东西。
· View则基于Model当前的状态来更新自己的显示
猜你喜欢
- 2024-09-10 高手在哪里?Cocos2d-x的Scheduler问题求解
- 2024-09-10 CocosCreator学习 碰撞系统(cocoscreator spine)
- 2024-09-10 Cocos2d-x项目实践一FlappyBird-屏幕适配
- 2024-09-10 愤怒的小鸟团队筹资4000万美元开发区块链游戏
- 2024-09-10 基于Cocos2d跨平台单机麻将-源码(cocos creator 麻将)
- 2024-09-10 XcodeGhost波及游戏引擎?cocos 2d-x发声明
- 2024-09-10 Cocos2d-x项目实践一FlappyBird-游戏逻辑
- 2024-09-10 深度干货|Cocos2d-x v3.11在HTML5方向的优化
- 2024-09-10 Win10/Win8.1/WP8.1游戏可用Cocos2d-X创建
- 2024-09-10 Cocos2d-x3.5下“回调特性”的一种简单的实现方法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)