iOS:quartz2D绘图 (动画)

摘要:
Quartz2D可用于绘制所需的图形。他们画的是静态图形。如何绘制动态图形?Quartz2D可以画图。想想看。如果我们设置一个计时器,在短时间内绘制多张图片,这不是动画吗?这个想法已经付诸实践了。站立时绘制的英雄动画:攻击时绘制的人物动画:以三种攻击模式运行时绘制的角色动画:将英雄的位置移到中间:

quartz2D可以用来绘制自己需要的图形,它们绘制出来的是一个静态的图形,那么如何绘制一个动态的图形呢?动态的图形就是动画,所谓动画,其实就是很多张图片在短时间内不停的切换所产生的一种视觉效果。quartz2D可以绘制图形,想一想,那么如果我们设置一个定时器,在很短的时间内不停的绘制多张图片,这不就是动画效果吗?好了,思路已有,接下来就是实践了。

代码之前的一些准备:首先需要一份连续的图片素材,接着自定义一个视图类,并将控制器中的视图与它关联在一起。

iOS:quartz2D绘图 (动画)第1张 iOS:quartz2D绘图 (动画)第2张 iOS:quartz2D绘图 (动画)第3张

我准备的素材是一个游戏的英雄人物,它有站着、攻击(招式有三种)、奔跑的几种状态,导入的素材文件为hero

iOS:quartz2D绘图 (动画)第4张  iOS:quartz2D绘图 (动画)第5张  iOS:quartz2D绘图 (动画)第6张 iOS:quartz2D绘图 (动画)第7张  iOS:quartz2D绘图 (动画)第8张

下面开始代码的实现了:

1、在ViewController.m文件中初始化自定义的视图,即设置视图大小,并添加一个英雄图片

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //添加英雄视图    
    HeroView *heroView = [[HeroView alloc]initWithFrame:self.view.bounds];
    
    [self.view addSubview:heroView];
}

2、现在余下所有的代码都是自定义类ViewDemo.m文件中进行的,即

//枚举所有的英雄状态

typedef enum{
    Hero_Stand,
    Hero_Run,
    Hero_Attack,
    Hero_AttackJ,
    Hero_AttackT
}HeroState;

//声明属性 

@interface HeroView()
@property (strong,nonatomic)NSTimer *timer;
@property (assign,nonatomic)NSInteger index;
@property (assign,nonatomic)HeroState state;
@property (assign,nonatomic)CGPoint point;
@end

//初始化视图

-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        //初始化一个开始索引
        _index = 1;
        
        //初始化一个英雄状态
        _state = Hero_Stand;
        
        //定时器
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(updateIndex) userInfo:nil repeats:YES];
        
        self.backgroundColor = [UIColor whiteColor];
    }
    return self;
}

//不使用时停止定时器

-(void)dealloc
{
    //停止定时器
    if (_timer)
    {
        [_timer invalidate];
    }
}

//定时器刷新方法

-(void)updateIndex
{
    //更新图片额索引
    NSInteger maxIndex = 1;
    switch (_state)
    {
        case Hero_Stand:
            maxIndex = 3;
            break;
            
        case Hero_Run:
            maxIndex = 11;
            break;
            
        case Hero_Attack:
            maxIndex = 5;
            break;
            
        case Hero_AttackJ:
            maxIndex = 8;
            break;
            
        case Hero_AttackT:
            maxIndex = 3;
            break;
    }
    
    //如果没有到最后一张图片,就累加
    if (_index < maxIndex)
    {
        _index++;
    }
    //换成首张图片
    else
    {
        _index = 1;
    }
    
    //让视图重绘
    [self setNeedsDisplay];
}

//重写drawRect方法,根据英雄状态和索引绘制相应的图片

- (void)drawRect:(CGRect)rect
{
    //画不同状态下的英雄
    UIImage *image;
    switch (_state)
    {
        case Hero_Stand:
            image = [UIImage imageNamed:[NSString stringWithFormat:@"Hero%ld.png",_index]];
            break;
            
        case Hero_Run:
            image = [UIImage imageNamed:[NSString stringWithFormat:@"HeroRun%ld.png",_index]];
            break;
            
        case Hero_Attack:
            image = [UIImage imageNamed:[NSString stringWithFormat:@"HeroAttack%ld.png",_index]];
            break;
            
        case Hero_AttackJ:
            image = [UIImage imageNamed:[NSString stringWithFormat:@"HeroAttackJ%ld.png",_index]];
            break;
            
        case Hero_AttackT:
            image = [UIImage imageNamed:[NSString stringWithFormat:@"HeroAttackT%ld.png",_index]];
            break;
    }
    
    //一张张绘制不同状态的所有图片
    [image drawAtPoint:self.point];
}

