我很好奇使用Quarts2D实现以下功能的'正确'方法:
我希望有一个视图,并且能够在任何坐标处添加一个圆圈。一旦我添加圆圈,它应该以预定义的速率扩展;我也想重复这个过程,并且如果这些扩大的圈子有一个数字。
Think Missile Command:
通常,如果我使用SDL或其他图形库在C ++中编写,我会:
有一堂课代表'成长圈' 有一个向量/数组来指向我创建的所有'成长圈'。
每个刻度都会增加所有圆直径,并且在我的渲染循环中,我将迭代列表并将适当的圆绘制到我的缓冲区。
然而,这似乎与我之前在iPhone开发中使用视图的方式不太吻合。
所以我猜这是开放式的,但对于这样的事情是否有'正确'的方法?
是游戏循环风格(如上所述),还是应该为{circle'对象创建UIView
子类,并覆盖drawRect
?我想我必须通过创建一个视图并将其添加到我的主视图来添加每个圆圈?
初步调查也让我跨越CAShapeLayer类的引用,虽然我猜这可能与实现UIView子类化技术大致相同。
答案 0 :(得分:2)
这是一种方法。将以下代码添加到您的UIViewController子类中,您将获得一个增长的圆圈,然后在您触摸的地方逐渐消失:
- (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"];
}