/* Copyright (C) 2013 Patrik Wållgren This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package bgsep.model; import java.util.Observable; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; /** * A superclass that handles joystick movements. * You should implement a subclass that overrides * onStickMovement() * @author Patrik * */ public abstract class Joystick extends Observable { private float prevPosX, prevPosY; private float startPosX, startPosY; private boolean enabled; private ImageView boundary, stick; /** * Takes a positioned boundary ImageView and a positioned * stick ImageView. Enabled by default. * @param boundary an ImageView */ public Joystick(ImageView boundary, ImageView stick) { prevPosX = prevPosY = 0; startPosX = boundary.getWidth()/2; startPosY = boundary.getHeight()/2; boundary.setOnTouchListener(new JoystickTouchEvent()); this.boundary = boundary; this.stick = stick; enabled = true; } private class JoystickTouchEvent implements OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { if(enabled) { switch(event.getAction()) { case MotionEvent.ACTION_MOVE: int maxTop, maxRight, maxBottom, maxLeft; maxTop = 0; maxRight = boundary.getWidth(); maxLeft = 0; maxBottom = boundary.getHeight(); if((event.getX() < maxLeft || event.getX() > maxRight) && (event.getY() > maxTop && event.getY() < maxBottom)) moveJoystick(prevPosX, event.getY()); else if((event.getY() < maxTop || event.getY() > maxBottom) && (event.getX() > maxLeft && event.getX() < maxRight)) moveJoystick(event.getX(), prevPosY); else if(!(event.getX() < maxLeft || event.getX() > maxRight || event.getY() < maxTop || event.getY() > maxBottom)) moveJoystick(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: prevPosX = startPosX; prevPosY = startPosY; onStickMovement(); break; default: break; } return true; } return false; } private void moveJoystick(float XPos, float YPos) { //Update previous position prevPosX = XPos; prevPosY = YPos; onStickMovement(); } } /** * Returns the X position of the stick where origo is the middle point in the * boundary * @return the X position of the stick */ public float getX() { return (prevPosX - startPosX) / (boundary.getWidth()/2); } /** * Returns the Y position of the stick where origo is the middle point in the * boundary * @return the Y position of the stick */ public float getY() { return (prevPosY - startPosY) / (boundary.getHeight()/2) * -1; } public boolean getEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public ImageView getBoundary() { return boundary; } public ImageView getStick() { return stick; } /** * Method to be overriden by subclasses when the user moves the stick */ abstract public void onStickMovement(); }