0

我为在屏幕上弹跳的对象(视图)实现了 UIdynamics。在模拟器上这可以完美地工作,但是在实际的 iphone 上进行测试时,边界不起作用。如有必要,我会发布代码,但这在我看来就像我在概念上遗漏了一些东西。任何提示或想法?

附加细节:屏幕周围的边界,我已经在两种尺寸的模拟器上进行了测试,它工作正常。

“bad”是视图的名称——(“screenWidth”和“screenHeight”也被定义为实例变量)

///left wall
badCollision = [[UICollisionBehavior alloc] initWithItems:@[bad]];
badCollision.collisionDelegate = self;
CGPoint pt1 = CGPointMake(0, 0);
CGPoint pt2 = CGPointMake(0, screenHeight);
[badCollision addBoundaryWithIdentifier:@"leftWall" fromPoint:pt1 toPoint:pt2];
[animator addBehavior:badCollision];

//right wall
badCollision = [[UICollisionBehavior alloc] initWithItems:@[bad]];
badCollision.collisionDelegate = self;
pt1 = CGPointMake(screenWidth, 0);
pt2 = CGPointMake(screenWidth, screenHeight);
[badCollision addBoundaryWithIdentifier:@"rightWall" fromPoint:pt1 toPoint:pt2];
[animator addBehavior:badCollision];

//top wall
badCollision = [[UICollisionBehavior alloc] initWithItems:@[bad]];
badCollision.collisionDelegate = self;
pt1 = CGPointMake(0, 0);
pt2 = CGPointMake(screenWidth, 0);
[badCollision addBoundaryWithIdentifier:@"topWall" fromPoint:pt1 toPoint:pt2];
[animator addBehavior:badCollision];

//bottom wall
badCollision = [[UICollisionBehavior alloc] initWithItems:@[bad]];
badCollision.collisionDelegate = self;
pt1 = CGPointMake(0, screenHeight);
pt2 = CGPointMake(screenWidth, screenHeight);
[badCollision addBoundaryWithIdentifier:@"bottomWall" fromPoint:pt1 toPoint:pt2];
[animator addBehavior:badCollision];

这就是当“坏”击中一堵墙时会发生什么。

    NSLog(@"Wall Hit");
    UIPushBehavior *badForce = [[UIPushBehavior alloc] initWithItems:@[item] mode:UIPushBehaviorModeInstantaneous];
    UIView *itemView = (UIView*)item;
    itemView.backgroundColor = [UIColor redColor];
    [UIView animateWithDuration:0.3 animations:^{
        itemView.backgroundColor = [UIColor blueColor];
    }];
    int xneg = (int)drand48();
    if (xneg < .51)
        xneg = 1;
    else
        xneg = -1;
    int yneg = (int)drand48();
    if (yneg < .51)
        yneg = 1;
    else
        yneg = -1;
    double xSpeed = xneg*(drand48()+1)/20+.02;
    double ySpeed = yneg*(drand48()+1)/20+.02;
    badForce.pushDirection = CGVectorMake(xSpeed,ySpeed);
    badForce.active = YES;

甚至打印语句都不会显示在日志中

4

1 回答 1

0

您的行为似乎就像您想更新现有行为(您的badForce.active = YES)一样,但您每次都在创建新的推送行为。做一个或另一个。如果你要每次都创建一个新的推送行为,你必须每次都将它添加到你的动画师中。如果您要创建一次,则将其添加到您的动画师一次,然后每次更新并激活它。

您可能想要创建一个推送行为,添加一次,然后一次又一次地更新它:

- (void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p
{
    NSString *wallIdentifier = (id)identifier;
    NSLog(@"Wall Hit: %@", wallIdentifier);

    if (!self.push) {
        self.push = [[UIPushBehavior alloc] initWithItems:@[item] mode:UIPushBehaviorModeInstantaneous];
        self.push.active = NO;
        [self.animator addBehavior:self.push];
    }

    UIView *itemView = (UIView*)item;
    itemView.backgroundColor = [UIColor redColor];
    [UIView animateWithDuration:0.3 animations:^{
        itemView.backgroundColor = [UIColor blueColor];
    }];

    double weight = 0.5;
    double xSpeed = weight * (drand48() * 2.0 - 1.0); // rand number between -weight and weight
    double ySpeed = weight * (drand48() * 2.0 - 1.0); // rand number between -weight and weight

    if ([wallIdentifier isEqualToString:@"bottomWall"])
        ySpeed = -fabs(ySpeed);
    else if ([wallIdentifier isEqualToString:@"topWall"])
        ySpeed = fabs(ySpeed);
    else if ([wallIdentifier isEqualToString:@"leftWall"])
        xSpeed = fabs(xSpeed);
    else if ([wallIdentifier isEqualToString:@"rightWall"])
        xSpeed = -fabs(xSpeed);

    self.push.pushDirection = CGVectorMake(xSpeed,ySpeed);
    self.push.active = YES;
}

请注意,我希望您原谅我调整您的pushDirection算法,但我从您创建的四面墙(而不是将参考视图的边界定义为碰撞边界的更简单的过程)推断出您希望推动向量根据您碰巧撞到的墙壁而有所不同。如果您撞到顶墙(反之亦然),则上述内容会向下推,如果您撞到左墙(反之亦然),则上述内容会向右推。但是使用你想要的任何推送向量算法。

主要观察结果是,您要么想要添加一个推送行为并一次又一次地更新它,要么您只想每次都添加新的瞬时推送行为。但是上面的代码在模拟器和设备上都有效(老实说,我不清楚为什么它对你有用,而不是另一个;我看不出你的原始代码是如何工作的)。

于 2014-03-13T23:36:36.050 回答