so my current version looks like this: Animation Movie
i'm fairly new to core-animations, so what i try to achieve is that there are multiple points like the current one, moving from the left box in various angles, heights and speeds out of it, just like a tennis ball machine.
the first problem is, that my "ball" doesn't look like it gets grabbed from gravity and also the speed at first is not fast enough.
also, how to do this animation multiple times with variating distances between the beginning.
if something is unclear, PLEASE leave a comment.
my current code:
- (void)loadView {
[super loadView];
self.view.backgroundColor = [UIColor lightGrayColor];
CGPoint startPoint = CGPointMake(20, 300);
CGPoint endPoint = CGPointMake(300, 500);
UIBezierPath *trackPath = [UIBezierPath bezierPath];
[trackPath moveToPoint:startPoint];
[trackPath addQuadCurveToPoint:endPoint controlPoint:CGPointMake(endPoint.x, startPoint.y)];
CALayer *point = [CALayer layer];
point.bounds = CGRectMake(0, 0, 20.0, 20.0);
point.position = startPoint;
point.contents = (id)([UIImage imageNamed:@"point.png"].CGImage);
[self.view.layer addSublayer:point];
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.path = trackPath.CGPath;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
anim.repeatCount = HUGE_VALF;
anim.duration = 2.0;
[point addAnimation:anim forKey:@"movepoint"];
CALayer *caseLayer = [CALayer layer];
caseLayer.bounds = CGRectMake(0, 0, 140.0, 150.0);
caseLayer.position = startPoint;
caseLayer.contents = (id)([UIImage imageNamed:@"case.png"].CGImage);
[self.view.layer addSublayer:caseLayer];
}
Easiest way to model gravity is with those parabolic equations that you learn in basic physics. In short, the function below takes an initial position, a speed, and an angle (IN RADIANS, where 0 is to the right). a CALayer appears at position and gets shot at that speed and angle.
I'm using a CADisplayLink (which is effectively a timer that synchronizes with your frame rate) to call a function very quickly. Every time the function is called, the point is moved. The horizontal speed is constant and the vertical speed increases towards the bottom every frame to emulate gravity (`vy -= 0.5f; ). If you want more/less gravity, just mess around with this 0.5f value.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
point = [[CALayer alloc] init];
point.bounds = CGRectMake(0.0f, 0.0f, 10.0f, 10.0f);
point.backgroundColor = [UIColor redColor].CGColor;
point.position = CGPointMake(-10.0f, -10.0f);
[self.layer addSublayer:point];
[point release];
}
return self;
}
-(void)animateBallFrom:(CGPoint)start withSpeed:(CGFloat)speed andAngle:(CGFloat)angle
vx = speed*cos(angle);
vy = speed*sin(angle);
[CATransaction begin];
[CATransaction setDisableActions:YES];
point.position = start;
[CATransaction commit];
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animate)];
[displayLink setFrameInterval:2];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
-(void)animate {
if (point.position.x + point.bounds.size.width/2.0f < 0.0f || point.position.x > self.bounds.size.width + point.bounds.size.width/2.0f ||
point.position.y + point.bounds.size.height/2.0f < 0.0f || point.position.y > self.bounds.size.height + point.bounds.size.height/2.0f) {
[displayLink invalidate];
} else {
[CATransaction begin];
[CATransaction setDisableActions:YES];
point.position = CGPointMake(point.position.x+vx, point.position.y-vy);
vy -= 0.5f;
[CATransaction commit];
}
}
and the interface:
@interface Bounce : UIView {
CALayer *point;
CADisplayLink *displayLink;
CGFloat vx, vy;
}
-(void)animateBallFrom:(CGPoint)start withSpeed:(CGFloat)speed andAngle:(CGFloat)angle;
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With