1

我们的目标是创造一个环境,一个球的图像将在一个视图中非常缓慢地不断反弹。我可以使无休止的弹跳以高速工作,但不能以慢速工作。

这是代码示例:

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];

我的高中物理课一定没有沉没,因为我不明白为什么这不起作用。摩擦力为零,弹性为一,球应该永远弹跳,不是吗?

4

2 回答 2

4

请记住,UIKIt 动力学不是物理学。苹果在 WWDC 上反复强调这一点。它是“类似物理的”。

UICollisionBehavior抑制小于 100p/s 的矢量分量(这没有记录;您可以通过实验来解决)。这通常是您想要的,所以事情不会永远弹跳,并使一些常见的用途更容易实现。UIDynamicItemBehavior并没有真正融入我的经验。它没有定义项目的真正“基本”特征;它只是以感觉像物理的方式调整其他行为。

floatUIKit Dynamics 也有各种舍入错误,当您推动 a可以容纳的边缘时,这些错误会使项目以非理想方式表现。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];
}
于 2013-11-06T15:01:28.630 回答
0

这可能不适用于您的用例,但它适用于我的情况,我不希望我的物品在减速时相互卡住

我添加了一个委托来检测碰撞何时发生,并在碰撞的相反方向对每个项目添加了一个小的推动,这样项目就不会最终被粘在一起

于 2016-10-05T12:22:23.860 回答