首页 > 代码库 > 应用程序开发之模仿史上最牛游戏(三)
应用程序开发之模仿史上最牛游戏(三)
声明:转载请注明http://www.cnblogs.com/letougaozao/p/3720679.html
- 关卡解锁
- 关卡状态的设计
一、解锁动画(点一下解锁)
解锁前后
监听touch end方法,使用涂层layer动画
-加入QuartzCore.framework框架
-动画包括哪些内容呢?(注意播放声音的代码)
1??整个关卡摇摆两下(旋转动画)、并且变大(缩放动画)
2??搁层消失(直接移除)
1.封装一个动画组的方法
- (CAAnimationGroup *)animationCroup { //1.摇摆动画 CAKeyframeAnimation *shake = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"]; CGFloat angle = M_PI_4/4; shake.values = @[@(-angle), @(angle), @(-angle)]; shake.repeatCount = 3; //2.伸缩动画 CAKeyframeAnimation *scale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; scale.values = @[@1.2, @1]; //3.添加动画组 CAAnimationGroup *group = [CAAnimationGroup animation]; group.animations = @[shake, scale]; return group; }
2.执行前面的动画且设置代理(动画执行完之后执行后面的动画)
//0.点击了,覆盖层就消失,且执行动画过程中,不允许用户交互 [self setUserInteractionEnabled:NO]; [_stageCover removeFromSuperview]; //1.播放动画 CAAnimationGroup *group = [self animationCroup]; group.delegate = self; [self.layer addAnimation:group forKey:nil]; //2.播放声音 [[SoundManager sharedSoundManager] playSound:kSoundDrop];
2??锁掉下去(位移动画)
3??出现new且摇摆两下(可见之前new是隐藏的,改为不隐藏),显示白框(更改图片)
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { //1.锁掉下来 CGFloat destY = [UIScreen mainScreen].bounds.size.height - self.frame.origin.y; CGFloat duration = destY/1000; [UIView animateWithDuration:duration animations:^{ CGRect frame = _stageLock.frame; frame.origin.y = destY; _stageLock.frame = frame; } completion:^(BOOL finished) { [_stageLock removeFromSuperview]; [_stageNew setHidden:NO]; _stageRim.image = [UIImage imageNamed:@"select_stage_new.png"]; CAAnimationGroup *group = [self animationCroup]; [self.stageNew.layer addAnimation:group forKey:nil]; [self setUserInteractionEnabled:YES]; }]; }
二、关卡状态的设计
1??关卡状态(对状态的分析,才能设计后面有声明属性)
-从未解锁(显示锁)
-即将解锁(一进来就解锁)
执行解锁动画
-已经解锁,从未玩过
-已经解锁,且玩过(如果为S显示后面的图片)
2??每一关用一个模型来保存状态(StageRecordModel)
-分数(成绩)score
-等级(A~F,S)rank
-是否解锁,unlocked;
-关卡编号(NSString)no
//分数 @property (nonatomic, assign) double score; //编号 @property (nonatomic, assign) int no; //等级(A~F,S) @property (nonatomic, copy) NSString *rank; //状态 @property (nonatomic, assign, getter = isUnlock) BOOL unlock;
3??归档
-遵循NSCoding协议<NSCoding>
-重写两个方法
#import "StageRecordModel.h" #define kRank @"rank" #define kNo @"no" #define kUnlock @"unlock" #define kScore @"score" @implementation StageRecordModel - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { self.rank = [aDecoder decodeObjectForKey:kRank]; self.no = [aDecoder decodeIntForKey:kNo]; self.score = [aDecoder decodeDoubleForKey:kScore]; self.unlock = [aDecoder decodeBoolForKey:kUnlock]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.rank forKey:kRank]; [aCoder encodeInt:self.no forKey:kNo]; [aCoder encodeDouble:self.score forKey:kScore]; [aCoder encodeBool:self.isUnlock forKey:kUnlock]; } @end
4??专门写一个工具类,来保存数据、读取数据(存模型数据,专门写一个工具类)
这里有一个小细节:我们可以把路径直接写成一个宏(非常好用)
#define kPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"records.data"]
-存档方法 saveStageRecord
//存档 - (void)saveStageRecord:(StageRecordModel *)stageRecordModel { if (stageRecordModel.no < 0) return; [allRecords setObject:stageRecordModel forKey:@(stageRecordModel.no)]; [NSKeyedArchiver archiveRootObject:allRecords toFile:kPath]; }
-读档方法 stageRecordWithNo
1.在类初始化的时候,加载所有的数据到字典(重写init方法)
- (id)init { if (self = [super init]) { allRecords = [NSKeyedUnarchiver unarchiveObjectWithFile:kPath]; if (!allRecords) { allRecords = [NSMutableDictionary dictionary]; StageRecordModel *stageRecordModel = [[StageRecordModel alloc] init]; stageRecordModel.no = 1; [allRecords setObject:stageRecordModel forKey:@(stageRecordModel.no)]; } } return self; }
2.读档方法
//读档 - (StageRecordModel *)stageRecordWithNo:(int)no { return allRecords[@(no)]; }
-将工具类设置成单例模式
将单例代码抽成宏
1.声明文件中
singleton_interface(StageRecordTool)
2.实现文件中
singeton_implementation(StageRecordTool)
5??加载状态
-让StageModel拥有一个状态的属性
我们在StageInfo当中,添加一个StageRecordModel属性
//让关卡信息拥有一个StageRecordModel属性 @property (nonatomic, strong) StageRecordModel *stageRecordModel;
-在添加每一个Stage的时候,同时加载状态
//2.1加载关卡的状态 StageRecordModel *stageRecordModel =[[StageRecordTool sharedStageRecordTool] stageRecordWithNo:i + 1]; //2.2加载关卡的信息 StageInfo *stageInfo = [StageInfo stageInfoWith:stageDic]; stageInfo.stageRecordModel = stageRecordModel; stageInfo.stageNo = i + 1;
-重写setStageModel方法时,第三步-更新关卡的状态
//3.根据关卡的状态,获得关卡显示的内容 [self updateStageState];
我将下面出现情况所写的代码直接在最后贴出来,我觉得我写的还是比较容易理解的,每一种情况还是需要自己好好分析一下。
1.关卡记录为nil,就显示未解锁状态
直接设置不能和用户交互
2.即将解锁,有关卡记录,但是unlock属性为NO
第一次进入游戏的,把第一关加入,并且执行动画,,并且把解锁的unlock设置成YES
3.解锁,unlock属性为YES,但是rink为nil
溢出遮盖、锁
边框显示白色
显示new
4.已解锁,unlock为YES,rank不为nil
溢出遮盖、锁
显示等级(rank)和阴影(shadow)
移除new
设置等级显示的图片
-判断是否是s(序列帧动画)
1.加载图片(当view是通过xib创建的时候,会调用awakeFromNib方法)
2.播放
#pragma mark 根据关卡状态、获得关卡要显示的内容 - (void)updateStageState { if (!_stageInfo.stageRecordModel) { [self setUserInteractionEnabled:NO]; } else { if (!_stageInfo.stageRecordModel.unlock) { [self updateStageWithWillUnlock]; } else { [self updateStageWithUnlock]; } } } #pragma mark 即将解锁时,执行的代码 - (void)updateStageWithWillUnlock { //0.点击了,覆盖层就消失,且执行动画过程中,不允许用户交互 [self setUserInteractionEnabled:NO]; [_stageCover removeFromSuperview]; //1.播放动画 CAAnimationGroup *group = [self animationCroup]; group.delegate = self; [self.layer addAnimation:group forKey:nil]; //2.播放声音 [[SoundManager sharedSoundManager] playSound:kSoundDrop]; //3.设置unlock属性为YES _stageInfo.stageRecordModel.unlock = YES; [[StageRecordTool sharedStageRecordTool] saveStageRecord:_stageInfo.stageRecordModel]; } #pragma mark 已经解锁,执行的代码 - (void)updateStageWithUnlock { //1.遮盖和锁去掉 [_stageCover removeFromSuperview]; [_stageLock removeFromSuperview]; if (_stageInfo.stageRecordModel.rank == nil) { //2.显示new [_stageNew setHidden:NO]; //3.将边框换成黄色 _stageRim.image = [UIImage imageNamed:@"select_stage_new.png"]; } else { //2.显出阴影、等级 [_stageShadow setHidden:NO]; [_stageRank setHidden:NO]; //3.把new移除 [_stageNew removeFromSuperview]; //4.根据等级显示图片 _stageRank.image = [UIImage imageNamed:[NSString stringWithFormat:@"select_stage_%@.png", _stageInfo.stageRecordModel.rank]]; if ([@"s" isEqualToString:_stageInfo.stageRecordModel.rank]) { [_stageRim startAnimating]; } else { [_stageRim setImage:[UIImage imageNamed:@"select_stage_normal.png"]]; } } } #pragma mark - 解锁的动画 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { //1.锁掉下来 CGFloat destY = [UIScreen mainScreen].bounds.size.height - self.frame.origin.y; CGFloat duration = destY/1000; [UIView animateWithDuration:duration animations:^{ CGRect frame = _stageLock.frame; frame.origin.y = destY; _stageLock.frame = frame; } completion:^(BOOL finished) { [_stageLock removeFromSuperview]; [_stageNew setHidden:NO]; _stageRim.image = [UIImage imageNamed:@"select_stage_new.png"]; CAAnimationGroup *group = [self animationCroup]; [self.stageNew.layer addAnimation:group forKey:nil]; [self setUserInteractionEnabled:YES]; }]; } - (CAAnimationGroup *)animationCroup { //1.摇摆动画 CAKeyframeAnimation *shake = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"]; CGFloat angle = M_PI_4/4; shake.values = @[@(-angle), @(angle), @(-angle)]; shake.repeatCount = 3; //2.伸缩动画 CAKeyframeAnimation *scale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; scale.values = @[@1.2, @1]; //3.添加动画组 CAAnimationGroup *group = [CAAnimationGroup animation]; group.animations = @[shake, scale]; return group; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。