------

[ AD ] Port Monitor ( Try to use a Best WebSite Monitoring Tool )

------

cocos2d meets MVC – Implementing simple board game part 2


By BARTEK | Published: 

Introducing model

In the previous part we introduced the View and the Controller. To comply with MVC paradigm we need to add a model which will represent the current state of a game board. Our implementation now should contain the following classes:

1.     GameBoardView - the View,

2.     GameBoardController - the Controller.

3.     GameBoard the Model.

 


 

 

 

GameBoard implementation

Our requirement (described in the first part) is that:

A game board is defined by a number of rows and columns, which may vary for different application levels.

We implement it in the following way:

@interface GameBoard : NSObject {
    NSInteger numberOfRows;
    NSInteger numberOfColumns;
}
 
- (id)initWithRows:(NSInteger)aNumberOfRows columns:(NSInteger)aNumberOfColumns;
 
@property (nonatomic) NSInteger numberOfRows;
@property (nonatomic) NSInteger numberOfColumns;
 
@end

Please notice that the model extends NSObject the model should contain just the state of a game board (and the methods to update this state) we shouldnt put any view related concerns here.

 

 

GameBoardView implementation

We need to modify the View and pass it the Model, we do this in initWithGameBoard method.

@interface GameBoardView : CCNode {
    GameBoard *gameBoard;
}
 
@property (nonatomic, retain) GameBoard *gameBoard;
 
- (id)initWithGameBoard:(GameBoard *)aGameBoard;  // with Model
 
@end

Our implementation of a GameBoardView can look like this (rendering game board spaces omitted to simplify the code):

- (id)initWithGameBoard:(GameBoard *)aGameBoard {
    if ((self = [super init])) {
        // retain gameboard
        self.gameBoard = aGameBoard;
 
        // render gameboard background
        CCSprite *gameboardSprite = [CCSprite spriteWithFile:@"gameboard.png"];
        gameboardSprite.anchorPoint = CGPointMake(0, 0);
 
        [self addChild:gameboardSprite];
 
        // render spaces
        for (int i = 0; i < gameBoard.numberOfRows; i++) {
            for (int j = 0; j < gameBoard.numberOfColumns; j++) {
                // position and render game board spaces
            }
        }
    }
 
    return self;
}

 

 

GameBoardController

Finally the implementation of an init method in the Controller should be updated the View needs to have the GameBoard model injected in its init method so we construct the game board in Controller (just for now) and pass it to the View (later on we will create a game board based on a level definition).

- (id)init {
    if ((self = [super init])) {
 
        // initialize model
        gameBoard = [[GameBoard alloc] initWithRows:7 columns:9];
 
        // initialize view
        view = [[GameBoardView alloc] initWithGameBoard:gameBoard];
 
        [self addChild:view];
    }
 
    return self;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

Handling touches

 

GameBoardView updates

In order to handle touches we need to slightly modify the View. We make it extend CCLayer instead of CCNode to have a possibility to handle touch events inside of it:

@interface GameBoardView : CCLayer {
...
}

The View itself should not be responsible for handling the actions that are results of user interaction with the game board so we will pass it to the Controller using protocol.

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

We also modify the init method of a GameBoardView so we can pass a delegate object that will be responsible for handling the touches:

- (id)initWithGameBoard:(GameBoard *)aGameBoard delegate:(id)aDelegate;

And the implementation is:

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint point = [self convertTouchToNodeSpace:touch];
 
    // calculate row and column touched by the user and call a delegate method
    // ...
    [self.delegate gameBoard:self.gameBoard touchedAtRow:row column:column];
}

 

 

GameBoardController updates

GameBoardController will be responsible for handling user touches, so we need to implement a GameBoardViewDelegate in a GameBoardController:

@interface GameBoardController : CCNode
- (void)gameBoard:(GameBoard *)gameBoard touchedAtRow:(int)row column:(int)column {
    // do the game logic here and update view accordingly
}

The last step is to modify the View initialization in the following way (in init method):

// initialize view
view = [[GameBoardView alloc] initWithGameBoard:gameBoard delegate:self];

 

 

source - 실제 구현한 부분

 

//

//  GameBoard.h

//  Mvc

//

//  Created by James Yu on 12. 7. 6..

//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.

//

 

#import <Foundation/Foundation.h>

 

@interface GameBoard : NSObject {

   

    NSInteger numberOfRows;

    NSInteger numberOfColumns;

}

 

-(id)initWithRows:(NSInteger)aNumberOfRows columns:(NSInteger)aNumberOfColumns;

 

@property (nonatomic) NSInteger numberOfRows;

@property (nonatomic) NSInteger numberOfColumns;

   

 

@end

 

 

//

//  GameBoard.m

//  Mvc

//

//  Created by James Yu on 12. 7. 6..

//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.

//

 

#import "GameBoard.h"

 

