Zastosowanie efektu powiększenia w środowisku gier cocos2D?

Pracuję nad grą z cocos2D silnik gry i załadować wszystkie sprites Podczas ładowania poziomu, teraz, ponieważ niektóre z sprites (przeszkody) są wyższe niż 320 pikseli, więc wydaje się, że trudno je sprawdzić. Tak więc dla wygody chcę zastosować efekt ZOOM IN i ZOOM out, który minimalizuje wszystkie sprity całego poziomu na raz, a w przypadku pomniejszenia będą one rezydowały w starej pozycji.

Czy Mogę to osiągnąć?

Jeśli tak, to jak?

Please tell about pinch zoom też.

Author: rptwsthi, 2011-05-07

4 answers

Powiększanie, jest dość proste, wystarczy ustawić właściwość skali głównej warstwy gry... ale jest kilka haczyków.

Gdy skalujesz warstwę, przesunie ona jej położenie. Nie spowoduje automatycznego powiększenia w kierunku środka tego, na co aktualnie patrzysz. Jeśli masz jakiś rodzaj przewijania w grze, musisz to uwzględnić.

Aby to zrobić, ustaw anchorPoint swojej warstwy na ccp(0.0f, 0.0f), a następnie oblicz, jak bardzo przesunięta jest twoja warstwa i zmień jej położenie odpowiednio.
- (void) scale:(CGFloat) newScale scaleCenter:(CGPoint) scaleCenter {
    // scaleCenter is the point to zoom to.. 
    // If you are doing a pinch zoom, this should be the center of your pinch.

    // Get the original center point.
    CGPoint oldCenterPoint = ccp(scaleCenter.x * yourLayer.scale, scaleCenter.y * yourLayer.scale); 

    // Set the scale.
    yourLayer.scale = newScale;

    // Get the new center point.
    CGPoint newCenterPoint = ccp(scaleCenter.x * yourLayer.scale, scaleCenter.y * yourLayer.scale); 

    // Then calculate the delta.
    CGPoint centerPointDelta  = ccpSub(oldCenterPoint, newCenterPoint);

    // Now adjust your layer by the delta.
    yourLayer.position = ccpAdd(yourLayer.position, centerPointDelta);
}
Zbliżenie jest łatwiejsze... po prostu Wykryj dotyk, a następnie zadzwoń do swojej procedury skalowania.
- (void) ccTouchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {

    // Examine allTouches instead of just touches.  Touches tracks only the touch that is currently moving...
    //   But stationary touches still trigger a multi-touch gesture.
    NSArray* allTouches = [[event allTouches] allObjects];

    if ([allTouches count] == 2) {            
        // Get two of the touches to handle the zoom
        UITouch* touchOne = [allTouches objectAtIndex:0];
        UITouch* touchTwo = [allTouches objectAtIndex:1];

        // Get the touches and previous touches.
        CGPoint touchLocationOne = [touchOne locationInView: [touchOne view]];
        CGPoint touchLocationTwo = [touchTwo locationInView: [touchTwo view]];  

        CGPoint previousLocationOne = [touchOne previousLocationInView: [touchOne view]];
        CGPoint previousLocationTwo = [touchTwo previousLocationInView: [touchTwo view]];

        // Get the distance for the current and previous touches.
        CGFloat currentDistance = sqrt(
                                       pow(touchLocationOne.x - touchLocationTwo.x, 2.0f) + 
                                       pow(touchLocationOne.y - touchLocationTwo.y, 2.0f));

        CGFloat previousDistance = sqrt(
                                        pow(previousLocationOne.x - previousLocationTwo.x, 2.0f) + 
                                        pow(previousLocationOne.y - previousLocationTwo.y, 2.0f));

        // Get the delta of the distances.
        CGFloat distanceDelta = currentDistance - previousDistance;

        // Next, position the camera to the middle of the pinch.
        // Get the middle position of the pinch.
        CGPoint pinchCenter = ccpMidpoint(touchLocationOne, touchLocationTwo);

        // Then, convert the screen position to node space... use your game layer to do this.
        pinchCenter = [yourLayer convertToNodeSpace:pinchCenter];

        // Finally, call the scale method to scale by the distanceDelta, pass in the pinch center as well.
        // Also, multiply the delta by PINCH_ZOOM_MULTIPLIER to slow down the scale speed.      
        // A PINCH_ZOOM_MULTIPLIER of 0.005f works for me, but experiment to find one that you like.
        [self scale:yourlayer.scale - (distanceDelta * PINCH_ZOOM_MULTIPLIER)
            scaleCenter:pinchCenter];
    }    
}
 27
Author: Michael Fredrickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-12 16:06:50

Jeśli wszystkie sprite ' y mają ten sam rodzic, możesz po prostu przeskalować ich rodzica i będą skalowane z nim, zachowując ich współrzędne względem rodzica.

 1
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-07 14:16:23

Ten kod skaluje moją warstwę o 2 do określonej lokalizacji

    [layer setScale:2];
    layer.position=ccp(240/2+40,160*1.5);
    double dx=(touchLocation.x*2-240);
    double dy=(touchLocation.y*2-160);
    layer.position=ccp(inGamePlay.position.x-dx,inGamePlay.position.y-dy);
 0
Author: mohammad alabid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-07 19:55:55

Mój kod i działa lepiej niż inne:

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

    NSArray* allTouches = [[event allTouches] allObjects];
    CCLayer *gameField = (CCLayer *)[self getChildByTag:TAG_GAMEFIELD];
    if (allTouches.count == 2) {

        UIView *v = [[CCDirector sharedDirector] view];
        UITouch *tOne = [allTouches objectAtIndex:0];
        UITouch *tTwo = [allTouches objectAtIndex:1];
        CGPoint firstTouch = [tOne locationInView:v];
        CGPoint secondTouch = [tTwo locationInView:v];
        CGPoint oldFirstTouch = [tOne previousLocationInView:v];
        CGPoint oldSecondTouch = [tTwo previousLocationInView:v];
        float oldPinchDistance = ccpDistance(oldFirstTouch, oldSecondTouch);
        float newPinchDistance = ccpDistance(firstTouch, secondTouch);

        float distanceDelta = newPinchDistance - oldPinchDistance;
        NSLog(@"%f", distanceDelta);
        CGPoint pinchCenter = ccpMidpoint(firstTouch, secondTouch);
        pinchCenter = [gameField convertToNodeSpace:pinchCenter];

        gameField.scale = gameField.scale - distanceDelta / 100;
        if (gameField.scale < 0) {

            gameField.scale = 0;
        }
    }
}
 0
Author: user2083364,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-25 09:11:40