5
votes

I've used this excellent tutorial to kickoff a small project I'm working on involving physics:

http://www.cocoanetics.com/2010/05/physics-101-uikit-app-with-box2d-for-gravity/

Basically, it creates a world and applies the physics of B2D to whichever views you have. Very simple and it works. However, I tried to apply the same logic by using CALayers, i.e., I programmatically create layers, add them to the main view.layer and try to animate them.

Sample code for creating the layer:

CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor blackColor].CGColor;
layer.frame = CGRectMake(50, 100, 30, 30);
layer.name = @"square";
[self.view.layer addSublayer:layer];

And the applied physics in the ticker:

CALayer *oneLayer = (CALayer *)b->GetUserData();
// y Position subtracted because of flipped coordinate system
CGPoint newCenter = CGPointMake(b->GetPosition().x * PTM_RATIO, self.view.bounds.size.height - b->GetPosition().y * PTM_RATIO);
oneLayer.position = newCenter;
CGAffineTransform transform = CGAffineTransformMakeRotation(- b->GetAngle());
oneLayer.affineTransform = transform;

Notice that I adapted the affine transform call to the CALayer class.

I've checked and double-checked the variables, and the numbers seem to match. What I get is a weird bounce from the CALayer animation, and a perfect animation from the UIView. Anyone experienced in Box2D and UIKit to answer why this can be happening?

1
Can you explain "weird bounce"erkanyildiz
This: youtu.be/OpTXuqIgiPE - black is CALayer, Green is UIView.The CALayer bounces before hitting the "ground". One reason leads me to think that the dimensions et al. are correct is due to the fact that the CALayer ultimately stops bouncing with the bottom of frame touching the ground.hcabral

1 Answers

5
votes

Unlike UIViews, CALayers have built-in implicit animations. Every time you change a value of an animatable property a short animation will be introduced. You have to wrap your code in CATransaction and disable actions to get rid of this effect:

[CATransaction begin];
[CATransaction setDisableActions:YES]; // implicit animations get disabled

CALayer *oneLayer = (CALayer *)b->GetUserData();
// y Position subtracted because of flipped coordinate system
CGPoint newCenter = CGPointMake(b->GetPosition().x * PTM_RATIO, self.view.bounds.size.height - b->GetPosition().y * PTM_RATIO);
oneLayer.position = newCenter;
CGAffineTransform transform = CGAffineTransformMakeRotation(- b->GetAngle());
oneLayer.affineTransform = transform;

[CATransaction commit];