MultiTouch управление движением спрайтов - cocos2d - PullRequest
2 голосов
/ 12 февраля 2012

Я уже давно занимаюсь этой проблемой. То, что я пытаюсь сделать, это иметь движение вправо / влево 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];
    }

}

1 Ответ

1 голос
/ 12 февраля 2012

Если я правильно понимаю вашу проблему, вы должны сделать следующее:

  1. в ccTouchesEnded, вместо простого вызова endWalk, проверьте, присутствует ли еще какое-либо касание (для этого вы можете выполнить итерацию по allTouches);

  2. в соответствующем случае (т. Е. Касание все еще активирует игрока), наберите startWalk.

  3. если нет прикосновения, позвоните endWalk.

Код будет аналогичен тому, что есть в ccTouchesBegan, только вы выполняете итерацию (я не уверен, что allTouches содержит в индексе 0 в touchesEnded).

СТАРЫЙ ОТВЕТ:

Вы сейчас ничего не говорите о том, как вы обрабатываете прикосновения. В любом случае, путь состоит в определении ccTouches* методов (против ccTouch*), где * может быть: 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 {
  ...
}

Имейте в виду, что touchSegan срабатывает при каждом обнаружении нового . Таким образом, если вы хотите узнать статус всех активных в данный момент касаний, вы должны использовать allTouches.

Также взгляните на этот пост от iphonesdk , который я нашел проницательным в отношении семантики касаний в этих методах.

...