public class JoystickView extends SurfaceView
implements SurfaceHolder.
Callback,
View.
OnTouchListener {
private float centerX;
private float centerY;
private float baseRadius;
private float hatRadius;
private RightJoystickListener rightJoystickListener;
private LeftJoystickListener leftJoystickListener;
private void setupDimensions() {
centerX = getWidth() / 2;
centerY = getHeight() / 2;
baseRadius
= Math.
min(getWidth
(), getHeight
()) / 3;
hatRadius
= Math.
min(getWidth
(), getHeight
()) / 6;
}
public JoystickView
(Context context
) {
super(context);
getHolder().addCallback(this);
setOnTouchListener(this);
if(context instanceof RightJoystickListener) {
rightJoystickListener = (RightJoystickListener) context;
}
if(context instanceof LeftJoystickListener) {
leftJoystickListener = (LeftJoystickListener) context;
}
getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
super(context, attrs);
getHolder().addCallback(this);
setOnTouchListener(this);
if(context instanceof RightJoystickListener) {
rightJoystickListener = (RightJoystickListener) context;
}
if(context instanceof LeftJoystickListener) {
leftJoystickListener = (LeftJoystickListener) context;
}
getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
super(context, attrs, defStyleAttr);
getHolder().addCallback(this);
setOnTouchListener(this);
if(context instanceof RightJoystickListener) {
rightJoystickListener = (RightJoystickListener) context;
}
if(context instanceof LeftJoystickListener) {
leftJoystickListener = (LeftJoystickListener) context;
}
}
private void drawJoystick(float newX, float newY) {
if (getHolder().getSurface().isValid()) {
Canvas myCanvas
= this.
getHolder().
lockCanvas();
myCanvas.
drawColor(Color.
TRANSPARENT, PorterDuff.
Mode.
CLEAR);
colors.setARGB(100, 193, 193, 193);
myCanvas.drawCircle(centerX, centerY, baseRadius, colors);
colors.setARGB(255, 193, 193, 193);
myCanvas.drawCircle(newX, newY, hatRadius, colors);
getHolder().unlockCanvasAndPost(myCanvas);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
setupDimensions();
drawJoystick(centerX, centerY);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
public boolean onTouch
(View v, MotionEvent e
) {
if(v.equals(this)) {
if(e.getAction() != e.ACTION_UP) {
float displacement
= (float)Math.
sqrt((Math.
pow(e.
getX() - centerX,
2)) + Math.
pow(e.
getY() - centerY,
2));
if(displacement < baseRadius) {
drawJoystick(e.getX(), e.getY());
} else {
float ratio = baseRadius / displacement;
float constrainedX = centerX + (e.getX() - centerX) * ratio;
float constrainedY = centerY + (e.getY() - centerY) * ratio;
drawJoystick(constrainedX, constrainedY);
rightJoystickListener.onRightJoystickMoved(
(constrainedX - centerX) / baseRadius, (constrainedY - centerY) / baseRadius
, getId());
leftJoystickListener.onLeftJoystickMoved(
(constrainedX - centerX) / baseRadius, (constrainedY - centerY) / baseRadius
, getId());
}
} else {
drawJoystick(centerX, centerY);
leftJoystickListener.onLeftJoystickMoved(0,0, getId());
rightJoystickListener.onRightJoystickMoved(0,0, getId());
}
}
return true;
}
public interface RightJoystickListener {
void onRightJoystickMoved(float xPercent, float yPercent, int id);
}
public interface LeftJoystickListener {
void onLeftJoystickMoved(float xPercent, float yPercent, int id);
}
}