`

cocos2d里面如何实现MVC(二)

 
阅读更多

 

上一篇博文中,我提到了《如何在cocos2d里面实现mvc》,但是,都是一些纯理论的东西,我们需要看一些代码才能理解地更清楚。这篇博文是基于上一篇来写的,所以我建议你先阅读完上一篇再接着往下看。

模型类

    就像之前所讨论的,GameModel类存储了游戏世界里面的一些属性,比如当前的重力。但是,它同时也负责创建和连接游戏里面的对象,比如Player和Platforms。它们之间的关系如下图所示:(译者:这里采用了针对接口编程的方法,所有的游戏对象都继承至updateable接口,这样就可以在game loop里面更新自己了。同时GameModel类提供了一个工厂方法createGameObjects,用来创建游戏里面的对象。)



 你可能已经注意到了,所有的model类都实现了updateable protocol,并实现了update方法。这样它们就可以在game loop里面更新自己的状态了。比如,在Player类里面,我们需要根据当前x轴和y轴的速度来更新player的位置信息。在我的游戏里面,我把它委托给Physics组件,它是我实现的一个简单的物理引擎。但是,假如你的游戏很简单的话,你可以不用分开你的物理代码,然后可以直接在update方法里面来做碰撞检测等物理操作。

 

@implementation Player
- (void)update:(ccTime)dt
{
    [_physics updateModel:self dt:dt];
    // detect collisions with game objects, etc.
}

 

 GameModel实现的update方法,不仅仅用来更新自己的状态,同时,它还调用player的update方法和所有platform的update方法。这个update方法,之后会被game loop所调用。

 

@implementation GameModel
- (void)update:(ccTime)dt
{
    // modify game model properties here
    // update player
    [self.player update:dt];
    // update platforms
    for (Platform *platform in _platforms) {
        [platform update:dt];
    }
    // ...
}
 

 

视图和控制器类

    对于我的游戏里面的每一个场景(CCScene),都关联了一个Controller类,它负责处理用户交互、创建视图和管理场景的跳转。控制器会schedule一个游戏主循环,在这个loop里面,所有的model和view的update方法都会被调用。

 

@implementation GameplayController
- (id)init
{
    if((self=[super init])) {
        GameplayView *view = [[GameplayView alloc] initWithDelegate:self];
    // retain view in controller
    self.view = view;
    // release view
    [view release];
 
    // init model
    GameModel *model = [GameModel sharedModel];
    [model createGameObjects];
    [model.player run];
 
    [self scheduleUpdate];
    }
}
 
- (void)update:(ccTime) dt
{
    GameModel *model = [GameModel sharedModel];
 
    if (model.isGameOver) {
    [[CCDirector sharedDirector] replaceScene:[GameOverController node]];
    }
 
    // process model
    [model update:dt];
 
    // update view
    [self.view update:dt];
}

 

 View主要负责根据model的状态来渲染游戏画面。但是,同时,因为cococs2d的实现方式,我们还需要把touch事件传递给controller类。你应该注意到了,view不并直接依赖controller。view类调用controller的方法是通过GameViewDelegate协议来实现的。这也是为什么我们要在init方法里面传递一个delegate的原因。 

 

@implementation GameplayView
- (id)initWithDelegate:(id)theDelegate
{
    if ((self = [super init])) {
        self.delegate = theDelegate;
 
    // initialize layers
    _backgroundLayer = [GameplayBackgroundLayer node];
    [self.delegate addChild: _backgroundLayer];
 
    _platformLayer = [GameplayPlatformLayer node];
    [self.delegate addChild:_platformLayer];
 
    _playerLayer = [GameplayPlayerLayer node];
    _playerLayer.delegate = theDelegate;
    [self.delegate addChild: _playerLayer];
 
    _hudLayer = [GameplayHudLayer node];
    _hudLayer.delegate = theDelegate;
        [self.delegate addChild:_hudLayer];
    }
 
    return self;
}

 

 // 更新:我忘了告诉大家layer本身是怎么实现的了。其实很简单,就是创建一些sprite、action和animation等。 

 

@implementation GameplayPlayerLayer
- (id)init
{
    if ((self = [super init])) {
        self.isTouchEnabled = YES;
    self.isAccelerometerEnabled = YES;
        ResourceManager *resources = [ResourceManager sharedResourceManager];
 
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:PLAYER_SPRITE_SHEET_PLIST];
 
    CCSpriteBatchNode *spriteSheet = [resources playerSpriteSheet];
    [self addChild:spriteSheet];
        // ... 
       // initialize sprites
       // initialize animations
}

 

 层里面的精灵都会在layer的update方法里面被更新,如下所示:

 

- (void)update:(ccTime)dt 
{
    // update player sprite based on model
    GameModel *model = [GameModel sharedModel];
 
    _playerSprite.position = ccp((model.player.position.x - model.viewPort.rect.origin.x) * PPM_RATIO,  (model.player.position.y - model.viewPort.rect.origin.y) * PPM_RATIO);
}

  注意,在渲染player的位置的时候,我们使用了PPM_RATIO,用来把米转换成point。(为什么是point而不是pixel,因为cocos2d使用的是point而不是pixel,不明白的可以看看源代码和官方文档)

 

    touch事件被传递给了controller类,如下所示:

 

@implementation GameplayPlayerLayer
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.delegate playerBeginJump];
}

 

 然后下图就是view和controller交互的完整的UML图:


 

处理模型事件

    上一篇博文中,我留下了一个问题,就是怎么处理model和controller之间的交互。其它很简单,就是使用观察者模式,controller只要订阅model的事件,然后定义相应的处理方法即可。当model更新的时候,会触发事件,然后所有侦听了该事件的controller都能被通知到。下面给出实现:(译者:很多童靯不知道对象之间该怎么交互,其实使用NSNotification可以大大地解耦对象的交互,使代码更容易维护。)

 

@implementation Player
- (void)beginJump
{
    if ([_gameModel isOnGround:self]) {
        [[NSNotificationCenter defaultCenter] postNotificationName:EVENT_PLAYER_BEGIN_JUMP object:nil];
    ...
}

 controller订阅事件,当事件发生的时候会得到通知,同时相应的事件处理函数将会被调用。

 

@implementation GameplayController
- (id)init
{
    if ((self = [super init])) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPlayerBeginJumpNotification:) name:EVENT_PLAYER_BEGIN_JUMP object:nil];
        ...
    }
}
 
- (void)onPlayerBeginJumpNotification:(NSNotification *)notification
{
    [[SimpleAudioEngine sharedEngine] playEffect:PLAYER_JUMP_SOUND];
}
 

就这么多!

    乍一看,可能会觉得有点复杂。而且,要创建这么多类,却只是为了实现一个简单的功能,确实有点划不来。而且,你还记得吗?如果在系统里面添加太多的类,其实是一种反模式(anti-pattern),叫做Fear of Adding Classes。但是,从长远的角度来看,从可维护性的角度来看,加这么多类是值得的。后面的教程我将向大家展示出来。如果大家对于如何在cocos2d里面使用mvc有更好的看法,欢迎补充。

 

 

  • 大小: 9.9 KB
  • 大小: 15.5 KB
分享到:
评论

相关推荐

    cocos2D-lua 核心编程内置代码

    在“Cocos2d-x之Lua核心编程(第二版)_配套代码”中,我们可以找到一系列的示例和代码,这些代码涵盖了Cocos2d-lua的核心功能和编程技巧。 一、Cocos2d-lua简介 Cocos2d-lua是Cocos2d-x的一个扩展,它允许开发者使用...

    GameBoard-《cocos2d-x如何实现MVC》系列中的完整实例

    "GameBoard-《cocos2d-x如何实现MVC》系列中的完整实例"是一个关于如何在cocos2d-x中应用Model-View-Controller(MVC)设计模式的实际项目。MVC模式是一种软件架构模式,常用于构建可维护性和扩展性较高的应用程序,...

    Lua实现PureMVC

    这个是一个根据AS3(ActionScript 3) pureMVC而转换过来的lua pureMVC。所有的接口完全跟AS3版本一致...注意,这个PureMVC中的 class(ClassName, BaseName) 函数并不提供,因为此框架本意就是为了用于cocos2d-x-lua中。

    cocos2d-x C++实现切水果刀刃效果

    在本文中,我们将深入探讨如何使用C++编程语言在cocos2d-x游戏引擎中实现一个生动逼真的“切水果”刀刃效果。cocos2d-x是一个流行的开源跨平台2D游戏开发框架,它基于C++,并支持多种操作系统,如iOS、Android和...

    cocoscreator使用puremvc

    Cocos Creator是一款强大的2D和3D游戏开发引擎,它提供了直观的可视化编辑工具和灵活的组件系统,使得游戏开发变得更加高效。PureMVC则是一个经典的多层应用程序框架,最初设计用于ActionScript环境,但现在已经有了...

    cocosLua中MVC的应用

    在游戏开发领域,Cocos2d-x是一款广泛使用的开源跨平台2D游戏引擎,而Cocos2d-x Lua则是其支持的脚本语言之一,它提供了便捷的lua接口来实现游戏逻辑。MVC(Model-View-Controller)是一种常见的软件设计模式,常...

    在IPhone上用Cocos2d做的一个小游戏

    游戏逻辑的实现主要依赖于Cocos2d的事件处理机制和动作系统。例如,当用户触摸屏幕时,我们可以监听Touch事件,触发忍者发射飞镖的动作。这涉及到EventDispatcher的事件监听和处理,以及Action对象的创建和执行,如...

    cocos2d-js-mvc:基于cocos2d-js的mvc框架,现已不再维护,目前更新的是基于cocos creator的游戏框架ituuz-x

    【cocos2d-js-mvc】是一个基于Cocos2d-js的游戏开发框架,它采用了Model-View-Controller(MVC)的设计模式。MVC是一种软件设计模式,将应用程序分为三个核心部分:模型(Model)、视图(View)和控制器(Controller...

    基于Cocos2d-x框架,并使用MVC架构的棋类游戏

    基于Cocos2d-x框架,并使用MVC架构的一个棋类游戏。 Pure MVC架构,构建可维护的Cocos2d-x游戏。 ###使用的框架 Cocos2d-x2.2.3 ###apk下载地址 应用宝 360手机助手 ###相关博客 架构篇:...

    cocos2dx用c++实现MoonWarriors

    《cocos2dx用c++实现MoonWarriors》是一款基于Cocos2d-x游戏引擎,用C++语言编写的简单游戏。Cocos2d-x是一个跨平台的2D游戏开发框架,它允许开发者使用C++、Lua或者JavaScript来创建游戏,并能在iOS、Android、...

    lua实现cocos2d-x的mvvm框架

    MVVM源于MVC(Model-View-Controller)模式,期间还演化出MVP(Model-View-Presenter)模式。MVVM的出现促进了GUI前端开发和后端开发逻辑的分离,提高了前端开发效率。 MVVM的核心是数据驱动即ViewModel,ViewModel是...

    cocos2d-x飞机游戏 源码

    在代码实现上,cocos2d-x遵循MVC(模型-视图-控制器)设计模式,将数据、显示和逻辑分离,使得代码结构清晰,易于维护。游戏的主循环通常在Director类中,负责更新场景、渲染画面、处理输入等。 总结来说,cocos2d-...

    cocos2d-x 2012-03-31开发者大会演讲稿PDF(6)-刘万千 基于cocos2d-x的跨平台游戏制作20120331.pdf

    标题和描述均指向了一个特定的主题:基于cocos2d-x的跨平台游戏制作,这是由刘万千在2012年3月31日的开发者大会上所作的演讲。cocos2d-x是一款广泛使用的开源游戏开发框架,特别适用于创建跨平台的游戏应用,即可以...

    cocos2d-x C++ 版本 塔防 游戏

    在cocos2d-x中实现塔防游戏,开发者需要掌握以下关键知识点: 1. **游戏场景管理**:cocos2d-x中的Scene类是游戏的顶级容器,负责管理游戏的不同阶段。开发者需要创建多个场景来表示游戏的不同状态,如主菜单、游戏...

    知易Cocos2D-iPhone开发教程(1-8)全套文档

    通过这套教程,读者将能够逐步掌握Cocos2D-iPhone的使用方法,从创建简单的静态画面到实现复杂的交互式游戏,从而迈入iOS游戏开发的大门。无论是对编程感兴趣的新手,还是希望转行游戏开发的从业者,都能从中...

    IOS应用源码之【游戏】-BouncingBall1_cocos2d.rar

    【游戏】★★★★★-BouncingBall1_cocos2d 是一个基于Cocos2d引擎开发的iOS游戏源代码项目。Cocos2d是一个广泛使用的开源游戏开发框架,尤其适用于2D游戏。这个项目的源码提供了学习和理解iOS游戏开发的基础,特别...

    IOS应用源码之【游戏】ABC123_使用cocos2d开发的游戏.rar

    4. 用户交互:Cocos2d-iOS的触摸事件处理机制使得游戏能够响应用户的触摸操作,实现流畅的游戏控制。 5. 存档系统:可能实现了本地存档功能,保存玩家的进度和成就,以便下次继续游戏。 6. 分数和成就:通过Game ...

    IOS应用源码之cocos2d-iphone-0.7.3.zip

    《深入解析iOS应用源码:cocos2d-iphone-0.7.3》 cocos2d-iphone是一款强大的2D游戏开发框架,专为iOS平台设计,它基于开源的cocos2d-x项目,并针对Objective-C和Apple的UIKit进行了优化。在“cocos2d-iphone-0.7.3...

    iOS实例开发源码——jotaeme1212-Ejemplos-en-Cocos2D-320a463.zip

    9. **设计模式**:源代码可能运用了MVC(模型-视图-控制器)、观察者模式等设计模式,有助于开发者学习如何在iOS和Cocos2D项目中组织代码,提高代码的可读性和可维护性。 总之,这个压缩包提供的源代码示例是一个...

Global site tag (gtag.js) - Google Analytics