/** * Copyright 2008 - 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.3.3 */ package loon.component; import loon.LSystem; import loon.LTexture; import loon.LTextures; import loon.action.map.Config; import loon.component.skin.ControlSkin; import loon.event.SysTouch; import loon.opengl.GLEx; import loon.utils.MathUtils; /** * 内置的滑杆控制器,用以操作八方向行走等 */ public class LControl extends LComponent { public static interface DigitalListener { public void up(); public void down(); public void left(); public void right(); public void up45(); public void down45(); public void left45(); public void right45(); } public DigitalListener control; private static final float SIDE = 0.5f; private static final float DIAGONAL = 0.354f; private LTexture controlBase; private LTexture controlDot; private int baseWidth, baseHeight; private int dotWidth, dotHeight; private float centerX, centerY; private boolean allowDiagonal; public LControl(int x, int y) { this(x, y, 128, 128, 64, 64); } public LControl(int x, int y, int bw, int bh, int dw, int dh) { this(x, y, LTextures.loadTexture(LSystem.FRAMEWORK_IMG_NAME + "control_base.png"), LTextures .loadTexture(LSystem.FRAMEWORK_IMG_NAME + "control_dot.png"), bw, bh, dw, dh); } public LControl(int x, int y, String basename, String dot, int bw, int bh, int dw, int dh) { this(x, y, LTextures.loadTexture(basename), LTextures.loadTexture(dot), bw, bh, dw, dh); } public LControl(ControlSkin skin, int x, int y, int bw, int bh, int dw, int dh) { this(x, y, skin.getControlBaseTexture(), skin.getControlDotTexture(), bw, bh, dw, dh); } public LControl(int x, int y, LTexture basefile, LTexture dot, int bw, int bh, int dw, int dh) { super(x, y, bw, bh); this.controlBase = basefile; this.controlDot = dot; this.baseWidth = bw; this.baseHeight = bh; this.dotWidth = dw; this.dotHeight = dh; this.allowDiagonal = true; this.centerOffset(); } public boolean isAllowDiagonal() { return this.allowDiagonal; } public void setAllowDiagonal(final boolean a) { this.allowDiagonal = a; } private void centerOffset() { this.centerX = (baseWidth - dotWidth) / 2f + 1f; this.centerY = (baseHeight - dotHeight) / 2f + 1f; } @Override public void processTouchPressed() { final float relativeX = MathUtils.bringToBounds(0, baseWidth, SysTouch.getX() - getScreenX()) / baseWidth - 0.5f; final float relativeY = MathUtils.bringToBounds(0, baseHeight, SysTouch.getY() - getScreenY()) / baseHeight - 0.5f; onUpdateControlDot(relativeX, relativeY); } @Override public void processTouchReleased() { centerOffset(); } private void position(final float x, final float y, final int direction) { this.centerX = dotWidth * 0.5f + x * baseWidth; this.centerY = dotHeight * 0.5f + y * baseHeight; if (control != null) { switch (direction) { case Config.TUP: control.up(); break; case Config.UP: control.up45(); break; case Config.TRIGHT: control.right(); break; case Config.RIGHT: control.right45(); break; case Config.TDOWN: control.down(); break; case Config.DOWN: control.down45(); break; case Config.TLEFT: control.left(); break; case Config.LEFT: control.left45(); break; default: break; } } } private void onUpdateControlDot(final float x, final float y) { if (x == 0 && y == 0) { position(0, 0, Config.EMPTY); return; } if (this.allowDiagonal) { final float angle = MathUtils.toDegrees(MathUtils.atan2(x, y)) + 180; if (LSystem.checkAngle(0, angle) || LSystem.checkAngle(360, angle)) { position(0, -SIDE, Config.TUP); } else if (LSystem.checkAngle(45, angle)) { position(-DIAGONAL, -DIAGONAL, Config.LEFT); } else if (LSystem.checkAngle(90, angle)) { position(-SIDE, 0, Config.TLEFT); } else if (LSystem.checkAngle(135, angle)) { position(-DIAGONAL, DIAGONAL, Config.DOWN); } else if (LSystem.checkAngle(180, angle)) { position(0, SIDE, Config.TDOWN); } else if (LSystem.checkAngle(225, angle)) { position(DIAGONAL, DIAGONAL, Config.RIGHT); } else if (LSystem.checkAngle(270, angle)) { position(SIDE, 0, Config.TRIGHT); } else if (LSystem.checkAngle(315, angle)) { position(DIAGONAL, -DIAGONAL, Config.UP); } else { position(0, 0, Config.EMPTY); } } else { if (MathUtils.abs(x) > MathUtils.abs(y)) { if (x > 0) { position(SIDE, 0, Config.RIGHT); } else if (x < 0) { position(-SIDE, 0, Config.LEFT); } else if (x == 0) { position(0, 0, Config.EMPTY); } } else { if (y > 0) { position(0, SIDE, Config.DOWN); } else if (y < 0) { position(0, -SIDE, Config.UP); } else if (y == 0) { position(0, 0, Config.EMPTY); } } } } @Override public void createUI(GLEx g, int x, int y, LComponent component, LTexture[] buttonImage) { if (visible) { g.setAlpha(0.5f); g.draw(controlBase, x, y, baseWidth, baseHeight); g.draw(controlDot, x + centerX, y + centerY, dotWidth, dotHeight); g.setAlpha(1f); } } @Override public void close() { super.close(); if (controlBase != null) { controlBase.close(); controlBase = null; } if (controlDot != null) { controlDot.close(); controlDot = null; } } @Override public String getUIName() { return "Control"; } public DigitalListener getDigitalListener() { return control; } public void setControl(DigitalListener c) { this.control = c; } }