zoukankan      html  css  js  c++  java
  • IOS之UIImageView--小实例项目--带音效的拳皇动画

     内容大纲:

    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

     
    可能遇到的错误
     
     
     设置音频速率在代码顺序上的注意点:
     
     
     
     
     
     
  • 相关阅读:
    tableau prep 转置-pivot
    tabeau 画Slopegraph斜面图
    java栈
    java快速排序
    java冒泡排序
    java实现双向链表
    五、使用依赖注入取代硬连接资源(静态工厂、单例),也可用于构造方法、bulider模式
    转 String的不变性 immutable
    三、使用私有构造方法(公开成员属性或者公开静态工厂方法)或者枚举类实现singleton
    有状态对象和无状态对象
  • 原文地址:https://www.cnblogs.com/goodboy-heyang/p/4965869.html
Copyright © 2011-2022 走看看