package org.anddev.andengine.engine.camera; /** * (c) 2010 Nicolas Gramlich * (c) 2011 Zynga Inc. * * @author Nicolas Gramlich * @since 15:55:54 - 27.07.2010 */ public class BoundCamera extends Camera { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== protected boolean mBoundsEnabled; private float mBoundsMinX; private float mBoundsMaxX; private float mBoundsMinY; private float mBoundsMaxY; private float mBoundsCenterX; private float mBoundsCenterY; private float mBoundsWidth; private float mBoundsHeight; // =========================================================== // Constructors // =========================================================== public BoundCamera(final float pX, final float pY, final float pWidth, final float pHeight) { super(pX, pY, pWidth, pHeight); } public BoundCamera(final float pX, final float pY, final float pWidth, final float pHeight, final float pBoundMinX, final float pBoundMaxX, final float pBoundMinY, final float pBoundMaxY) { super(pX, pY, pWidth, pHeight); this.setBounds(pBoundMinX, pBoundMaxX, pBoundMinY, pBoundMaxY); this.mBoundsEnabled = true; } // =========================================================== // Getter & Setter // =========================================================== public boolean isBoundsEnabled() { return this.mBoundsEnabled; } public void setBoundsEnabled(final boolean pBoundsEnabled) { this.mBoundsEnabled = pBoundsEnabled; } public void setBounds(final float pBoundMinX, final float pBoundMaxX, final float pBoundMinY, final float pBoundMaxY) { this.mBoundsMinX = pBoundMinX; this.mBoundsMaxX = pBoundMaxX; this.mBoundsMinY = pBoundMinY; this.mBoundsMaxY = pBoundMaxY; this.mBoundsWidth = this.mBoundsMaxX - this.mBoundsMinX; this.mBoundsHeight = this.mBoundsMaxY - this.mBoundsMinY; this.mBoundsCenterX = this.mBoundsMinX + this.mBoundsWidth * 0.5f; this.mBoundsCenterY = this.mBoundsMinY + this.mBoundsHeight * 0.5f; } public float getBoundsWidth() { return this.mBoundsWidth; } public float getBoundsHeight() { return this.mBoundsHeight; } @Override public void setCenter(final float pCenterX, final float pCenterY) { super.setCenter(pCenterX, pCenterY); if(this.mBoundsEnabled) { this.ensureInBounds(); } } // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== // =========================================================== // Methods // =========================================================== protected void ensureInBounds() { super.setCenter(this.determineBoundedX(), this.determineBoundedY()); } private float determineBoundedX() { if(this.mBoundsWidth < this.getWidth()) { return this.mBoundsCenterX; } else { final float currentCenterX = this.getCenterX(); final float minXBoundExceededAmount = this.mBoundsMinX - this.getMinX(); final boolean minXBoundExceeded = minXBoundExceededAmount > 0; final float maxXBoundExceededAmount = this.getMaxX() - this.mBoundsMaxX; final boolean maxXBoundExceeded = maxXBoundExceededAmount > 0; if(minXBoundExceeded) { if(maxXBoundExceeded) { /* Min and max X exceeded. */ return currentCenterX - maxXBoundExceededAmount + minXBoundExceededAmount; } else { /* Only min X exceeded. */ return currentCenterX + minXBoundExceededAmount; } } else { if(maxXBoundExceeded) { /* Only max X exceeded. */ return currentCenterX - maxXBoundExceededAmount; } else { /* Nothing exceeded. */ return currentCenterX; } } } } private float determineBoundedY() { if(this.mBoundsHeight < this.getHeight()) { return this.mBoundsCenterY; } else { final float currentCenterY = this.getCenterY(); final float minYBoundExceededAmount = this.mBoundsMinY - this.getMinY(); final boolean minYBoundExceeded = minYBoundExceededAmount > 0; final float maxYBoundExceededAmount = this.getMaxY() - this.mBoundsMaxY; final boolean maxYBoundExceeded = maxYBoundExceededAmount > 0; if(minYBoundExceeded) { if(maxYBoundExceeded) { /* Min and max Y exceeded. */ return currentCenterY - maxYBoundExceededAmount + minYBoundExceededAmount; } else { /* Only min Y exceeded. */ return currentCenterY + minYBoundExceededAmount; } } else { if(maxYBoundExceeded) { /* Only max Y exceeded. */ return currentCenterY - maxYBoundExceededAmount; } else { /* Nothing exceeded. */ return currentCenterY; } } } } // =========================================================== // Inner and Anonymous Classes // =========================================================== }