package org.andengine.engine.camera;
/**
* (c) 2010 Nicolas Gramlich
* (c) 2011 Zynga Inc.
*
* @author Nicolas Gramlich
* @since 22:11:17 - 25.03.2010
*/
public class SmoothCamera extends ZoomCamera {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
protected float mMaxVelocityX;
protected float mMaxVelocityY;
protected float mMaxZoomFactorChange;
protected float mTargetCenterX;
protected float mTargetCenterY;
protected float mTargetZoomFactor;
// ===========================================================
// Constructors
// ===========================================================
public SmoothCamera(final float pX, final float pY, final float pWidth, final float pHeight, final float pMaxVelocityX, final float pMaxVelocityY, final float pMaxZoomFactorChange) {
super(pX, pY, pWidth, pHeight);
this.mMaxVelocityX = pMaxVelocityX;
this.mMaxVelocityY = pMaxVelocityY;
this.mMaxZoomFactorChange = pMaxZoomFactorChange;
this.mTargetCenterX = this.getCenterX();
this.mTargetCenterY = this.getCenterY();
this.mTargetZoomFactor = 1.0f;
}
// ===========================================================
// Getter & Setter
// ===========================================================
public float getTargetCenterX() {
return this.mTargetCenterX;
}
public float getTargetCenterY() {
return this.mTargetCenterY;
}
public float getTargetZoomFactor() {
return this.mTargetZoomFactor;
}
@Override
public void setCenter(final float pCenterX, final float pCenterY) {
this.mTargetCenterX = pCenterX;
this.mTargetCenterY = pCenterY;
}
public void setCenterDirect(final float pCenterX, final float pCenterY) {
super.setCenter(pCenterX, pCenterY);
this.mTargetCenterX = pCenterX;
this.mTargetCenterY = pCenterY;
}
@Override
public void setZoomFactor(final float pZoomFactor) {
if(this.mTargetZoomFactor != pZoomFactor) {
if(this.mTargetZoomFactor == this.mZoomFactor) {
this.mTargetZoomFactor = pZoomFactor;
this.onSmoothZoomStarted();
} else {
this.mTargetZoomFactor = pZoomFactor;
}
}
}
public void setZoomFactorDirect(final float pZoomFactor) {
if(this.mTargetZoomFactor != this.mZoomFactor) {
this.mTargetZoomFactor = pZoomFactor;
super.setZoomFactor(pZoomFactor);
this.onSmoothZoomFinished();
} else {
this.mTargetZoomFactor = pZoomFactor;
super.setZoomFactor(pZoomFactor);
}
}
public float getMaxVelocityX() {
return this.mMaxVelocityX;
}
public void setMaxVelocityX(final float pMaxVelocityX) {
this.mMaxVelocityX = pMaxVelocityX;
}
public float getMaxVelocityY() {
return this.mMaxVelocityY;
}
public void setMaxVelocityY(final float pMaxVelocityY) {
this.mMaxVelocityY = pMaxVelocityY;
}
public void setMaxVelocity(final float pMaxVelocityX, final float pMaxVelocityY) {
this.mMaxVelocityX = pMaxVelocityX;
this.mMaxVelocityY = pMaxVelocityY;
}
public float getMaxZoomFactorChange() {
return this.mMaxZoomFactorChange;
}
public void setMaxZoomFactorChange(final float pMaxZoomFactorChange) {
this.mMaxZoomFactorChange = pMaxZoomFactorChange;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
protected void onSmoothZoomStarted() {
}
protected void onSmoothZoomFinished() {
}
@Override
public void onUpdate(final float pSecondsElapsed) {
super.onUpdate(pSecondsElapsed);
/* Update center. */
final float currentCenterX = this.getCenterX();
final float currentCenterY = this.getCenterY();
final float targetCenterX = this.mTargetCenterX;
final float targetCenterY = this.mTargetCenterY;
if(currentCenterX != targetCenterX || currentCenterY != targetCenterY) {
final float diffX = targetCenterX - currentCenterX;
final float dX = this.limitToMaxVelocityX(diffX, pSecondsElapsed);
final float diffY = targetCenterY - currentCenterY;
final float dY = this.limitToMaxVelocityY(diffY, pSecondsElapsed);
super.setCenter(currentCenterX + dX, currentCenterY + dY);
}
/* Update zoom. */
final float currentZoom = this.getZoomFactor();
final float targetZoomFactor = this.mTargetZoomFactor;
if(currentZoom != targetZoomFactor) {
final float absoluteZoomDifference = targetZoomFactor - currentZoom;
final float zoomChange = this.limitToMaxZoomFactorChange(absoluteZoomDifference, pSecondsElapsed);
super.setZoomFactor(currentZoom + zoomChange);
if(this.mZoomFactor == this.mTargetZoomFactor) {
this.onSmoothZoomFinished();
}
}
}
private float limitToMaxVelocityX(final float pValue, final float pSecondsElapsed) {
if(pValue > 0) {
return Math.min(pValue, this.mMaxVelocityX * pSecondsElapsed);
} else {
return Math.max(pValue, -this.mMaxVelocityX * pSecondsElapsed);
}
}
private float limitToMaxVelocityY(final float pValue, final float pSecondsElapsed) {
if(pValue > 0) {
return Math.min(pValue, this.mMaxVelocityY * pSecondsElapsed);
} else {
return Math.max(pValue, -this.mMaxVelocityY * pSecondsElapsed);
}
}
private float limitToMaxZoomFactorChange(final float pValue, final float pSecondsElapsed) {
if(pValue > 0) {
return Math.min(pValue, this.mMaxZoomFactorChange * pSecondsElapsed);
} else {
return Math.max(pValue, -this.mMaxZoomFactorChange * pSecondsElapsed);
}
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}