【问题标题】:Different touches that not react with each other objective c不相互反应的不同触摸目标 c
【发布时间】:2016-03-08 08:08:41
【问题描述】:

我在 Ipad 上为两个玩家制作简单的游戏,就像乒乓球一样,当一个手指在屏幕上时,玩家可以用他的球拍做出反应,但是当第二个手指在他的球拍上时,他不能移动他的球拍,但是他而是移动第一个桨,我设置了一些NSLog,它说它们都移动了,但这是不对的,这是我的代码示例:

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
/* Called when a touch begins */
    for (UITouch *touch in touches) {
//First player
CGPoint touchLocation = [touch locationInNode:self];
SKPhysicsBody* body = [self.physicsWorld bodyAtPoint:touchLocation];

if (body && [body.node.name isEqualToString: paddleCategoryName]) {
    NSLog(@"Began touch on first paddle");
    self.isFingerOnPaddle = YES;
}
//Second player
CGPoint secondTouchLocation = [touch locationInNode:self];
SKPhysicsBody* secondbody = [self.physicsWorld bodyAtPoint:secondTouchLocation];
if (secondbody && [secondbody.node.name isEqualToString: secondPaddleCategoryName]) {
    NSLog(@"Began touch on second paddle");
    self.isSecondFingerOnPaddle = YES;
}
    }
 }

-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
for (UITouch *touch in touches) {
    //for first player
    if (self.isFingerOnPaddle) {
        CGPoint touchLocation = [touch locationInNode:self];
        CGPoint previousLocation = [touch previousLocationInNode:self];
        SKSpriteNode* paddle = (SKSpriteNode*)[self childNodeWithName: paddleCategoryName];
        int paddleY = paddle.position.y + (touchLocation.y - previousLocation.y);
        paddleY = MAX(paddleY, paddle.size.height/2);
        paddleY = MIN(paddleY, self.size.height - paddle.size.height/2);
        paddle.position = CGPointMake(paddle.position.x, paddleY);
        NSLog(@"First paddle moving");

    }
    //for second player
    if (self.isSecondFingerOnPaddle) {
        CGPoint touchLocation = [touch locationInNode:self];
        CGPoint previousLocation = [touch previousLocationInNode:self];
        SKSpriteNode* secondPaddle = (SKSpriteNode*)[self childNodeWithName: secondPaddleCategoryName];
        int secondPaddleY = secondPaddle.position.y + (touchLocation.y - previousLocation.y);
        secondPaddleY = MAX(secondPaddleY, secondPaddle.size.height/2);
        secondPaddleY = MIN(secondPaddleY, self.size.height - secondPaddle.size.height/2);
        secondPaddle.position = CGPointMake(secondPaddle.position.x, secondPaddleY);
        NSLog(@"Second paddle moving");
    }
}
}
-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
self.isFingerOnPaddle = NO;
self.isSecondFingerOnPaddle = NO;
 }

我做错了什么,我需要改变我的代码工作,就像它应该做的那样

