0

iPadの画面を下半分と上半分に分割するちょっとしたゲームに取り組んでいます。各プレーヤーには、自分のセクションがあります (ワンフィンガープレイ)。ビューでマルチタッチを有効にする必要がありました。これは、2 人のプレーヤーが同時に画面にヒットすると、1 人のプレーヤーのメソッドのみが実行されるか、まったく実行されないためです。

ただし、これにより、2 人のプレイヤーがまったく同じアクションを実行すると、メソッドが 2 回起動するという奇妙な動作が発生します。これが現在の動作方法です。プレイヤーがビュー内のオブジェクトに触れたかどうかを確認します。存在する場合、メソッドが起動します。プレーヤーがオブジェクトではなくビュー自体に触れた場合、別のメソッドが起動します。プレーヤー 1 またはプレーヤー 2 からタッチを区別するために、ビューが上半分または下半分でタッチされているかどうかを確認します。

私は解決策を考えてきましたが、これを解決するための良い方法が何であるかわかりません。タッチをより簡単に区別できるように、各プレーヤーのビュー (透明) を分離する必要があるのではないでしょうか? これが私の touchesBegan メソッドです。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    NSMutableSet *touchedCirclesPlayerOne = [NSMutableSet set];
    NSMutableSet *touchedCirclesPlayerTwo = [NSMutableSet set];

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInView:self.view];
        for (Circle *circle in playerOneCircles) {
            if ([circle.layer.presentationLayer hitTest:touchLocation]) {
                [touchedCirclesPlayerOne addObject:circle];

            } 
        }

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInView:self.view];
        for (Circle *circle in playerTwoCircles) {
            if ([circle.layer.presentationLayer hitTest:touchLocation]) {
                [touchedCirclesPlayerTwo addObject:circle];

                } 
            }
    }

    if (touchedCirclesPlayerOne.count) {

        NSLog(@"test");

        for (Circle *circle in touchedCirclesPlayerOne) {

            [circle playerTap:nil];

        }

    } else if (touchedCirclesPlayerTwo.count) {

        NSLog(@"test2");

        for (Circle *circle in touchedCirclesPlayerTwo) {

            [circle SecondPlayerTap:nil];

        }


    } else {

        for (UITouch *touch in touches) {
            CGPoint touchLocation = [touch locationInView:self.view];

            if (CGRectContainsPoint(CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2), touchLocation)) {

            NSLog(@"wrong player 1");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"wrong player 1" object:self];

            }  else {

                NSLog(@"wrong player 2");
                [[NSNotificationCenter defaultCenter] postNotificationName:@"wrong player 2" object:self];
            }

        }


    }

}

}

ここに少し概略図があります。2 人のプレイヤーが同じことを行う場合を除いて、これはすべて機能します。各プレイヤーに対して同じアクションを 2 回実行します。

回路図

4

2 に答える 2

1

そのコードはおなじみのようです:-)。ただし、そこにあるものは多くの余分な作業を行います。また、タップが 2 つある場合は、常にプレーヤー 1 のタップが行われ、プレーヤー 2 のタップは行われません。

プレーヤー エリアごとに 1 回のタップを強制しますか? このコードはそれを妨げないことに注意してください。前のタッチの後に別のタッチを開始できますが、それはセットには含まれません。ただし、オブジェクトを見ると、状態に関係なく、現在のすべてのタッチを確認できます。allTouches を照会すると、画面上のすべての現在のタッチが得られます。

次の変更を検討してください...

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // Since this rect object is always needed, you probably want to
    // make it once, and keep it as private variables.  If your area is
    // not really divided completely in half, you will want two separate
    // rects, each defining the area for each player.
    CGRect player1Area = CGRectMake(0, self.view.frame.size.height/2, self.view.frame.size.width, self.view.frame.size.height/2);

    // For performance sake, we will loop through the touches a single time
    // and process each tap in that loop.  Use these flags to later determine
    // what to do if the player tapped some place other than on a circle.
    BOOL player1Tapped = NO;
    BOOL player2Tapped = NO;
    BOOL player1TappedCircle = NO;
    BOOL player2TappedCircle = NO;

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInView:self.view];
        if (CGRectContainsPoint(player1Area, touchLocation)) {
            // This touch is in player 1's area
            // Small additional code to restrict player to a single tap.
            player1Tapped = YES;
            for (Circle *circle in playerOneCircles) {
                // I guess you are using a CAShapeLayer, and looking at the
                // position during animation?
                if ([circle.layer.presentationLayer hitTest:touchLocation]) {
                    player1TappedCircle = YES;
                    [circle playerTap:nil];
                }
            }
        } else {
            // This touch is not for player 1, so must be for player 2...
            player2Tapped = YES;
            for (Circle *circle in playerTwoCircles) {
                if ([circle.layer.presentationLayer hitTest:touchLocation]) {
                    player2TappedCircle = YES;
                    [circle secondPlayerTap:nil];
                }
            }
        }
    }

    // All touches have now been handled.  We can do stuff based on whether any player
    // has tapped any area, or circles, or whatever.
    if (player1Tapped && !player1TappedCircle) {
        // Player 1 tapped, but did not tap on a circle.
    }
    if (player2Tapped && !player2TappedCircle) {
        // Player 2 tapped, but did not tap on a circle.
    }    
}
于 2012-04-26T12:38:13.180 に答える
0

私はそれを2つのビューに分けます。次に、各ビューにジェスチャ認識機能を追加します。

UITapGestureRecognizer *tapRecog1 = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap1:)] autorelease]; 

[self.view1 addGestureRecognizer:self.tapRecog1]; 

UITapGestureRecognizer *tapRecog2 = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap2:)] autorelease]; 

[self.view2 addGestureRecognizer:self.tapRecog2];

次に、アクション メソッドを実装します。

- (void)handleTap1:(UITapGestureRecognizer *)tap;
{
    CGPoint point = [tap locationInView:self.view1];

    // do stuff
}

- (void)handleTap2:(UITapGestureRecognizer *)tap;
{
    CGPoint point = [tap locationInView:self.view2];

    // do stuff
}
于 2012-04-26T11:26:17.860 に答える