2012-04-26 5 views
0

저는 하반부와 상반부에 ipad 화면을 나누는 작은 게임을 만들고 있습니다. 각 플레이어는 자신 만의 섹션을 가지고 연주 할 수 있습니다 (한 손가락 연주). 두 명의 플레이어가 동시에 화면을 쳤을 때 한 플레이어에 대한 메소드 만 실행되거나 전혀 실행되지 않기 때문에 뷰에서 멀티 터치를 활성화해야했습니다.멀티 터치로 두 번 발사하는 방법이 있습니다.

그러나 두 명의 플레이어가 정확히 동일한 작업을 수행 할 때 두 번씩 실행되는 메서드가 이상하게 작동합니다. 이것이 현재 작동하는 방식입니다 : 플레이어가보기에서 객체를 터치했는지 확인합니다. 그들이 가지고있는 경우, 메서드가 발생합니다. 플레이어가 객체를 터치했지만 뷰 자체를 터치하지 않으면 다른 메소드가 실행됩니다. 보기가 플레이어 1/2 또는 플레이어 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]; 
      } 

     } 


    } 

} 

} 

여기가 약간 개략적입니다. 이것은 두 선수가 같은 일을 할 때를 제외하고는 모두 작동합니다. 그것은 각 플레이어에 대해 동일한 액션을 두 번 발사합니다.

schematic

답변

1

코드가 익숙해졌습니다. 그러나, 당신이 거기에 가지고있는 것은 많은 여분의 일을합니다. 또한, 두 개의 도청이 있다면, 그것은 항상 플레이어 1의 탭을 할 것이고, 플레이어 2의 탭은하지 않을 것입니다.

플레이어 당 한 번의 탭을 시행 하시겠습니까? 이 코드가이를 방지하지는 않습니다. 이전 터치 후에 다른 터치를 시작할 수 있으며, 이는 설정되지 않습니다. 그러나 개체를보고 상태에 관계없이 현재의 모든 접촉을 볼 수 있습니다. Query 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. 
    }  
} 
+0

oh 안녕하세요 :). 당신이 거기에있어 좋은 그리고 논리적 인 해결책. 내가 이렇게 보았을 때 분명하고 분명해 보입니다. 나는 불과 2 개월 동안 코딩을 해왔으므로 여전히 문제가 너무 복잡합니다. 나는 다시 한번 너에게 감사해야한다. –

0

나는 두 가지보기로 분리한다. 그런 다음 각보기에 제스처 인식기를 부착합니다.

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 
} 
+0

이 실제로 해결책이 될 것를 생각해 보자. 유일한 문제는 UIViews가 움직이는 동안 이것이 작동하지 않는다는 것입니다. –