目标是创建一个环境,在这种环境中,球的图像会在视图 非常缓慢 内无休止地反弹。我可以以高速度进行无尽的弹跳,但速度不是很慢。
以下是代码示例:
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView: self.view];
UICollisionBehavior *ballCollision = [[UICollisionBehavior alloc] initWithItems: @[largeBall, mediumBall, smallBall]];
[ballCollision setTranslatesReferenceBoundsIntoBoundary: YES];
[ballCollision setCollisionMode: UICollisionBehaviorModeBoundaries];
float force = 0.1;
int angle = 225;
NSNumber *rad = [NSNumber numberWithDouble: DEGREES_TO_RADIANS(angle)];
UIPushBehavior *smallPush = [[UIPushBehavior alloc] initWithItems: @[smallBall] mode: UIPushBehaviorModeInstantaneous];
[smallPush setAngle: [rad floatValue]];
[smallPush setMagnitude: force];
UIDynamicItemBehavior *dynamicBehavior = [[UIDynamicItemBehavior alloc] initWithItems: @[smallBall]];
[dynamicBehavior setDensity: 0.0];
[dynamicBehavior setElasticity: 1.0];
[dynamicBehavior setFriction: 0.0];
[dynamicBehavior setResistance: 0.0];
[animator addBehavior: ballCollision];
[animator addBehavior: smallPush];
[animator addBehavior: dynamicBehavior];
我的高中物理课不能沉没,因为我无法弄清楚为什么这不起作用。摩擦是零,弹性是一,球应该永远弹跳,不应该吗?
答案 0 :(得分:4)
请记住,UIKIt Dynamics不是物理学。苹果公司在WWDC上反复说这话。这是“物理性的。”
UICollisionBehavior
抑制小于100p / s的矢量分量(这没有记录;你可以通过实验来解决它)。这通常是你想要的,所以事情不会永远弹跳,并使一些常见的用途更容易实现。 UIDynamicItemBehavior
并没有真正融入我的经验中。它没有定义项目的真正“基本”特征;它只是像物理一样调整其他行为。
UIKit Dynamics还有各种舍入错误,当您按下float
可以容纳的边缘时,项目会以非理想的方式运行。 UIKit Dynamics的目的是在UIView
中稍微反弹,而不是模拟真实的物理交互。
我并不认为UIKit Dynamics在如何做到这一点上是正确的。我觉得使用它很有挑战性,而且它通常表现得非常明显。如果你需要更像物理的东西,你可能想要探索SpriteKit。如果它影响你,我建议打开关于这个特殊问题的雷达(bugreport.apple.com)。
您可以通过更简单的实现自己进行试验:
- (void)viewDidLoad {
// Variables to play with
CGFloat force = .25; // At .25, will bounce forever.
CGFloat angle = 0; // Play with small values to see effect.
[super viewDidLoad];
UIView *ball = [[UIView alloc] initWithFrame:CGRectMake(400, 300, 50, 50)];
ball.backgroundColor = [UIColor greenColor];
[self.view addSubview:ball];
self.animator = [[UIDynamicAnimator alloc] initWithReferenceView: self.view];
UICollisionBehavior *ballCollision = [[UICollisionBehavior alloc] initWithItems: @[ball]];
[ballCollision setTranslatesReferenceBoundsIntoBoundary:YES];
UIPushBehavior *smallPush = [[UIPushBehavior alloc] initWithItems:@[ball]
mode:UIPushBehaviorModeInstantaneous];
[smallPush setAngle:GetRadiansForDegrees(angle)];
[smallPush setMagnitude: force];
UIDynamicItemBehavior *dynamicBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[ball]];
__weak id weakBehavior = dynamicBehavior;
[dynamicBehavior setElasticity: 1];
[dynamicBehavior setResistance: 0.0];
dynamicBehavior.action = ^{
NSLog(@"linear:%@", NSStringFromCGPoint([weakBehavior linearVelocityForItem:ball]));
};
[self.animator addBehavior: ballCollision];
[self.animator addBehavior: smallPush];
[self.animator addBehavior: dynamicBehavior];
}
答案 1 :(得分:0)
这可能不适用于您的用例,但它适用于我的工作,我不希望我的项目在减速时彼此卡住
我添加了一个代表来检测碰撞发生的时间,并在碰撞的相反方向上对每个项目添加了一个小推动,这样物品就永远不会被卡在一起