内容大纲:

1、初步工作
2、开始敲代码
3、注意
4、可能遇到的错误
5、设置音频速率在代码顺序上的注意点

带音效的拳皇动画实例项目

初步工作

1、新建一Objective-C工程之后,将需要的拳皇动画实例的图片以及音效资源都拷贝进工程。

2、勾选,只勾选会产生项目的虚拟文件目录即可。

3、在storyboard上添加组件,这里由于时间缘故就添加四个按钮和一个ImageView。并设置好ImageView的显示Model

4、为组件连好线,

开始敲代码

1、第一步,敲出stand序列动画的实现

 1 #import "ViewController.h"
2
3 @interface ViewController ()
4
5 @property (weak, nonatomic) IBOutlet UIImageView *imageView;
6
7 //1-4 由于UIimageView
8 @property (nonatomic,strong)NSArray<UIImage*> *imageArray;
9 @end
10
11 @implementation ViewController
12
13 - (void)viewDidLoad {
14 //1 需要初始化好imageView指向的对象,先从站立动作开始
15
16 //1-4 由于UIimageView需要用数组添加序列动画,所以用可变数组
17 NSMutableArray *array = [NSMutableArray array];
18
19
20 //1-1 添加图片 因为站立的图片有10张
21 for (int i = 0; i<10; i++) {
22 //1-2 要获取资源图,就需要先获取资源图片的名称
23 NSString* pictureName = [NSString stringWithFormat:@"stand_%d",i+1];
24 //1-3 可以通过[UIImage imageNamed:pictureName]转为UIImage对象,但是不建议
25 // UIImage *image = [UIImage imageNamed:pictureName];
26
27 //1-5 建议通过initWithContentsOfFile
28 NSString* pathStr = [[NSBundle mainBundle] pathForResource:pictureName ofType:@"png"];
29 UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathStr];
30 //1-6 添加进可变数组
31 [array addObject:image];
32 }
33 //1-7 最后通过具有全局变量作用的外部引用指向 可变数组的引用,供外界使用
34 self.imageArray = array;
35 }
36
37 #pragma mark - 设置拳皇动画
38
39 //站立
40 - (IBAction)stand {
41 //2 以上图片资源加载完毕之后,就可以使用动画
42 self.imageView.animationImages = self.imageArray;
43 self.imageView.animationRepeatCount = 0;
44 [self.imageView startAnimating];
45 }
46
47 //小招
48 - (IBAction)smallClick {
49 }
50
51
52 //大招
53 - (IBAction)bigClick {
54 }
55
56 #pragma mark - 游戏结束 Game Over
57 //停止 需要进行内存管理
58 - (IBAction)stopGame {
59 }
60
61
62 @end

运行结果可以实现stand的站立备战状态:

因为拳皇动画的三种状态(站立,小招,大招)加载图片各自需要一系列序列动画,也就是都需要执行以下共同的代码:

 1     //1-4 由于UIimageView需要用数组添加序列动画,所以用可变数组
2 NSMutableArray *array = [NSMutableArray array];
3
4
5 //1-1 添加图片 因为站立的图片有10张
6 for (int i = 0; i<10; i++) {
7 //1-2 要获取资源图,就需要先获取资源图片的名称
8 NSString* pictureName = [NSString stringWithFormat:@"stand_%d",i+1];
9 //1-3 可以通过[UIImage imageNamed:pictureName]转为UIImage对象,但是不建议
10 // UIImage *image = [UIImage imageNamed:pictureName];
11
12 //1-5 建议通过initWithContentsOfFile
13 NSString* pathStr = [[NSBundle mainBundle] pathForResource:pictureName ofType:@"png"];
14 UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathStr];
15 //1-6 添加进可变数组
16 [array addObject:image];
17 }
18 //1-7 最后通过具有全局变量作用的外部引用指向 可变数组的引用,供外界使用
19 self.imageArray = array;

那么我们可以将其抽取出来,模块化成一个方法:

 1 #pragma mark - 加载图片资源的方法
