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事件,然後更新model
  • model 更新它自身的狀態, 處理遊戲邏輯,然後告訴view它改變了哪些東西。
  • View則基於Model當前的狀態來更新自己的顯示

轉自:http://www.cnblogs.com/andyque/archive/2012/03/18/2390106.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章