//触摸开始时的事件,每次点击就会切换英雄的状态

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //切换状态
    if (_state < Hero_AttackT)
    {
        _state ++;
    }
    else
    {
        _state = Hero_Stand;
    }
    _index = 1;
}

//触摸移动事件,可以手动移动英雄的位置

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    
    //计算移动的位置
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self];
    CGPoint preLocation = [touch previousLocationInView:self];
    CGFloat xOffset = location.x - preLocation.x;
    CGFloat yOffset = location.y - preLocation.y;
    _point = CGPointMake(_point.x+xOffset, _point.y+yOffset);
    
    //让视图重绘
    [self setNeedsDisplay];
}

好了所有的代码都已写完,下面就是演示了,由于无法插入视频,就给出截图了。

站着时绘制的英雄动画:    

iOS:quartz2D绘图 (动画)第9张

攻击时绘制的英雄动画:三种攻击方式

iOS:quartz2D绘图 (动画)第10张 iOS:quartz2D绘图 (动画)第11张

iOS:quartz2D绘图 (动画)第12张

奔跑时绘制的英雄动画:

iOS:quartz2D绘图 (动画)第13张

移动英雄的位置到中间:

iOS:quartz2D绘图 (动画)第14张

免责声明:文章转载自《iOS:quartz2D绘图 (动画)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇《逆向工程核心原理》笔记第一章到第十一章MySQL集群常见高可用方案(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

UE4_攻击伤害2_AI受击动画

新建一个简单的Ai, 给他添加上模型并调整至正确,修改碰撞设置。 visibility默认是忽略的,可以调整到阻挡,这样就能阻挡我们发出的射线。 这是一种阻挡射线的方法,但并不打算用这种。所以把visibility调回去。 在项目设置的collision里找到射线,新建一个射线命名为attack,并且默认相应改成 ignore 找到SimpleAI...

10个顶级的CSS和Javascript动画框架推荐

在网站中嵌入动画已成为近年来的一个设计趋势,许多公司都已开始转向并拥抱HTML5、CSS3和JavaScript这个技术“三人组”。尽管这些技术还不能制作一些非常复杂的动画(像flash所实现的),但是如果拥有好的想法及创造性思维,使用它们制作的即便是一些简单的动画也足以打动我们。 而且,随着CSS3技术的发展,CSS3动画日益流行。目前,WebKit浏览...

JQuery几种动画效果的方法

下面介绍了几种动画效果的方法,具体如下: 1、show()显示效果 语法:show(speed,callback)  Number/String,Function speend为动画执行时间,单位为毫秒。也可以为slow","normal","fast" callback可选,为当动画完成时执行的函数。 show(speed,[easing],callba...

Android Activity 切换动画(非原创)

在Android开发过程中,经常会碰到Activity之间的切换效果的问题,下面介绍一下如何实现左右滑动的切换效果,首先了解一下Activity切换的实现,从Android2.0开始在Activity增加了一个方法: public voidoverridePendingTransition(int enterAnim, int exitAnim) 其中:...

YYModel底层解析- Runtime

这段时间一直在忙新的需求,没有时间来整理代码,发表自己技术博客,今天我们来看一下YYModel的底层解析以及如何使用,希望对大家有所帮助! 一 概述 概括 YYModel是一个轻量级的JSON模型转换库,它的思路非常清晰代码风格也很好,所以还是建议大家看一下底层实现的逻辑,也可以从源码加深对Runtime的理解。 简介 下面是YYModel第三方库的一些代...

cocos creator 3D | 蚂蚁庄园运动会星星球

上一篇文章写了一个简易版的蚂蚁庄园登山赛,有小伙伴留言说想要看星星球的,那么就写起来吧! 效果预览 配置环境 cocos creator 3d 1.0.0 小球点击 3d里节点无法用 cc.Node.EventType.TOUCH_START 监听。最终在论坛上找到一个 raycast 解决方法。参考代码如下。 start() { system...