MultiTouch управление движением спрайтов - cocos2d

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

}

person Alexander Blunck    schedule 12.02.2012    source источник


Ответы (1)


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

  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 {
  ...
}

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

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

person sergio    schedule 12.02.2012
comment
Как работают касания, это не моя проблема (см. обновленный вопрос). У меня возникают проблемы с тем, что игрок продолжает двигаться после того, как коснулся экрана двумя пальцами, а затем поднял один вверх и продолжал движение игрока. - person Alexander Blunck; 12.02.2012
comment
Тем временем я сам нашел решение ... но спасибо за ваши усилия, и, поскольку ваш обновленный ответ - это практически то, к чему я пришел, я принимаю ваш ответ ;-) - person Alexander Blunck; 13.02.2012