# AndEngine - Smooth scaling on a sprite

I'm trying to implement a pinch zoom on a sprite. I would like to get an effect like the SmoothCamera, but on a single sprite. I've managed to pinch zoom on the sprite by changing its scale, but the zoom is really fast and not smooth... it doesn't feel right.

This code is on my sprite :

public class BoardSprite extends Sprite implements IPinchZoomDetectorListener {
...
private float scale = 1;
@Override
public void onPinchZoom(PinchZoomDetector pPinchZoomDetector,
TouchEvent pTouchEvent, float pZoomFactor) {
float newScale = scale * pZoomFactor;
if (newScale > 3) {
newScale = 3;
} else if ( newScale < 1) {
newScale = 1;
}

scale = newScale;
this.setScale(newScale);
}


I'm looking for a way to improve this solution or for a better approach.

• Just curious: what if you tried float newScale = pZoomFactor; -- what effect would that produce? – Thomas Jan 20 '14 at 13:54
• That's actually pretty good, the only problem is that it seems to start back to 1 each time I start a new pinch. I'll have a look at it later today. – Phil-R Jan 21 '14 at 14:14

I have no experience with AndEngine, but from your code I suspect that since you update the scale variable with the result of scale * pZoomFactor every time onPinchZoom is called, you're basically turning this multiplication into an exponentiation.

To avoid this, simply delete the scale = newScale; assignment. But now, since you want to compute the scale relative to the scale at the beginning of the pinch zoom, you have to add a method that initializes scale to that value. The following might work:

private float scale = 1;

@Override
public void onPinchZoomStarted(PinchZoomDetector pPinchZoomDetector,
TouchEvent pSceneTouchEvent) {
this.scale = Math.min(getScaleX(), getScaleY());
}

@Override
public void onPinchZoom(PinchZoomDetector pPinchZoomDetector,
TouchEvent pTouchEvent, float pZoomFactor) {
float newScale = scale * pZoomFactor;
if (newScale > 3) {
newScale = 3;
} else if (newScale < 1) {
newScale = 1;
}

// scale = newScale;
this.setScale(newScale);
}


Try setting a target scale, then ease towards that value, rather than setting the value directly. This is how the pinch zoom works in Angry Birds. It eases in over time.

The basic method is to increase the scale of your sprite by a fraction of the difference between the target scale and the current scale each update.

float easeRate = 0.01; // Higher for faster easing;