开发者

Applying Zoom Effect In cocos2D gaming environment?

I'm working on a game with c开发者_Go百科ocos2D game engine and make load all the sprites while it load the level, now as because some of sprites (obstacles) are taller than 320 pixel, thus it seems difficult to check them out. So for the convenience sake I want to apply ZOOM IN and ZOOM out effect, which minimizes entire level's all sprites at once, and in zoom out case these will resided to there old position.

Can I achieve this?

If yes, then how?

Please tell about pinch zoom also.


Zooming, is fairly simple, simply set the scale property of your main game layer... but there are a few catches.

When you scale the layer, it will shift the position of the layer. It won't automatically zoom towards the center of what you're currently looking at. If you have any type of scrolling in your game, you'll need to account for this.

To do this, set the anchorPoint of your layer to ccp(0.0f, 0.0f), and then calculate how much your layer has shifted, and reposition it accordingly.

- (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);
}

Pinch zoom is easier... just detect the touchesMoved, and then call your scaling routine.

- (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];
    }    
}


If all the sprites have the same parent you can just scale their parent and they will be scaled with it, keeping their coordinates relative to the parent.


this code scale my Layer by 2 to specific location

    [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);


My code and it works better than other ones:

- (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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