iOS开发-------MVC架构思想-植物大战僵尸

        十月长假也就这么过去了,利用假期想磨练一下自己的MVC架构的思想,于是找了一个相对比较麻烦的Demo来锻炼下,在之前很喜欢植物大战僵尸这个游戏,也算为游戏致敬了,但是这个植物大战僵尸肯定不是之前玩过的那个游戏,只是致敬,类似打地鼠,但是代码感觉非常多,所以也算楼主的目前博客里面最有料的了,不得不说,想逻辑的时候直接的虐心啊,先看一下效果吧





然后看一下如果家中的僵尸达到60个,那么就会跳出一个失败的动画,并伴随着僵尸的奸笑声,这里就不给动态图了




要用MVC架构,逻辑最重要,在写代码的时候明显的感觉的到,没有逻辑步步为艰,并且还会出现写不下去的情况,首先看看以我个人见解建构的MVC目录




Model类:

Zombie(僵尸类): 考虑到以后会更加僵尸种类,所以先创建了一个BaseZombie(僵尸的基类),拥有各种僵尸都有的属性,因为这个小游戏中有四种类型的僵尸,所以上面的图可以看到,有4种类型的僵尸。这里是先理理思路,代码后面会有的。

Manager(管理器):单例

ZomibieManager(僵尸管理器):顾名思义,里面存的是僵尸的对象

MusicManager(背景音乐管理器):能够控制音乐的播放


View类:

BackgroundView(背景视图):继承于UIView,是负责显示背景,也就是绿草坪,标签上的僵尸数以及得分,会根据得分以及僵尸数,分别向VC汇报是否结束游戏,什么时候提高僵尸移动加速

ZombieView(单个僵尸视图):继承于UIImageView,是负责每个僵尸的显示,接收点击事件回调以及动画的形成

Zombies_View(所有僵尸视图):继承于UIView,负责僵尸被点击后的操作、将是进入家中的回调以及负责加快僵尸移动速度

GameOverView(游戏结束视图):继承于UIView,负责展示游戏结束的视图,并能够将重新开始按钮点击实现回调给VC


Controller类

全局的一个boss,负责指挥所有的子控件,并实现最终的回调


大体的逻辑就如上了,只挂图和讲理论不适合我,还是上代码,会更直接简明一些,那就按照MVC的顺序,注:本demon中所有的汇报回调都是Block回调


全局用的宏

       因为在程序中必然要减少数字的使用,面的这种情况,最简单的方法就是定义一个宏,楼主将所有的宏打包成一个头文件,叫做DEFINE.h,下面就是宏文件
#ifndef ____DEFINE_h
#define ____DEFINE_h

#define GAMEOVERCOUNT 60        //家里的僵尸达到60,游戏结束
#define ADD_SPEED_STAND 20       //加速标准,达到20即加速

#define ZOMBIE_MOVE_SPEED 0.5   //僵尸的移动速度
#define TIMER_SPEED       0.05  //计时器回调的间隔

#define ZOMBIE_COUNT 15         //每轮僵尸的个数
#define ZOMBIE_TYPE_COUNT 4     //僵尸的种类

#define ZOMBIE_ADD_SPEED 0.1    //每次加速时增量

#endif



Model(模型)类


Zombie(僵尸类)

         这里面最简单的也就是僵尸(模型)类了,里面只需记住相对应的僵尸类型的 图片数量(zombiesFrameCount)  僵尸图片的宽度(zombiesFrameWidth) 以及僵尸图片的高度(zombiesFrameHeight),全部定义在BaseZombie类中,如下
//
//  BaseZombie.h
//  打僵尸
//
//  Created by YueWen on 15/10/5.
//  Copyright (c) 2015年 YueWen. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface BaseZombie : NSObject

@property(nonatomic,assign)NSInteger zombiesFrameCount;//僵尸图片的张数
@property(nonatomic,assign)NSInteger zombiesFrameWidth;//僵尸图片的宽度
@property(nonatomic,assign)NSInteger zombiesFrameHeight;//僵尸图片的高度

