iOS:quartz2D绘图 (动画)

时间:2023-03-09 17:17:03
iOS:quartz2D绘图 (动画)

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

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

iOS:quartz2D绘图 (动画) iOS:quartz2D绘图 (动画) iOS:quartz2D绘图 (动画)

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

iOS:quartz2D绘图 (动画)  iOS:quartz2D绘图 (动画)  iOS:quartz2D绘图 (动画) iOS:quartz2D绘图 (动画)  iOS:quartz2D绘图 (动画)

下面开始代码的实现了:

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 = ; //初始化一个英雄状态
_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 = ;
switch (_state)
{
case Hero_Stand:
maxIndex = ;
break; case Hero_Run:
maxIndex = ;
break; case Hero_Attack:
maxIndex = ;
break; case Hero_AttackJ:
maxIndex = ;
break; case Hero_AttackT:
maxIndex = ;
break;
} //如果没有到最后一张图片,就累加
if (_index < maxIndex)
{
_index++;
}
//换成首张图片
else
{
_index = ;
} //让视图重绘
[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 = ;
}

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

-(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绘图 (动画)

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

iOS:quartz2D绘图 (动画) iOS:quartz2D绘图 (动画)

iOS:quartz2D绘图 (动画)

奔跑时绘制的英雄动画:

iOS:quartz2D绘图 (动画)

移动英雄的位置到中间:

iOS:quartz2D绘图 (动画)