cocos2d里面如何实现MVC(五)

it2025-11-17  7

    本文基于前面两篇文章,如果您还没有看过,建议先阅读下面两篇文章:

cocos2d里面如何实现mvc(三),cocos2d里面如何实现mvc(四)

更新Model

    当用户从工具箱中选一个小工具,然后把它放置到game board上面去时,我们需要编码响应这些事件。在上一篇文章中,我们已经实现了GameBoardViewDelegate的touchedAtRow方法。我们还需要给这个协议再添加一个接口方法。如下所示:

@protocol GameBoardViewDelegate- (void)gameBoard:(GameBoard *)gameBoard touchedAtRow:(int)row column:(int)column;- (void)gameBoard:(GameBoard *)gameBoard toolboxItemTouchedAtIndex:(int)index;@end

    我们需要修改touch事件处理器,这样就可以判断我们到底是触摸了工具箱还是game board。

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint point = [self convertTouchToNodeSpace:touch];// touched on a game board if (CGRectContainsPoint(gameBoardRectangle, point)) {int row, column;// calculate row and column based on a touch coordinate// ...// call controller [self.delegate gameBoard:self.gameBoard touchedAtRow:row column:column]; }// touched on a toolbox else if (CGRectContainsPoint(toolboxRectangle, point)) {int index;// calculate toolbox item index based on a touch coordinate [self.delegate gameBoard:self.gameBoard toolboxItemTouchedAtIndex:index]; }}

    在controller类里面处理touch事件是非常简单的,我们只需要持有一个model的引用,然后基于touch事件来调用model的方法就行了。我们的接口看起来和下面差不多,只是省略掉了一些实现细节:

@interface GameBoard : NSObject {// ...}// ...- (void)putGamePiece:(GamePiece *)gamePiece row:(int)row column:(int)column;- (GamePiece *)getGamePieceFromToolboxItemAtIndex:(int)index;@end

    然后,我们在GameBoardController里面完全实现GameBoardViewDelegate的两个方法。

- (void)gameBoard:(GameBoard *)aGameBoard toolboxItemTouchedAtIndex:(int)index {// keep the toolbox selection state in the Model gameBoard.selectedToolboxItemIndex = index;}- (void)gameBoard:(GameBoard *)aGameBoard touchedAtRow:(int)row column:(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:row column:column]; }}

    到目前为止,我们实现了,用户可以点击工具箱中的小工具,然后把它们放置到game board中的一个小方块上面,同时model类在中间起了桥梁作用。

通知view关于model的改变

    为了在view里面反映出model的状态更改,我们可以在model有变化的时候给view发送通知消息,然后view就可以根据不同的消息来作出不同的响应了。和我们在实现view通过controller一样,这里我们也定义了一个GameBoardDelegate,用来通知view model的变化。

@protocol GameBoardDelegate;@interface GameBoard : NSObject// ...@property (nonatomic, assign)id<GameBoardDelegate> delegate;// ...@end@protocol GameBoardDelegate- (void)gameBoard:(GameBoard *)gameBoard didPutGamePiece:(GamePiece *)gamePiece row:(int)row column:(int)column;@end@implementation GameBoard- (void)putGamePiece:(GamePiece *)gamePiece row:(int)row column:(int)column {// ...// store game piece// notify that the game piece was put on a gameboard [delegate gameBoard:self didPutGamePiece:gamePiece row:row column:column];}@end

    在GameBoardView里面实现GameBoardDelegate的时候,当我们需要在game board上面放置一个小工具的时候,我们定义了一个CCSprite。

@interface GameBoardView : CCLayer// ...@end@implementation GameBoardView- (id)initWithGameBoard:(GameBoard *)aGameBoard delegate:(id)aDelegate {if ((self = [super init])) {// retain gameboard self.gameBoard = aGameBoard; self.gameBoard.delegate = self;// assign delegate self.delegate = aDelegate; }}- (void)gameBoard:(GameBoard *)gameBoard didPutGamePiece:(GamePiece *)gamePiece row:(int)row column:(int)column {// create CCSprite and put it on a game board at corresponding position CCSprite *gamePieceSprite = [CCSprite spriteWithFile:fileName];// ... [self addChild:gamePieceSprite];}@end

总结

    现在框架中所有的部分都联系起来了,model、view和controller三者组成了著名的MVC模式

View接收touch事件,然后把事件传递给controller,Controller 响应用户的touch事件,然后更新modelmodel 更新它自身的状态, 处理游戏逻辑,然后告诉view它改变了哪些东西。View则基于Model当前的状态来更新自己的显示 

 

后记:本文已同步更新到cocos2d mvc这个系列里面去了。

    如果你觉得本文章对你有所帮助,请您点一下旁边的“推荐”按钮,这样可以让更多的人看到,同时也会给我写作的动力,谢谢大家。

转载于:https://www.cnblogs.com/zilongshanren/archive/2012/03/18/2390106.html

相关资源:数据结构—成绩单生成器
最新回复(0)