@end

       不需要实现任何的方法,其他四种类型的model类中,也只需重写init方法即可,这里只给出zombieType1(僵尸类型1)的init方法,其他的一样,只需记住图片的数量,以及高和宽即可。
- (instancetype)init
{
    self = [super init];
    if (self) {
        
        //为框架赋值
        self.zombiesFrameHeight = 72;
        self.zombiesFrameWidth = 83;
        
        //图片的数量
        self.zombiesFrameCount = 31;
        
    }
    return self;
}

ZombiesManager(僵尸对象管理器)

        zombiesManager(僵尸对象管理器)是一个存储僵尸对象的类,它不管视图的东西,只负责管理僵尸的类对象,它能够告知VC他的僵尸对象是否已经加载完毕,如果加载完毕,将数组返回交给Zombies_View来继续包装成视图;楼主的习惯,只要是管理者,一般情况下,都是会定义成单例的,这次必然也不例外

首先会声明一个单例方法
/**
 *  获取单例对象
 *
 *  @return 单例对象
 */
+(instancetype)shareZombieManager;

因为要存储僵尸对象,但是又不希望外界能够轻易的改动,那么设置一个开放的数组属性,只能读,即readOnly
/**
 *  存放僵尸对象的数组
 */
@property(nonatomic,strong,readonly)NSArray * zombies;


接着需要一个加载僵尸的方法,来加载 宏 规定的僵尸数
/**
 *  加载僵尸
 */
-(void)loadZombies;

这个Manager需要一个回调,是告知VC,他的僵尸数组已经加载完毕,并且返回加载完毕的数组,并用该数组完成下一步的操作
typedef void(^ZombieManagerLoadFinishBlock)(NSArray * zombies);

有回调比有回调属性,有回调属性必然会有设置回调属性的方法
/**
 *  为回调的代码块赋值
 *
 *  @param zombieMangerLoadFinishBlock 回调的代码块
 */
-(void)setZombieManagerLoadFinishHandleBlock:(ZombieManagerLoadFinishBlock)zombieMangerLoadFinishBlock;

声明文件完毕,接下来就是实现文件了,延展中的代码块属性不赘余,但是延展中需要一个存放对象的可变数组
@property(nonatomic,strong)NSMutableArray * zombies_m;

首先实现init方法以及单例方法
-(instancetype)init
{
    if (self = [super init])
    {
        //初始化数组
        self.zombies_m = [NSMutableArray array];
    }
    return self;
}

+(instancetype)shareZombieManager
{
    static ZombieManager * zombieManager = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        zombieManager = [[ZombieManager alloc]init];
    });
    
    return zombieManager;
}

加载数组的属性,这里唯一一个小心的地方就是每次加载前需要清空数组,不然会因为单例属性而出现对象数量的累加
/**
 *  加载僵尸数组
 */
-(void)loadZombies
{
    //开始之前清除数组
    [self.zombies_m removeAllObjects];
    
    //开始循环加载僵尸
    for (NSInteger i = 0; i < ZOMBIE_COUNT; i++)
    {
        [self addZombie];
    }
}

添加僵尸,貌似只是简单的一句话,但是添加僵尸是随机添加的,不能规定那种僵尸是几个,所以有一个随机返回僵尸对象的方法
/**
 *  随机返回僵尸对象
 *
 *  @return 增加的僵尸
 */
-(BaseZombie *)arcdToModeZombie
{
    NSInteger temp = arc4random() % ZOMBIE_TYPE_COUNT + 1;//随机数 1~4,并根据数组返回僵尸类型
    
    switch (temp) {
        case 1:
            return [[ZombieType1 alloc]init];
            break;
        case 2:
            return [[ZombieType2 alloc]init];
            break;
        case 3:
            return [[ZombieType3 alloc]init];
            break;
        case 4:
            return [[ZombieType4 alloc]init];
            break;
        default:
            break;
    }
    return nil;
}

那么添加僵尸的方法就很简单了,只需给数组添加一个对象即可
//增加一个僵尸
-(void)addZombie
{
    [self.zombies_m addObject:[self arcdToModeZombie]];
}


这里说一下设置代
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值