package org.andengine.engine.camera.hud.controls; import org.andengine.engine.camera.Camera; import org.andengine.opengl.texture.region.ITextureRegion; import org.andengine.opengl.vbo.VertexBufferObjectManager; import org.andengine.util.math.MathUtils; /** * (c) 2010 Nicolas Gramlich * (c) 2011 Zynga Inc. * * @author Nicolas Gramlich * @since 00:21:55 - 11.07.2010 */ public class DigitalOnScreenControl extends BaseOnScreenControl { // =========================================================== // Constants // =========================================================== private static final float EXTENT_SIDE = 0.5f; private static final float EXTENT_DIAGONAL = 0.354f; private static final float ANGLE_DELTA = 22.5f; // =========================================================== // Fields // =========================================================== private boolean mAllowDiagonal; // =========================================================== // Constructors // =========================================================== public DigitalOnScreenControl(final float pX, final float pY, final Camera pCamera, final ITextureRegion pControlBaseTextureRegion, final ITextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final VertexBufferObjectManager pVertexBufferObjectManager, final IOnScreenControlListener pOnScreenControlListener) { this(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, false, pVertexBufferObjectManager, pOnScreenControlListener); } public DigitalOnScreenControl(final float pX, final float pY, final Camera pCamera, final ITextureRegion pControlBaseTextureRegion, final ITextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final boolean pAllowDiagonal, final VertexBufferObjectManager pVertexBufferObjectManager, final IOnScreenControlListener pOnScreenControlListener) { super(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, pVertexBufferObjectManager, pOnScreenControlListener); this.mAllowDiagonal = pAllowDiagonal; } // =========================================================== // Getter & Setter // =========================================================== public boolean isAllowDiagonal() { return this.mAllowDiagonal; } public void setAllowDiagonal(final boolean pAllowDiagonal) { this.mAllowDiagonal = pAllowDiagonal; } // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override protected void onUpdateControlKnob(final float pRelativeX, final float pRelativeY) { if(pRelativeX == 0 && pRelativeY == 0) { super.onUpdateControlKnob(0, 0); return; } if(this.mAllowDiagonal) { final float angle = MathUtils.radToDeg(MathUtils.atan2(pRelativeY, pRelativeX)) + 180; if(DigitalOnScreenControl.testDiagonalAngle(0, angle) || DigitalOnScreenControl.testDiagonalAngle(360, angle)) { super.onUpdateControlKnob(-EXTENT_SIDE, 0); } else if(DigitalOnScreenControl.testDiagonalAngle(45, angle)) { super.onUpdateControlKnob(-EXTENT_DIAGONAL, -EXTENT_DIAGONAL); } else if(DigitalOnScreenControl.testDiagonalAngle(90, angle)) { super.onUpdateControlKnob(0, -EXTENT_SIDE); } else if(DigitalOnScreenControl.testDiagonalAngle(135, angle)) { super.onUpdateControlKnob(EXTENT_DIAGONAL, -EXTENT_DIAGONAL); } else if(DigitalOnScreenControl.testDiagonalAngle(180, angle)) { super.onUpdateControlKnob(EXTENT_SIDE, 0); } else if(DigitalOnScreenControl.testDiagonalAngle(225, angle)) { super.onUpdateControlKnob(EXTENT_DIAGONAL, EXTENT_DIAGONAL); } else if(DigitalOnScreenControl.testDiagonalAngle(270, angle)) { super.onUpdateControlKnob(0, EXTENT_SIDE); } else if(DigitalOnScreenControl.testDiagonalAngle(315, angle)) { super.onUpdateControlKnob(-EXTENT_DIAGONAL, EXTENT_DIAGONAL); } else { super.onUpdateControlKnob(0, 0); } } else { if(Math.abs(pRelativeX) > Math.abs(pRelativeY)) { if(pRelativeX > 0) { super.onUpdateControlKnob(EXTENT_SIDE, 0); } else if(pRelativeX < 0) { super.onUpdateControlKnob(-EXTENT_SIDE, 0); } else if(pRelativeX == 0) { super.onUpdateControlKnob(0, 0); } } else { if(pRelativeY > 0) { super.onUpdateControlKnob(0, EXTENT_SIDE); } else if(pRelativeY < 0) { super.onUpdateControlKnob(0, -EXTENT_SIDE); } else if(pRelativeY == 0) { super.onUpdateControlKnob(0, 0); } } } } private static boolean testDiagonalAngle(final float pTestAngle, final float pActualAngle) { return pActualAngle > pTestAngle - ANGLE_DELTA && pActualAngle < pTestAngle + ANGLE_DELTA; } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== }