2
3 -(NSArray)loadResouceWithName:(NSString)name withCount:(int)count{
4 NSMutableArray *array = [NSMutableArray array];
5
6 for (int i = 0; i<count; i++) {
7 NSString* pictureName = [NSString stringWithFormat:@"%@_%d",name,i+1];
8
9 NSString* pathStr = [[NSBundle mainBundle]
10 pathForResource:pictureName ofType:@"png"];
11 UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathStr];
12
13 [array addObject:image];
14 }
15
16 return array;
17
18 } ```

完整的代码:

完整的代码:点击左边的+号即可查看源码

特别有必要提出的有关内存管理的代码:

 1 #pragma mark - 游戏结束 Game Over
2 //停止 需要进行内存管理
3 - (IBAction)stopGame {
4 self.standImages = nil;
5 self.smallClickImages = nil;
6 self.bigClickImages = nil;
7
8 //为了能够是加载的图片也要释放掉
9 self.imageView.animationImages = nil;
10 /*
11 *为什么这个也要释放呢,因为self.imageView.animationImages是数组
12 *集合类型add/insert在ARC模式下都会将 强指针 指向 添加的对象,所以这里需要nil进行内存处理。
13 */
14 }

到这里,可以实现序列动画效果了。

但是我们还需要在出完招式之后,就接着能够回到站立备战状态,总和考虑这里使用延时的方法最合适。这里就直接用了重构,将重复的代码抽取出成Click方法。

 <- 重构之后的代码,点击左边的+号就可以看到源码

2、然后开始添加音效。

  • 这里就先简单概括一下思路:

    • 导入AVFoundation->创建AVPlay对象(包括指定好相关路径下的音频文件) ->并需要一个强引用指向它->最后记得销毁这个强引用(nil)。
    • 在使用AVPlayer创建对象的时候,初始化最好用initWithPlayerItem:AVPlayerItem* ,这样在切换音频对象比较方便。

然后根据这简短的思路快速实现代码:

 1 #import "ViewController.h"
2 #import <AVFoundation/AVFoundation.h>
3
4 @interface ViewController ()
5
6 @property (weak, nonatomic) IBOutlet UIImageView *imageView;
7
8 @property (nonatomic,strong)NSArray<UIImage*> *standImages;
9 @property (nonatomic,strong)NSArray<UIImage*> *smallClickImages;
10 @property (nonatomic,strong)NSArray<UIImage*> *bigClickImages;
11
12 //需要指向AVPlay的强引用
13 @property (nonatomic,strong)AVPlayer *player;
14 @end
15
16 @implementation ViewController
17
18 - (void)viewDidLoad {
19
20 self.standImages = [self loadResouceWithName:@"stand" withCount:10];
21 self.smallClickImages = [self loadResouceWithName:@"xiaozhao1" withCount:21];
22 self.bigClickImages = [self loadResouceWithName:@"dazhao" withCount:87];
23
24 }
25
26 #pragma mark - 加载图片资源的方法
27 -(NSArray*)loadResouceWithName:(NSString*)name withCount:(int)count{
28 NSMutableArray *array = [NSMutableArray array];
29
30
31 for (int i = 0; i<count; i++) {
32 NSString* pictureName = [NSString stringWithFormat:@"%@_%d",name,i+1];
33
34 NSString* pathStr = [[NSBundle mainBundle] pathForResource:pictureName ofType:@"png"];
35 UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathStr];
36
37 [array addObject:image];
38 }
39
40 return array;
41 }
42
43 #pragma mark - 设置拳皇动画
44
45 //站立
46 - (IBAction)stand {
47 self.imageView.animationImages = self.standImages;
48 self.imageView.animationRepeatCount = 0;
49 [self.imageView startAnimating];
50 }
51
52 //小招
53 - (IBAction)smallClick {
54 [self gameMusic:@"xiaozhao1"];
55 [self click:self.smallClickImages];
56
57 }
58
59
60 //大招
61 - (IBAction)bigClick {
62 [self gameMusic:@"dazhao"];
63 [self click:self.bigClickImages];
64 }
65 //产生音乐
66 -(void)gameMusic:(NSString*)musicName{
67 NSURL* url = [[NSBundle mainBundle] URLForResource:musicName withExtension:@"mp3"];
68 AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:url];
69 AVPlayer *smallPlayer = [[AVPlayer alloc] initWithPlayerItem:item];
70
71 self.player = smallPlayer;
72 [self.player play];
73 }
74 //出招
75 -(void)click:(NSArray*)imagesArray{
76 self.imageView.animationImages = imagesArray;
77 self.imageView.animationRepeatCount = 1;
78 [self.imageView startAnimating];
79
80 NSTimeInterval delayTime = 1/30.0 * imagesArray.count + 0.08;
81 [self performSelector:@selector(stand) withObject:nil afterDelay:delayTime];
82
83 }
84 #pragma mark - 游戏结束 Game Over
85 //停止 需要进行内存管理
86 - (IBAction)stopGame {
87 self.standImages = nil;
88 self.smallClickImages = nil;
89 self.bigClickImages = nil;
90 self.imageView.animationImages = nil;
91 }
92
93 @end

项目结果效果:

注意:

通过imageName:来加载的图片,指向它的强引用销毁时,图片不会随着一起销毁
UIImage *image = [UIImage imageNamed:imageName];
通过imageWithContentOfFile:加载的图片,指向它的强引用销毁时,图片会随着一起销毁
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath]

项目资源下载地址(两份压缩文件:项目资源文件,项目代码源文件):

百度云下载链接: http://pan.baidu.com/s/1c04sctM 密码: ryer

 
可能遇到的错误
 
 
 设置音频速率在代码顺序上的注意点:
 
 
 
 
 
 

IOS之UIImageView--小实例项目--带音效的拳皇动画的更多相关文章

  1. IOS开发之小实例--创建一个简单的用于视频录制和回放的应用程序

    前言:还是看了一下国外的入门IOS文章:<Create a Simple App for Video Recording and Playback>,主要涉及视频录制和回放的功能的基本实现 ...

  2. IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序

    前言:本篇博文是本人阅读国外的IOS Programming Tutorial的一篇入门文章的学习过程总结,难度不大,因为是入门.主要是入门UIImagePickerController这个控制器,那 ...

  3. IOS之UI--小实例项目--添加商品和商品名(纯代码终结版)

    前言:这个小实例项目是完完全全以MJ视频传授的优化方案一步一个思路从零开始敲出代码的,而且每一步都有思路,都有逻辑所以然.敲代码讲究思路,我个人不建议记忆太多东西,反正我记性很差的. 小贴士:文章末尾 ...

  4. IOS之UI--小实例项目--综合使用

    前言: 本博文是基于前一个小实例项目:IOS之UI--小实例项目--添加商品和商品名 进行继续综合学习积累的. 内容大纲 01-综合使用01-plist的使用 02-综合使用02-模型取代字典的好处分 ...

  5. OC小实例关于init方法不小心的错误

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  6. OC小实例关于init 方法不小心的错误

    OC小实例关于init 方法不小心的错误  正视遇到的每一个错误 在一个遥控器类操控小车玩具的小实例项目中,我采用组合的方式,将遥控器拥有小汽车对象(has a)关系,而不是继承(is a)关系. 想 ...

  7. iOS 模仿一个小项目,总结一下里边的模块

      ManoBoo:  参考链接:http://www.jianshu.com/p/fd4c46c31508  这个小的项目是参考ManoBoo的简书的,链接在上方,自己在仿做的过程中,也离不开Man ...

  8. IOS之UI--小实例项目--添加商品和商品名

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  9. Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作

    Entity Framework 的小实例:在项目中添加一个实体类,并做插入操作 1>. 创建一个控制台程序2>. 添加一个 ADO.NET实体数据模型,选择对应的数据库与表(Studen ...

随机推荐

  1. 基于Redis的BloomFilter算法去重

    BloomFilter算法及其适用场景 BloomFilter是利用类似位图或者位集合数据结构来存储数据,利用位数组来简洁的表示一个集合,并且能够快速的判断一个元素是不是已经存在于这个集合.因为基于H ...

  2. 使用“原生”HTML DOM获取input的输入值并显示

    理论基础 HTML <input> value属性.value规定<input>元素的值.value对于不同input类型,用法也不同. 1.对于"button&qu ...

  3. Android读写SD卡

    SD卡的读写是我们在开发Android 应用程序过程中最常见的操作.下面介绍SD卡的读写操作方式: 1. 获取SD卡的根目录 String sdCardRoot = Environment.getEx ...

  4. js 自带的 sort() 方法

    1. 方法概述 Array的sort()方法默认把所有元素先转换为String再根据Unicode排序, sort()会改变原数组,并返回改变(排序)后的数组 . 2. 例子 2.1 如果没有提供自定 ...

  5. 【洛谷 P3385】模板-负环(图论--spfa)

    题目:有一个图有N个顶点,M条边.边用三个整数a b w表示,意思为a->b有一条权值为w的边(若w<0则为单向,否则双向).共T组数据.对于每组数据,存在负环则输出一行"YE5 ...

  6. jQuery中each()、find()、filter()等节点操作方法

    1.each(callback) 官方解释: 返回值:jQuery 概述 以每一个匹配的元素作为上下文来执行一个函数. 意味着,每次执行传递进来的函数时,函数中的this关键字都指向一个不同的DOM元 ...

  7. 最短路径—大话Dijkstra算法和Floyd算法

    Dijkstra算法 算法描述 1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , ...

  8. lambda 个人学习理解

    lambda是简化代码量的写用更简单的方法来写匿名方法 lambda左边是参数,右边是代码块(方法执行语句). 整体运算结果是根据左边参数,执行右边语句,返回右边执行的结果: 匿名方法是简化方法 1. ...

  9. docker入门指南(转载)

    原文: http://bg.biedalian.com/2014/11/20/docker-start.html 关于 docker 今天云平台的同事提到, 现在的运维就是恶性循环, 因为大家都在申请 ...

  10. js中的浅拷贝和深拷贝

    说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的"深度",常见的对象都是"浅"的,也就是对象里的属性就是单个的属性,而"深&q ...