Проблемы с сенсорным обнаружением - PullRequest
0 голосов
/ 16 января 2012

Я только изучаю Cocos2d и Objective-C, и у меня есть некоторые проблемы с распознаванием касаний.

У меня есть несколько спрайтов в HelloWorldLayer и некоторые draggableSprites (NSMutableArray). Два из draggableSprites расположены один над другим (нижний больше).

Тогда у меня есть некоторый код, который встряхивает затронутый спрайт:

- (void)selectSpriteForTouch:(CGPoint)touchLocation {
    CCSprite *touchSprite = nil;
    for (CCSprite *sprite in dragableSprites) {
        if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {            
            touchSprite = sprite;
            break;
        }
    }    
    if (touchSprite != selSprite) {
        [selSprite stopAllActions];
        [selSprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]];
        CCRotateTo * rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-1.0];
        CCRotateTo * rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0];
        CCRotateTo * rotRight = [CCRotateBy actionWithDuration:0.1 angle:1.0];
        CCSequence * rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil];
        [touchSprite runAction:[CCRepeatForever actionWithAction:rotSeq]];            
        selSprite = touchSprite;
    }
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
    [self selectSpriteForTouch:touchLocation];   
    return TRUE;
}

Но когда я касаюсь верхних или нижних спрайтов, дрожит только нижний (он был добавлен первым в init).

Я думаю, что мне нужно заменить код CGRectContainsPoint(sprite.boundingBox, touchLocation), но я просто не знаю, как.

Я провел несколько ночей на форумах, но до сих пор не могу понять, как заставить топовый спрайт трястись ...

1 Ответ

0 голосов
/ 16 января 2012

Попробуйте что-то еще подобное (обратите внимание, что ccTouchesBegan не ccTouchBegan):

- (void)startShakingSprite:(CCSprite*)sprite {

    [sprite stopAllActions];
    [sprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]];
    CCRotateTo* rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-1.0];
    CCRotateTo* rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0];
    CCRotateTo* rotRight = [CCRotateBy actionWithDuration:0.1 angle:1.0];
    CCSequence* rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil];
    [sprite runAction:[CCRepeatForever actionWithAction:rotSeq]];  
}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent*)event {
    //get the touch
    UITouch* touch = [touches anyObject];
    //get its location
    CGPoint location = [touch locationInView:[touch view]];
    //convert location to cocos2d coordinates
    CGPoint point = CGPointMake(location.x, 480 - location.y);

    //now we go through your array of objects and see which contains the touch
    for(id sprite in draggableSprites) {
        if(CGRectContainsPoint(sprite.boundingBox, point)) {
            [self startShakingSprite:sprite];
        }
    }
}

Способ установки цикла for в selectSpriteForTouch приведет к тому, что будет выбран только первый объект в draggableSprites из-за вашего оператора break. С этим новым кодом каждый спрайт, ограничивающий прямоугольник, содержит анимацию. Код может быть не идеальным, потому что я набрал его прямо в Chrome, но вы поняли.

Еще одна важная вещь, которую стоит отметить, это то, что вы не можете запустить одно и то же действие на двух разных спрайтах, например:

id action = [CCScaleTo actionWithDuration:1 scale:1.0];
[someSprite runAction:action];
[someOtherSprite runAction:action];
[oneMoreSprite runAction:action];

Этот код не будет работать должным образом; только последний спрайт (oneMoreSprite) будет анимирован. Чтобы повторно использовать анимацию CC с несколькими спрайтами, используйте этот код:

id action = [CCScaleTo actionWithDuration:1 scale:1.0];
[someSprite runAction:action];
[someOtherSprite runAction:[[action copy] autorelease]];
[oneMoreSprite runAction:[[action copy] autorelease]];

Мы создаем копию действия, чтобы оно могло выполняться другим спрайтом (someOtherSprite, oneMoreSprite), не удаляя его из исходного спрайта, someSprite. Затем мы автоматически высвобождаем его, чтобы не было утечки памяти.

...