精灵运动的 MultiTouch 控制 - cocos2d

发布于 2025-01-05 00:01:33 字数 3098 浏览 7 评论 0原文

我已经处理这个问题有一段时间了。 我想做的是通过屏幕左侧或右侧的触摸来控制 CCSprite 的右/左移动。

如果您在每次触摸后抬起手指,那么这样做就没有问题。但我想要的最好用一个例子来描述: 玩家触摸屏幕的左侧,精灵就会向左移动。现在玩家(仍然触摸左侧)触摸右侧......精灵现在应该向右移动。现在玩家的一根手指在左侧,一根手指在右侧,如果他现在将触摸从右侧移开,精灵应该再次向左侧移动。

这就是我现在所拥有的:

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSSet *allTouches = [event allTouches];
    UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];

    if (location.x < 240) {
        [player walk:kkMoveLeft];
    } else if (location.x > 240) {
        [player walk:kkMoveRight];
    }

    //Swipe Detection Part 1
    firstTouch = location;
}

-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSSet *allTouches = [event allTouches];
    UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];

    //Swipe Detection Part 2
    lastTouch = location;

    float swipeLength = ccpDistance(firstTouch, lastTouch);

    if (firstTouch.y < lastTouch.y && swipeLength > 60) {
        [player jump:kkJumpUp];
    } else if (firstTouch.y > lastTouch.y && swipeLength > 60){
        [player jump:kkJumpDown];
    }

    [player endWalk];

}

如果有人能告诉我如何解决这个问题,我将不胜感激。谢谢 。

更新我的解决方案:

//1. Enable multitouch in the appDelegate
[glView setMultipleTouchEnabled:YES];

//2. Create an Array to keep track of active touches
touchArray = [[NSMutableArray alloc] init];

//3. Touch Methods
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        if (![touchArray containsObject:touch]) {
            [touchArray addObject:touch];
            CGPoint location = [touch locationInView:[touch view]];
            location = [[CCDirector sharedDirector] convertToGL:location];
            CCLOG(@"start: %f", location.x);
            if (location.x < 240) {
                [player walk:kkMoveLeft];
            } else if (location.x > 240) {
                [player walk:kkMoveRight];
            }
        }
    }

}

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

    for (UITouch *touch in touches) {
        [touchArray removeObject:touch];
        CGPoint location = [touch locationInView:[touch view]];
        location = [[CCDirector sharedDirector] convertToGL:location];
        CCLOG(@"end: %f", location.x);
    }

    for (UITouch *touch in touchArray) {
        CGPoint location = [touch locationInView:[touch view]];
        location = [[CCDirector sharedDirector] convertToGL:location];
        CCLOG(@"still: %f", location.x);
        if (location.x < 240) {
            [player walk:kkMoveLeft];
        } else if (location.x > 240) {
            [player walk:kkMoveRight];
        }
    }


    if ([touchArray count] == 0) {
        [player endWalk];
    }

}

I've been dealing with this problem for quite some time.
What I am trying to do is have a CCSprite's right/left movement controlled by touches on either the left side of the screen or the right.

Doing this is no problem if you lift your finger after each touch. But what I want is best described by an example:
The player touches the left side of the screen and the sprite moves to the left. Now the player (while still touching the left side) touches the right side...the sprite should now move right. Now the player has one finger on the left and one on the right side, if he now lifts the touch off the right side the sprite should again move to the left.

This is what I have now:

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSSet *allTouches = [event allTouches];
    UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];

    if (location.x < 240) {
        [player walk:kkMoveLeft];
    } else if (location.x > 240) {
        [player walk:kkMoveRight];
    }

    //Swipe Detection Part 1
    firstTouch = location;
}

