package br.com.etyllica.core.input.joystick;
import br.com.etyllica.core.event.MouseEvent;
import br.com.etyllica.core.event.PointerEvent;
import br.com.etyllica.core.linear.Point2D;
import br.com.etyllica.layer.Layer;
public class TouchJoystick {
private static final int INACTIVE = -1;
private static final int DEFAULT_RADIUS = 120/2;
private static final int DEFAULT_JOYSTICK_RADIUS = 50/2;
protected Layer area;
protected Layer joystick;
protected int activeId = INACTIVE;
protected boolean active = false;
protected Point2D center;
protected Point2D joyPosition;
protected int radius = DEFAULT_RADIUS;
protected int joystickRadius = DEFAULT_JOYSTICK_RADIUS;
protected double dist = 0;
protected double angle = 0;
protected double sensitivityX = 0;
protected double sensitivityY = 0;
public TouchJoystick(int x, int y) {
this(x, y, DEFAULT_RADIUS, DEFAULT_JOYSTICK_RADIUS);
}
public TouchJoystick(int x, int y, int radius) {
this(x, y, radius, DEFAULT_JOYSTICK_RADIUS);
}
public TouchJoystick(int x, int y, int radius, int joystickRadius) {
super();
area = new Layer(x, y, radius * 2, radius * 2);
int cx = x + radius;
int cy = y + radius;
center = new Point2D(cx, cy);
joyPosition = new Point2D(cx, cy);
joystick = new Layer(cx - joystickRadius, cy - joystickRadius, joystickRadius * 2, joystickRadius * 2);
reset();
}
public Layer getArea() {
return area;
}
public Layer getJoystick() {
return joystick;
}
public void setActive(boolean active) {
this.active = active;
}
public void updateMouse(PointerEvent event) {
int mx = event.getX();
int my = event.getY();
if(event.isButtonDown(MouseEvent.MOUSE_BUTTON_LEFT)) {
if (activeId == INACTIVE) {
if (joystick.colideCirclePoint(mx, my)) {
activeId = event.getPointer();
setActive(true);
}
} else {
angle = center.angle(mx, my);
double radAngle = Math.toRadians(angle);
sensitivityX = Math.cos(radAngle);
sensitivityY = Math.sin(radAngle);
updateJoystickPosition(mx, my);
fixValues();
update();
}
} else if(event.isButtonUp(MouseEvent.MOUSE_BUTTON_LEFT)) {
//Release Joystick
if(active && event.getPointer() == activeId) {
setActive(false);
activeId = INACTIVE;
reset();
sensitivityX = 0;
sensitivityY = 0;
}
}
}
protected void update() {
}
private void updateJoystickPosition(int mx, int my) {
int jx = mx-joystickRadius;
int jy = my-joystickRadius;
joyPosition.setLocation(mx, my);
dist = joyPosition.distance(center);
if(dist < radius) {
joystick.setCoordinates(jx, jy);
} else {
double lx = sensitivityX*radius;
double ly = sensitivityY*radius;
joystick.setCoordinates((int)(center.getX()+lx-joystickRadius), (int)(center.getY()+ly-joystickRadius));
}
}
private void fixValues() {
sensitivityY = -sensitivityY;
if(angle < 0) {
angle = -angle;
} else {
angle = 180+(180-angle);
}
}
public void reset() {
joystick.setCoordinates((int)center.getX()-joystickRadius, (int)center.getY()-joystickRadius);
onReset();
}
protected void onReset() {
}
public double getSensitivityX() {
return sensitivityX;
}
public double getSensitivityY() {
return sensitivityY;
}
public double getAngle() {
return angle;
}
public boolean isActive() {
return active;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public int getJoystickRadius() {
return joystickRadius;
}
public void setJoystickRadius(int joystickRadius) {
this.joystickRadius = joystickRadius;
}
public Point2D getCenter() {
return center;
}
}