【问题讨论】:

    标签: ios objective-c sprite-kit multi-touch


    【解决方案1】:

    更好的方法是对 paddle 进行子类化,并在 paddle 子类中执行触摸代码。这消除了循环遍历触摸数组以查看您的拨片是否被触摸的麻烦,而且它使代码更加整洁和易于阅读。唯一的问题是你必须对你的节点设置稍微不同的样式,因为触摸移动在桨之外不起作用。

    这是你的风格

    1) 子类 Paddle 到 SKNode
    2) 为您的实际桨 gfx 创建一个 SKSpriteNode 的子节点
    3) 桨框应设置为场景的宽度,允许玩家触摸的高度(可能是桨 gfx 的高度)
    4) 覆盖 Paddle 内的触摸代码,集合中的所有触摸代码应仅与 paddle 所触摸的内容有关
    5) 在这些覆盖中执行所有滑动逻辑

    现在您已经为您正在寻找的行为定义了 Paddle,您可以将它添加到您喜欢的任何场景中。

    这个方法的好处是你消除了很多重复的代码,(因为两边的桨表现不同)如果你想增加一些乐趣,你可以在两边添加更多的桨来提供更多的变化. (每个玩家在比赛场地的中间和底部都有一个桨,可以独立移动)

    【讨论】:

    • 感谢您的建议,我一定会采纳您关于添加更多桨的建议,听起来很棒。
    • 那么重点是编写可重用的代码,并避免重复
    【解决方案2】:

    你的逻辑是错误的,只需添加一个 touchArray 属性来存储第一次触摸和第二次触摸,在触摸开始时设置它,然后确定触摸何时移动。

    -(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
        /* Called when a touch begins */
        for (UITouch *touch in touches) {
    
            CGPoint touchLocation = [touch locationInNode:self];
            SKSpriteNode *node = (SKSpriteNode *)[self nodeAtPoint:touchLocation];
    
            if (node && [node.name isEqualToString: paddleCategoryName]) {
                NSLog(@"Began touch on first paddle");
    
                [self.touchArray replaceObjectAtIndex:0 withObject:touch];
    
            }else if (node && [node.name isEqualToString: secondPaddleCategoryName]) {
                NSLog(@"Began touch on second paddle");
    
                [self.touchArray replaceObjectAtIndex:1 withObject:touch];
    
            }
    
        }
    }
    
    -(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
        for (UITouch *touch in touches) {
            CGPoint touchLocation = [touch locationInNode:self];
    
            UITouch *firstTouch = self.touchArray[0];
            UITouch *secondTouch = self.touchArray[1];
    
            SKSpriteNode *paddle = [[SKSpriteNode alloc] init];
    
            if (touch == firstTouch) {
                CGPoint previousLocation = [touch previousLocationInNode:self];
                SKSpriteNode* paddle = (SKSpriteNode*)[self childNodeWithName: paddleCategoryName];
                int paddleY = paddle.position.y + (touchLocation.y - previousLocation.y);
                paddleY = MAX(paddleY, paddle.size.height/2);
                paddleY = MIN(paddleY, self.size.height - paddle.size.height/2);
                paddle.position = CGPointMake(paddle.position.x, paddleY);
                NSLog(@"First paddle moving");
    
            }else if (touch == secondTouch) {
                CGPoint touchLocation = [touch locationInNode:self];
                CGPoint previousLocation = [touch previousLocationInNode:self];
                SKSpriteNode* secondPaddle = (SKSpriteNode*)[self childNodeWithName: secondPaddleCategoryName];
                int secondPaddleY = secondPaddle.position.y + (touchLocation.y - previousLocation.y);
                secondPaddleY = MAX(secondPaddleY, secondPaddle.size.height/2);
                secondPaddleY = MIN(secondPaddleY, self.size.height - secondPaddle.size.height/2);
                secondPaddle.position = CGPointMake(secondPaddle.position.x, secondPaddleY);
                NSLog(@"Second paddle moving");
            }
    
    
        }
    }
    -(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
        for (UITouch *touch in touches) {
            if (touch == self.touchArray[0]) {
                [self.touchArray replaceObjectAtIndex:0 withObject:@""];
            }else if (touch == self.touchArray[1]) {
                [self.touchArray replaceObjectAtIndex:1 withObject:@""];
    
            }
        }
    
        self.isFingerOnPaddle = NO;
        self.isSecondFingerOnPaddle = NO;
    }
    

    【讨论】:

    • 对不起,我不明白如何设置数组,你能告诉我吗?
    • self.touchArray = [NSMutableArray arrayWithObjects:@"", @"", nil];
    • 将一个字符串放入一个触摸数组中(并投射,即撒谎),然后再进行触摸是一个敏锐的想法。
    • @Eiko 你有更好的报价吗?
    • 一个非常简单的方法是将这两个触摸存储在单独的属性中并将它们清零。但是当你不去想它时,几乎可以保证将 NSString 当作 UITouch 来处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    相关资源
    最近更新 更多