iPhone Quartz2D渲染扩展圈 [英] iPhone Quartz2D render expanding circle

查看:116
本文介绍了iPhone Quartz2D渲染扩展圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇使用Quarts2D实现以下功能的'正确'方法:



我想要一个视图,并且能够添加任意坐标处的圆圈。一旦我添加该圆圈,它应该以预定的速率扩展;我想重复这个过程,并有一个数字,如果这些扩大圈。



想想导弹命令:





通常,如果我使用SDL或其他图形库在C ++中编写此代码,我会:

让一个类代表一个增长的循环
有一个向量/数组来保存指向我创建的所有'增长圆'的指针。

所有的圆直径都会增加每个tick,在我的renderloop中,我会迭代该列表并绘制适当的圈子到我的缓冲区。



然而,这似乎不符合我以前iPhone开发中通常使用视图的方式。 / p>

所以我猜这是开放式的,但是对于这样的事情有没有正确的方法?

它是以游戏循环风格(如上所述),还是应该为 UIView 子类化'circle'对象,并覆盖 drawRect ?我想我必须通过创建一个视图并将其添加到我的主视图来添加每个圆圈。



初步调查还引入了对 CAShapeLayer 类,虽然我猜这可能与实现UIView子类化技术相同。

解决方案

以下是一种实现方法。将以下代码添加到您的UIViewController子类中,您将获得一个增长并随后消失的圆圈:

   - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self addGrowingCircleAtPoint:[[touches anyObject] locationInView:self.view]];

$ b - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if(flag&& [[anim valueForKey:@name ] isEqual:@grow]){
//当成长动画完成时,我们淡入图层
CALayer * lyr = [anim valueForKey:@layer];
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@opacity];
animation.fromValue = [lyr valueForKey:@opacity];
animation.toValue = [NSNumber numberWithFloat:0.f];
animation.duration = .5f;
animation.delegate = self;
lyr.opacity = 0.f;
[动画setValue:@fadeforKey:@name];
[animation setValue:lyr forKey:@layer];
[lyr addAnimation:animation forKey:@opacity];
} else if(flag& [[anim valueForKey:@name] isEqual:@fade]){
//当淡入淡出动画完成时,我们删除图层
CALayer * lyr = [anim valueForKey:@layer];
[lyr removeFromSuperlayer];
[lyr发行];



$ b - (void)addGrowingCircleAtPoint:(CGPoint)point {
//创建一个圆弧路径
CGMutablePathRef circlePath = CGPathCreateMutable();
CGPathAddArc(circlePath,NULL,0.f,0.f,20.f,0.f,(float)2.f * M_PI,true);

//创建形状图层
CAShapeLayer * lyr = [[CAShapeLayer alloc] init];
lyr.path = circlePath;

//不泄漏,请
CGPathRelease(circlePath);
lyr.delegate = self;

//设置形状图层的属性并将其添加到我们视图的图层
lyr.fillColor = [[UIColor redColor] CGColor];
lyr.position = point;
lyr.anchorPoint = CGPointMake(.5f,.5f);
[self.view.layer addSublayer:lyr];

//设置不断增长的动画
CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@transform];
animation.fromValue = [lyr valueForKey:@transform];
//这实际上会将圆圈变成椭圆形
CATransform3D t = CATransform3DMakeScale(6.f,4.f,1.f);
animation.toValue = [NSValue valueWithCATransform3D:t];
animation.duration = 2.f;
animation.delegate = self;
lyr.transform = t;
[动画setValue:@growforKey:@name];
[animation setValue:lyr forKey:@layer];
[lyr addAnimation:animation forKey:@transform];
}


I'm curious as to the 'proper' method for achieving the following functionality using Quarts2D:

I want to have a view, and to be able to add a circle at any coordinate. As soon as I add the circle it should expand at a predefined rate; I'd also like to repeat this process and have a number if these expanding circles.

Think Missile Command:

Generally, if I was writing this in C++ using SDL or some other graphics library I would:

Have a class to represent an 'growing circle' Have a vector/array to hold pointers to all the 'growing circles' I create.

All circles diameters would be increased each tick, and in my renderloop I would iterate the list and draw appropriate circles to my buffer.

This, however, doesn't seem to fit well with how I've generally used views in previous iPhone development.

So I guess it's kind of open-ended, but is there a 'correct' way for something like this?

Would it be in a game loop style (as described above), or should I be subclassing UIView for a 'circle' object, and override drawRect? I guess I would then have to add each circle by creating a view and adding it to my main view?

Initial investigation also brought me across references to the CAShapeLayer class, though I'm guessing this might be much the same as implementing the UIView subclassing technique.

解决方案

Here's one way to do it. Add the following code to your UIViewController subclass and you'll get a circle that grows and then fades away wherever you touch:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self addGrowingCircleAtPoint:[[touches anyObject] locationInView:self.view]];
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    if (flag && [[anim valueForKey:@"name"] isEqual:@"grow"]) {
        // when the grow animation is complete, we fade the layer
        CALayer* lyr = [anim valueForKey:@"layer"];
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue = [lyr valueForKey:@"opacity"];
        animation.toValue = [NSNumber numberWithFloat:0.f];
        animation.duration = .5f;
        animation.delegate = self;
        lyr.opacity = 0.f;  
        [animation setValue:@"fade" forKey:@"name"];
        [animation setValue:lyr forKey:@"layer"];
        [lyr addAnimation:animation forKey:@"opacity"];
    } else if (flag && [[anim valueForKey:@"name"] isEqual:@"fade"]) {
        // when the fade animation is complete, we remove the layer
        CALayer* lyr = [anim valueForKey:@"layer"];
        [lyr removeFromSuperlayer];
        [lyr release];
    }

}

- (void)addGrowingCircleAtPoint:(CGPoint)point {
    // create a circle path
    CGMutablePathRef circlePath = CGPathCreateMutable();
    CGPathAddArc(circlePath, NULL, 0.f, 0.f, 20.f, 0.f, (float)2.f*M_PI, true);

    // create a shape layer
    CAShapeLayer* lyr = [[CAShapeLayer alloc] init];
    lyr.path = circlePath;

    // don't leak, please
    CGPathRelease(circlePath);
    lyr.delegate = self;

    // set up the attributes of the shape layer and add it to our view's layer
    lyr.fillColor = [[UIColor redColor] CGColor];
    lyr.position = point;
    lyr.anchorPoint = CGPointMake(.5f, .5f);
    [self.view.layer addSublayer:lyr];

    // set up the growing animation
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.fromValue = [lyr valueForKey:@"transform"];
    // this will actually grow the circle into an oval
    CATransform3D t = CATransform3DMakeScale(6.f, 4.f, 1.f);
    animation.toValue = [NSValue valueWithCATransform3D:t];
    animation.duration = 2.f;
    animation.delegate = self;
    lyr.transform = t;  
    [animation setValue:@"grow" forKey:@"name"];
    [animation setValue:lyr forKey:@"layer"];
    [lyr addAnimation:animation forKey:@"transform"];
}

这篇关于iPhone Quartz2D渲染扩展圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