-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSSet *allTouches = [event allTouches];
    UITouch * touch = [[allTouches allObjects] objectAtIndex:0];
    CGPoint location = [touch locationInView: [touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];

    //Swipe Detection Part 2
    lastTouch = location;

    float swipeLength = ccpDistance(firstTouch, lastTouch);

    if (firstTouch.y < lastTouch.y && swipeLength > 60) {
        [player jump:kkJumpUp];
    } else if (firstTouch.y > lastTouch.y && swipeLength > 60){
        [player jump:kkJumpDown];
    }

    [player endWalk];

}

I'd appreciate it if someone could tell me how to go about this. Thank you .

UPDATE MY SOLUTION:

//1. Enable multitouch in the appDelegate
[glView setMultipleTouchEnabled:YES];

//2. Create an Array to keep track of active touches
touchArray = [[NSMutableArray alloc] init];

//3. Touch Methods
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        if (![touchArray containsObject:touch]) {
            [touchArray addObject:touch];
            CGPoint location = [touch locationInView:[touch view]];
            location = [[CCDirector sharedDirector] convertToGL:location];
            CCLOG(@"start: %f", location.x);
            if (location.x < 240) {
                [player walk:kkMoveLeft];
            } else if (location.x > 240) {
                [player walk:kkMoveRight];
            }
        }
    }

}

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

    for (UITouch *touch in touches) {
        [touchArray removeObject:touch];
        CGPoint location = [touch locationInView:[touch view]];
        location = [[CCDirector sharedDirector] convertToGL:location];
        CCLOG(@"end: %f", location.x);
    }

    for (UITouch *touch in touchArray) {
        CGPoint location = [touch locationInView:[touch view]];
        location = [[CCDirector sharedDirector] convertToGL:location];
        CCLOG(@"still: %f", location.x);
        if (location.x < 240) {
            [player walk:kkMoveLeft];
        } else if (location.x > 240) {
            [player walk:kkMoveRight];
        }
    }


    if ([touchArray count] == 0) {
        [player endWalk];
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月静好 2025-01-12 00:01:33

如果我正确理解您的问题,您应该做的是:

  1. ccTouchesEnded 中,而不是简单地调用 endWalk,检查是否仍然存在任何触摸(以这样做,您可以在 ccTouchesEnded 中迭代 allTouches);

  2. 在适当的情况下(即,触摸仍在激活播放器),调用 startWalk

  3. 如果没有触摸,则调用endWalk

该代码与您在 ccTouchesBegan 中的代码类似,只是您进行迭代(我不确定 allTouches 在 TouchesEnded 的索引 0 处包含什么)。

旧答案:

你没有说任何关于你现在如何处理触摸的事情。无论如何,正确的方法是定义 ccTouches* 方法(相对于 ccTouch*),其中 * 可以是:Began已移动已结束

-(void)tccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
    ...
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  ...
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  ...
}

请记住,touchesBegan 会在检测到每个触摸时触发。因此,如果您想了解当前活动的所有触摸的状态,则必须使用 allTouches

还可以看看 来自 iphonesdk 的这篇文章,我发现它对语义很有洞察力这些方法中的触摸次数。

If I understand correctly your problem, what you should do is:

  1. in ccTouchesEnded, instead of simply calling endWalk, check to see is any touch is still present (to do so, you could iterate over allTouches);

  2. in the appropriate case (i.e., a touch is still activating the player), call startWalk.

  3. if no touch is present, call endWalk.

The code would be similar to what you have in ccTouchesBegan, only you iterate (I am not sure what allTouches contains at index 0 in touchesEnded).

OLD ANSWER:

You are not saying anything about how you are handling touches right now. In any case, the way to go is defining ccTouches* methods (vs. ccTouch*), where * can be: Began, Moved, Ended.

-(void)tccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
    ...
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  ...
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  ...
}

Keep in mind that touchesBegan is fired at each new touch that is detected. So, if you want to know the status of all touches currently active, you have to use allTouches.

Have also a look at this post from iphonesdk which I found insightful as to the semantics of touches in those methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文