@implementation GameBoard

 

@synthesize numberOfRows;

@synthesize numberOfColumns;

 

 

-(id)initWithRows:(NSInteger)aNumberOfRows columns:(NSInteger)aNumberOfColumns

{

    self=[super init];

    if(self) {

    }

    return self;

}

 

@end

 

//

//  GameBoardView.h

//  Mvc

//

//  Created by James Yu on 12. 7. 6..

//  Copyright 2012 __MyCompanyName__. All rights reserved.

//

 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

#import "GameBoard.h"

 

 

@protocol GameBoardViewDelegate

-(void)gameBoard:(GameBoard*)gameBoard touchedAtRow:(int)row column:(int)column;

@end

 

// need to modify the View and pass it the Model,

// we do this in initWithGameBoard method.

 

@interface GameBoardView : CCLayer {

   

    GameBoard *gameBoard;

    id<GameBoardViewDelegate> delegate;

}

 

-(id)initWithGameBoard:(GameBoard *)aGameBoard delegate:(id)aDelegate;

 

@property (nonatomic, retain) GameBoard *gameBoard;

@property (nonatomic, retain) id<GameBoardViewDelegate> delegate;

 

@end

 

//

//  GameBoardView.m

//  Mvc

//

//  Created by James Yu on 12. 7. 6..

//  Copyright 2012 __MyCompanyName__. All rights reserved.

//

 

#import "GameBoardView.h"

 

 

@implementation GameBoardView

 

@synthesize gameBoard;

@synthesize delegate;

 

-(id)initWithGameBoard:(GameBoard *)aGameBoard delegate:(id)aDelegate {

   

    self =[super init];

   

    if ( self ) {

 

        self.isTouchEnabled=YES;

       

        // retain gameboard

        self.gameBoard = aGameBoard;

        self.delegate = aDelegate;

       

        // render gameboard background

        CCSprite *gameBoardSprite=

        [CCSprite spriteWithFile:@"icon.png"];

        gameBoardSprite.anchorPoint=CGPointMake(0,0);

        [self addChild:gameBoardSprite];

       

        // render spaces

        for( int i =0; i < gameBoard.numberOfRows; i++) {

            for( int j=0 ; i < gameBoard.numberOfColumns; j++ ) {

                // position and render game board spaces

               

            }

        }

       

    }

    return self;

}

 

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

   

    NSLog(@"touch");

    //UITouch *touch=[touches anyObject];

    //CGPoint point=[self convertToNodeSpace:touch];

   

    // calculate row and columns touched by the user and call a delegate method

   

    //[self.delegate gameBoard:self.gameBoard touchedAtRow:row column:column];

    [self.delegate gameBoard:self.gameBoard touchedAtRow:1 column:1];

   

}

 

@end

 


 

 

//

//  GameBoardController.h

//  Mvc

//

//  Created by James Yu on 12. 7. 6..

//  Copyright 2012 __MyCompanyName__. All rights reserved.

//

 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

#import "GameBoardView.h"

 

#import "GameBoard.h"

 

@interface GameBoardController : CCNode<GameBoardViewDelegate> {

   

    GameBoardView   *view;

    GameBoard       *gameBoard;

}

 

-(void)gameBoard:(GameBoard*)gameBoard touchedAtRow:(int)row column:(int)column;

 

@end

 

//

//  GameBoardController.m

//  Mvc

//

//  Created by James Yu on 12. 7. 6..

//  Copyright 2012 __MyCompanyName__. All rights reserved.

//

 

#import "GameBoardController.h"

 

// is responsible for initializing the view.

// also holds a reference to GameBoardView for future needs.

 

@implementation GameBoardController

 

-(id)init {

   

    self =[super init];

   

    if ( self ) {

        

        //view = [GameBoardView node];

        //[self addChild:view];

           

        // initialize model

        gameBoard=[[GameBoard alloc] initWithRows:7 columns:9];

       

        // initialize view

        view = [[GameBoardView alloc] initWithGameBoard:gameBoard delegate:self];

       

        [self addChild:view];

       

        Protocol *p=@protocol(GameBoardViewDelegate);

        if ( [self conformsToProtocol:p] == YES ) {

            NSLog(@"app supports delegate protocol");

        }

       

    }

    return self;

}

 

-(void)gameBoard:(GameBoard*)gameBoard touchedAtRow:(int)row column:(int)column {

   

    NSLog(@"touch row[%d] column[%d]", row, column);

   

}

@end

 

'0.일반개발' 카테고리의 다른 글

Spring MVC  (0) 2015.04.29
Spring MVC 개념  (0) 2015.04.28
cocos2d 기초 강좌 - 기본 함수  (0) 2012.06.01
Xcode 4.0 시뮬레이터에서 리소스가 반영되지 않을떄.  (0) 2012.05.30
Texture Packer  (0) 2012.05.25

+ Recent posts