Add files via upload
This commit is contained in:
128
java/com/example/ex4/Joystick.java
Normal file
128
java/com/example/ex4/Joystick.java
Normal file
@@ -0,0 +1,128 @@
|
||||
package com.example.ex4;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
|
||||
public class Joystick extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener {
|
||||
|
||||
private float centerX;
|
||||
private float centerY;
|
||||
private float baseRadius;
|
||||
private float hatRadius;
|
||||
private JoystickListener joystickCallback;
|
||||
//CTOR
|
||||
public Joystick(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
getHolder().addCallback(this);
|
||||
setOnTouchListener(this);
|
||||
if (context instanceof JoystickListener)
|
||||
joystickCallback = (JoystickListener) context;
|
||||
}
|
||||
//CTOR
|
||||
public Joystick(Context context, AttributeSet attrs, int defStyleAttr)
|
||||
{
|
||||
super(context, attrs, defStyleAttr);
|
||||
getHolder().addCallback(this);
|
||||
setOnTouchListener(this);
|
||||
if (context instanceof JoystickListener)
|
||||
joystickCallback = (JoystickListener) context;
|
||||
}
|
||||
//CTOR
|
||||
public Joystick(Context context)
|
||||
{
|
||||
super(context);
|
||||
getHolder().addCallback(this);
|
||||
setOnTouchListener(this);
|
||||
if (context instanceof JoystickListener)
|
||||
joystickCallback = (JoystickListener) context;
|
||||
}
|
||||
//instantiate dimenstions for drawing the Joystick
|
||||
private void setupDimensions()
|
||||
{
|
||||
centerX = getWidth() / 2;
|
||||
centerY = getHeight() / 2;
|
||||
baseRadius = Math.min(getWidth(), getHeight()) / 3;
|
||||
hatRadius = Math.min(getWidth(), getHeight()) / 5;
|
||||
}
|
||||
//method to be called when Joystick surface is created
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder surfaceHolder)
|
||||
{
|
||||
setupDimensions();
|
||||
drawJoystick(centerX, centerY);
|
||||
}
|
||||
//method to be called when Joystick surface is changed
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2)
|
||||
{
|
||||
setupDimensions();
|
||||
drawJoystick(centerX,centerY);
|
||||
}
|
||||
//method to be called when Joystick sutface is destroyed
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder)
|
||||
{
|
||||
UserHandler.getInstance().disconnect();
|
||||
}
|
||||
/*when Joystick is touched, method will be called and will compute values to be sent as
|
||||
* arguments to the JoystickCallBack onJoystickMoved even handler*/
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event)
|
||||
{
|
||||
if (view.equals(this))
|
||||
{
|
||||
if (event.getAction() != MotionEvent.ACTION_UP)
|
||||
{
|
||||
float displacement = (float) Math.sqrt((Math.pow(event.getX() - centerX, 2)) +
|
||||
Math.pow(event.getY() - centerY, 2));
|
||||
if (displacement < baseRadius)
|
||||
{
|
||||
drawJoystick(event.getX(), event.getY());
|
||||
joystickCallback.onJoystickMoved((centerX - event.getX()) / baseRadius,
|
||||
(event.getY() - centerY) / baseRadius, getId());
|
||||
}
|
||||
else {
|
||||
float ratio = baseRadius / displacement;
|
||||
float constrainedX = centerX + (event.getX() - centerX) * ratio;
|
||||
float constrainedY = centerY + (event.getY() - centerY) * ratio;
|
||||
drawJoystick(constrainedX, constrainedY);
|
||||
joystickCallback.onJoystickMoved((constrainedX - centerX) / baseRadius,
|
||||
(centerY - constrainedY) / baseRadius, getId());
|
||||
}
|
||||
} else {
|
||||
drawJoystick(centerX, centerY);
|
||||
joystickCallback.onJoystickMoved(0, 0, getId());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//draw the Joystick
|
||||
private void drawJoystick(float x, float y)
|
||||
{
|
||||
if (getHolder().getSurface().isValid())
|
||||
{
|
||||
Canvas drawCanvas = this.getHolder().lockCanvas();
|
||||
Paint colors = new Paint();
|
||||
drawCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
|
||||
colors.setARGB(255, 50, 50, 50);
|
||||
drawCanvas.drawCircle(centerX, centerY, baseRadius, colors);
|
||||
colors.setARGB(255, 0, 0, 255);
|
||||
drawCanvas.drawCircle(x, y, hatRadius, colors);
|
||||
getHolder().unlockCanvasAndPost(drawCanvas);
|
||||
}
|
||||
}
|
||||
//inteface defining the onJoystickMoved event handler
|
||||
public interface JoystickListener
|
||||
{
|
||||
void onJoystickMoved(float xPercent, float yPercent, int source);
|
||||
}
|
||||
}
|
||||
21
java/com/example/ex4/JoystickActivity.java
Normal file
21
java/com/example/ex4/JoystickActivity.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.example.ex4;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class JoystickActivity extends AppCompatActivity implements Joystick.JoystickListener
|
||||
{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_joystick);
|
||||
}
|
||||
//method to handle OnJoystickMoved event
|
||||
public void onJoystickMoved(float xPercent, float yPercent, int source)
|
||||
{
|
||||
UserHandler handler = UserHandler.getInstance();
|
||||
handler.send_message(true, xPercent); //true is aileron
|
||||
handler.send_message(false, yPercent); //false is elevator
|
||||
}
|
||||
}
|
||||
30
java/com/example/ex4/MainActivity.java
Normal file
30
java/com/example/ex4/MainActivity.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.example.ex4;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements View.OnClickListener
|
||||
{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
//assign the onClick as the one to be executed once the connect button is pressed
|
||||
Button connect_button = findViewById(R.id.connect_button);
|
||||
connect_button.setOnClickListener(this);
|
||||
}
|
||||
//onClick method of the connect button
|
||||
public void onClick(View view)
|
||||
{
|
||||
EditText[] values = new EditText[]{findViewById(R.id.ip_val),findViewById(R.id.port_val)};
|
||||
UserHandler.getInstance().connect(values[0].getText().toString(),
|
||||
Integer.parseInt(values[1].getText().toString()));
|
||||
startActivity(new Intent(this, JoystickActivity.class));
|
||||
}
|
||||
}
|
||||
109
java/com/example/ex4/UserHandler.java
Normal file
109
java/com/example/ex4/UserHandler.java
Normal file
@@ -0,0 +1,109 @@
|
||||
package com.example.ex4;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
public class UserHandler
|
||||
{
|
||||
private String aileron_path;
|
||||
private String elevator_path;
|
||||
private volatile String connection_ip;
|
||||
private volatile int connection_port;
|
||||
private volatile boolean stop;
|
||||
private volatile String message;
|
||||
private Thread message_thread;
|
||||
//static instance to be returned by getInstance()
|
||||
private static UserHandler instance = null;
|
||||
//get instance of the this singleton UserHandler
|
||||
public static UserHandler getInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = new UserHandler();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
//CTOR
|
||||
private UserHandler()
|
||||
{
|
||||
aileron_path = "/controls/flight/aileron";
|
||||
elevator_path = "/controls/flight/elevator";
|
||||
connection_ip = null;
|
||||
connection_port = 0;
|
||||
stop = false;
|
||||
message = null;
|
||||
message_thread = null;
|
||||
}
|
||||
//connect to FlightGear simulator
|
||||
public void connect(String ip, int port)
|
||||
{
|
||||
connection_ip = ip;
|
||||
connection_port = port;
|
||||
message_thread = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Socket sock = null;
|
||||
PrintWriter writer = null;
|
||||
try
|
||||
{
|
||||
sock = new Socket(InetAddress.getByName(connection_ip), connection_port);
|
||||
writer = new PrintWriter(new BufferedWriter((new OutputStreamWriter(sock.getOutputStream()))), true);
|
||||
//wait for message to send...
|
||||
while (!stop)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (message != null) {
|
||||
writer.print(message);
|
||||
message = null; }
|
||||
}
|
||||
}
|
||||
sock.close();
|
||||
sock = null;
|
||||
writer.close();
|
||||
writer = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (sock != null) { try { sock.close(); } catch (Exception ex) { ex.printStackTrace(); }}
|
||||
if (writer != null) { writer.close(); }
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
message_thread.start();
|
||||
}
|
||||
//disconnect from FlightGear simulator
|
||||
public void disconnect()
|
||||
{
|
||||
stop = true;
|
||||
try
|
||||
{
|
||||
message_thread.join();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
//send message to FlightGear
|
||||
public void send_message(boolean aileron, float val)
|
||||
{
|
||||
String aileron_or_elevator = elevator_path;
|
||||
if (aileron)
|
||||
{
|
||||
aileron_or_elevator = aileron_path;
|
||||
}
|
||||
synchronized (this)
|
||||
{
|
||||
message = "set " + aileron_or_elevator + " " + Float.toString(val) + " \r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user