GeekBand.iOS-猜城市游戏

2016/3/16 posted in  iOS学习笔记  

本游戏是一个用于练手的示例游戏,本文将从最开始的需求分析开始对游戏进行分析和实现

需求分析

简要需求以及程序原型设计如下图:
程序原型
程序需求的简单描述为:用户根据图片展示,猜测图片展现的是哪一个城市,并将答案输入文本框中,程序对输入内容进行判断,如果答对,增加得分加载下一张图片,如答错,记录尝试次数,超过程序要求,游戏结束。

游戏运行流程:
游戏运行流程图
补充需求说明:
1. 输入城市名称时,要求中文简体输入如北京、上海等。
2. 毎猜对一个城市,得分加10分。
3. 程序所需图片 采用[UIImage imageNamed:@""];方法读取;
4. 城市与图片对应实现采用程序硬编码实现。

系统设计

类结构图
具体说明如下:

  1. ViewController

    对使用Interface Builder创建的UI界面提供操作绑定,使代码可以对View控件进行控制。

  2. City (城市类)

    @interface City : NSObject
    @property int cityId;//城市ID,根据ID可以加载城市图片
    @property NSString* cityName;//城市名称,名称规范如:北京
    +(instancetype) initWithCityID:(int)cityId WithCityName:(NSString *)cityName;
    @end
    
  3. CityDB(工厂类)
    这是一个工厂类,使用类方法,封装了一些关于城市的操作函数,如返回某城市的图片,和硬编码加载所有城市返回。

    @interface CityDB : NSObject
    +(UIImage *) getCityImageByCity:(City *)city;
    +(NSArray<City *> *) loadAllCity;
    @end
    
  4. Level(关卡类)
    毎次随机出现的一个城市,抽象为一个关卡。

    @interface Level : NSObject
    @property City* city;
    @property int time;//当前尝试次数,初始化为0
    +(instancetype) initWithCity:(City *)city;
    @end
    
  5. Game(游戏控制类)

    @interface Game : NSObject
    @property BOOL gameOver;
    @property int currentScore;
    +(instancetype) game;//返回一个游戏对象
    -(BOOL) guessCityByName:(NSString *)cityName;//根据用户输入判断猜测是否正确
    -(UIImage *) imageForCurrentLevel;//获得当前关卡的城市的图片
    -(int) getTryTimes;//本关卡已经尝试的次数
    
    //内部处理所需
    //初始化类
    -(instancetype) init{
        self = [super init];
        if(self){
            _levels = [NSMutableArray arrayWithCapacity:20];
            _cities = [NSMutableArray arrayWithArray:[CityDB loadAllCity]];
            [self shuffleCities];//随机生成关卡
            _currentLevelIndex = 0;
            _currentScore = 0;
            _gameOver = false;
            _allowTime = 3;
        }
        return  self;
    }
    //根据CityDB加载的城市列表,随机关卡出现的顺序
    -(void) shuffleCities{
        Level* level;
        for(int i = 0; i<[[CityDB loadAllCity] count];i++){
            level = [Level initWithCity:[self getACityRandom]];
            [_levels addObject:level];
        }
    }
    //从未出现过的City中随机选取一个
    -(City *)getACityRandom{
        int i = arc4random() % _cities.count;
        City* city = [_cities objectAtIndex:i];
        [_cities removeObjectAtIndex:i];//把选取中的从待选取列表中移除
        return city;
    }
    //获得当前的关卡标号
    -(Level *)getCurrentLevel{
        return [_levels objectAtIndex:_currentLevelIndex];
    }
    //前往下一关
    -(void) nextLevel{
        _currentLevelIndex++;
        if(_currentLevelIndex >= _levels.count){
            self.gameOver = YES;
        }
    }
    //根据输入判断是否过关
    -(BOOL) guessCityByName:(NSString *)cityName{
        Level* currentLevel =[self getCurrentLevel];
        City* current = currentLevel.city;
        if([cityName isEqualToString:current.cityName]){
            self.currentScore += 10;
            [self nextLevel];
            return YES;
        }else{
          //增加已尝试次数
            currentLevel.time++;
            if (currentLevel.time >= _allowTime) {
                self.gameOver = YES;
            }
        }
        return NO;
    }
    //返回本关卡剩余可尝试次数
    -(int)getTryTimes{
        return _allowTime - [self getCurrentLevel].time;
    }
    @end
    

本文对游戏的实现,并不是最佳实现,读者可根据自己的理解分析对类进行设计与实现。

Demo演示

演示1
演示2