Objective c 多点触控导致方法触发两次
我正在制作一个小游戏,将ipad屏幕分为下半部分和上半部分。每个玩家都有自己的游戏区(一个手指游戏)。我必须在视图上启用多点触摸,因为当两个玩家同时点击屏幕时,只有一个玩家的方法会被执行,或者根本没有 然而,当两个玩家做完全相同的动作时,这会导致两次方法触发的奇怪行为。这就是它现在的工作原理: 它检查玩家是否触摸到视图中的对象。如果有,将触发一个方法。如果一个玩家没有接触到一个对象,而是视图本身,那么另一个方法会触发。它检查是否在上半部分或下半部分触摸视图,以区分触摸与玩家1或玩家2 我一直在想一个解决办法,但我不确定什么是解决这个问题的好办法。也许我应该为每个球员分开视图(透明),这样我可以更容易地区分触球?这是我的方法Objective c 多点触控导致方法触发两次,objective-c,ios,multi-touch,touchesbegan,Objective C,Ios,Multi Touch,Touchesbegan,我正在制作一个小游戏,将ipad屏幕分为下半部分和上半部分。每个玩家都有自己的游戏区(一个手指游戏)。我必须在视图上启用多点触摸,因为当两个玩家同时点击屏幕时,只有一个玩家的方法会被执行,或者根本没有 然而,当两个玩家做完全相同的动作时,这会导致两次方法触发的奇怪行为。这就是它现在的工作原理: 它检查玩家是否触摸到视图中的对象。如果有,将触发一个方法。如果一个玩家没有接触到一个对象,而是视图本身,那么另一个方法会触发。它检查是否在上半部分或下半部分触摸视图,以区分触摸与玩家1或玩家2 我一直在想
- (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];
}
}
}
}
}
这里有一个小示意图。这一切都是有效的,除非两个玩家做相同的事情。它为每个玩家发射两次相同的动作
我将它分为两个视图。然后,我会在每个视图上附加一个手势识别器
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
}
该代码看起来很熟悉:-)。然而,你有很多额外的工作。此外,如果有两次点击,它将始终执行玩家1的点击,而不是玩家2的点击 你真的想强制每个玩家区域一次点击吗? 请注意,此代码并不能阻止这种情况。您可以在上一次触摸后开始另一次触摸,但该触摸不在设置中。但是,通过查看对象,您可以看到所有当前触摸,无论其状态如何。查询AllTouchs,它将为您提供屏幕上的所有当前触摸 考虑以下变化
- (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.
}
}
哦,你好:)。你有这么好的逻辑解决方案。当我这样看的时候,它看起来是如此清晰和明显。我只写了几个月的代码,所以我还是把事情复杂化了。我还要再次感谢你。这确实是一个解决办法。唯一的问题是,当UIView设置动画时,这将不起作用。