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

そして、「悪い」ことが壁の 1 つにぶつかると、次のようになります。

    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;

printステートメントでさえログに表示されません

4

1 に答える 1

0

既存の動作 (あなたのbadForce.active = YES) を更新したいように動作しているように見えますが、毎回新しいプッシュ動作を作成しています。どちらかを行います。毎回新しいプッシュ動作を作成する場合は、毎回アニメーターに追加する必要があります。一度作成する場合は、アニメーターに一度追加してから、毎回更新してアクティブ化します。

おそらく、1 つのプッシュ動作を作成し、一度追加して、何度も更新する必要があります。

- (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が、4つの壁の作成から(参照ビューの境界を衝突境界に定義するはるかに簡単なプロセスではなく)、プッシュベクトルが必要であると推測しましたどの壁に衝突したかによって異なります。上の壁にぶつかると下に押し下げられ (逆も同様)、左の壁にぶつかると右に押し出されます (逆も同様)。ただし、任意のプッシュ ベクトル アルゴリズムを使用してください。

主な観察事項は、1 つのプッシュ動作を追加して何度も更新するか、毎回新しい瞬時プッシュ動作を追加するかのいずれかです。しかし、上記はシミュレーターとデバイスの両方で機能します (正直なところ、一方では機能し、他方では機能しなかった理由はわかりません。元のコードがどちらでも機能したかはわかりません)。

于 2014-03-13T23:36:36.050 に答える