mirror of
https://github.com/etlegacy/JoyStick.git
synced 2024-11-24 21:11:15 +00:00
first commit
This commit is contained in:
commit
66126df543
37 changed files with 795 additions and 0 deletions
40
.gitignore
vendored
Normal file
40
.gitignore
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/libraries
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
|
||||||
|
#Android generated
|
||||||
|
bin
|
||||||
|
gen
|
||||||
|
|
||||||
|
#Eclipse
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.settings
|
||||||
|
|
||||||
|
#IntelliJ IDEA
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
classes
|
||||||
|
|
||||||
|
#Command line
|
||||||
|
build.xml
|
||||||
|
proguard-project.txt
|
||||||
|
|
||||||
|
#Mac specific
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
#User specific
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
#gradle
|
||||||
|
build
|
||||||
|
.gradle
|
||||||
|
gradle
|
||||||
|
gradlew
|
||||||
|
gradlew.bat
|
||||||
|
signing.properties
|
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
28
app/build.gradle
Normal file
28
app/build.gradle
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.erz.joystick"
|
||||||
|
minSdkVersion 11
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
compile 'com.android.support:appcompat-v7:23.1.0'
|
||||||
|
compile 'com.android.support:design:23.1.0'
|
||||||
|
compile project(':joysticklibrary')
|
||||||
|
}
|
17
app/proguard-rules.pro
vendored
Normal file
17
app/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /Users/edgarramirez/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.erz.joystick;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.test.ApplicationTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||||
|
*/
|
||||||
|
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||||
|
public ApplicationTest() {
|
||||||
|
super(Application.class);
|
||||||
|
}
|
||||||
|
}
|
24
app/src/main/AndroidManifest.xml
Normal file
24
app/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.erz.joystick">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar"
|
||||||
|
android:configChanges="orientation|screenSize">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
49
app/src/main/java/com/erz/joystick/GameLoop.java
Normal file
49
app/src/main/java/com/erz/joystick/GameLoop.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package com.erz.joystick;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by edgarramirez on 7/17/15.
|
||||||
|
*/
|
||||||
|
public class GameLoop extends Thread {
|
||||||
|
static final long FPS = 60;
|
||||||
|
static final long ticksPS = 1000 / FPS;
|
||||||
|
SurfaceView view;
|
||||||
|
boolean running = false;
|
||||||
|
long startTime;
|
||||||
|
long sleepTime;
|
||||||
|
Canvas canvas;
|
||||||
|
|
||||||
|
public GameLoop(SurfaceView view) {
|
||||||
|
this.view = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRunning(boolean run) {
|
||||||
|
running = run;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (running) {
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
canvas = view.getHolder().lockCanvas();
|
||||||
|
synchronized (view.getHolder()) {
|
||||||
|
view.draw(canvas);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (canvas != null) {
|
||||||
|
view.getHolder().unlockCanvasAndPost(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleepTime = ticksPS - (System.currentTimeMillis() - startTime);
|
||||||
|
try {
|
||||||
|
if (sleepTime > 0)
|
||||||
|
sleep(sleepTime);
|
||||||
|
else
|
||||||
|
sleep(10);
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
154
app/src/main/java/com/erz/joystick/GameView.java
Normal file
154
app/src/main/java/com/erz/joystick/GameView.java
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
package com.erz.joystick;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by edgarramirez on 6/15/15.
|
||||||
|
*/
|
||||||
|
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
|
||||||
|
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
float centerX;
|
||||||
|
float centerY;
|
||||||
|
float min;
|
||||||
|
float posX;
|
||||||
|
float posY;
|
||||||
|
float radius;
|
||||||
|
GameLoop gameLoop;
|
||||||
|
Paint paint;
|
||||||
|
Random random = new Random();
|
||||||
|
int i;
|
||||||
|
int size = 20;
|
||||||
|
int minSpeed;
|
||||||
|
int maxSpeed;
|
||||||
|
int minRadius;
|
||||||
|
int maxRadius;
|
||||||
|
int maxX;
|
||||||
|
int maxY;
|
||||||
|
int tmpRadius;
|
||||||
|
Bitmap droid;
|
||||||
|
RectF rectF;
|
||||||
|
float rotate;
|
||||||
|
|
||||||
|
double radians;
|
||||||
|
double power;
|
||||||
|
|
||||||
|
double radians2;
|
||||||
|
|
||||||
|
Vector<Star> stars;
|
||||||
|
|
||||||
|
public GameView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
getHolder().addCallback(this);
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
paint.setColor(Color.WHITE);
|
||||||
|
droid = BitmapFactory.decodeResource(getResources(), R.drawable.droid);
|
||||||
|
rectF = new RectF();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(@NonNull Canvas canvas) {
|
||||||
|
if (canvas == null) return;
|
||||||
|
super.draw(canvas);
|
||||||
|
canvas.drawColor(Color.BLACK);
|
||||||
|
|
||||||
|
if (stars != null && stars.size() > 0) {
|
||||||
|
for (i=0; i<size; i++) {
|
||||||
|
stars.get(i).draw(canvas, paint, width, height, maxRadius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
posX -= Math.cos(radians) * (power/2);
|
||||||
|
posY += Math.sin(-radians) * (power/2);
|
||||||
|
if (posX > width - radius) posX = width - radius;
|
||||||
|
if (posX < radius) posX = radius;
|
||||||
|
if (posY > height - radius) posY = height - radius;
|
||||||
|
if (posY < radius) posY = radius;
|
||||||
|
|
||||||
|
if (radians2 == 0) rotate = 0;
|
||||||
|
else rotate = (float) Math.toDegrees(radians2) - 90;
|
||||||
|
canvas.rotate(rotate, posX, posY);
|
||||||
|
rectF.set(posX - radius, posY - radius, posX + radius, posY + radius);
|
||||||
|
canvas.drawBitmap(droid, null, rectF, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
gameLoop = new GameLoop(this);
|
||||||
|
gameLoop.setRunning(true);
|
||||||
|
gameLoop.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
min = Math.min(width, height);
|
||||||
|
|
||||||
|
centerX = width/2;
|
||||||
|
centerY = height/2;
|
||||||
|
posX = centerX;
|
||||||
|
posY = centerY;
|
||||||
|
radius = min/12;
|
||||||
|
rectF = new RectF(posX - radius, posY - radius, posX + radius, posY + radius);
|
||||||
|
|
||||||
|
minSpeed = (int) (min/75);
|
||||||
|
maxSpeed = (int) (min/25);
|
||||||
|
|
||||||
|
minRadius = (int) (min/250);
|
||||||
|
maxRadius = (int) (min/220);
|
||||||
|
|
||||||
|
if (maxRadius == minRadius) maxRadius += minRadius;
|
||||||
|
|
||||||
|
stars = new Vector<>();
|
||||||
|
for (i=0; i<size; i++) {
|
||||||
|
tmpRadius = random.nextInt(maxRadius - minRadius) + minRadius;
|
||||||
|
maxX = width - tmpRadius;
|
||||||
|
maxY = height - tmpRadius;
|
||||||
|
stars.add(new Star(random.nextInt(maxX - tmpRadius + (maxRadius * 4)) + (tmpRadius - (maxRadius * 4)),
|
||||||
|
random.nextInt(maxY - tmpRadius + (maxRadius * 4)) + (tmpRadius - (maxRadius * 4)),
|
||||||
|
random.nextInt(maxSpeed - minSpeed) + minSpeed,
|
||||||
|
tmpRadius));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
gameLoop.setRunning(false);
|
||||||
|
gameLoop = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(double radians, double power) {
|
||||||
|
this.radians = radians;
|
||||||
|
this.power = power;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotate(double radians) {
|
||||||
|
this.radians2 = radians;
|
||||||
|
}
|
||||||
|
}
|
34
app/src/main/java/com/erz/joystick/MainActivity.java
Normal file
34
app/src/main/java/com/erz/joystick/MainActivity.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package com.erz.joystick;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.erz.joysticklibrary.JoyStick;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity implements JoyStick.JoyStickListener {
|
||||||
|
|
||||||
|
GameView gameView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
gameView = (GameView) findViewById(R.id.game);
|
||||||
|
((JoyStick)findViewById(R.id.joy1)).setListener(this);
|
||||||
|
((JoyStick)findViewById(R.id.joy1)).setPadColor(Color.parseColor("#55ffffff"));
|
||||||
|
((JoyStick)findViewById(R.id.joy1)).setButtonColor(Color.parseColor("#55ff0000"));
|
||||||
|
|
||||||
|
((JoyStick)findViewById(R.id.joy2)).setListener(new JoyStick.JoyStickListener() {
|
||||||
|
@Override
|
||||||
|
public void onMove(double radians, double power) {
|
||||||
|
gameView.rotate(radians);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMove(double radians, double power) {
|
||||||
|
gameView.move(radians, power);
|
||||||
|
}
|
||||||
|
}
|
45
app/src/main/java/com/erz/joystick/Star.java
Normal file
45
app/src/main/java/com/erz/joystick/Star.java
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package com.erz.joystick;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by edgarramirez on 6/16/15.
|
||||||
|
*/
|
||||||
|
public class Star {
|
||||||
|
public float x;
|
||||||
|
public float y;
|
||||||
|
public float speedY;
|
||||||
|
public float radius;
|
||||||
|
public boolean ready = false;
|
||||||
|
RectF rectF;
|
||||||
|
|
||||||
|
public Star(float x, float y, float speedY, float radius) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.speedY = speedY;
|
||||||
|
this.radius = radius;
|
||||||
|
ready = true;
|
||||||
|
rectF = new RectF();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas, Paint paint, float width, float height, float max) {
|
||||||
|
if (!ready) return;
|
||||||
|
update(width, height, max);
|
||||||
|
|
||||||
|
rectF.set(x - radius, y - radius, x + radius, y + radius);
|
||||||
|
|
||||||
|
paint.setStrokeWidth(radius / 10);
|
||||||
|
canvas.drawOval(rectF, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(float width, float height, float max) {
|
||||||
|
if (!ready) return;
|
||||||
|
y += speedY;
|
||||||
|
|
||||||
|
if ((y + radius) > (height + (max * 4))) {
|
||||||
|
y = - (max * 4) - radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable/droid.png
Normal file
BIN
app/src/main/res/drawable/droid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
27
app/src/main/res/layout/activity_main.xml
Normal file
27
app/src/main/res/layout/activity_main.xml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.erz.joystick.GameView
|
||||||
|
android:id="@+id/game"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<com.erz.joysticklibrary.JoyStick
|
||||||
|
android:id="@+id/joy1"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="bottom"/>
|
||||||
|
|
||||||
|
<com.erz.joysticklibrary.JoyStick
|
||||||
|
android:id="@+id/joy2"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="bottom|right"
|
||||||
|
app:padColor="#55ffffff"
|
||||||
|
app:buttonColor="#55ff0000"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
10
app/src/main/res/menu/menu_main.xml
Normal file
10
app/src/main/res/menu/menu_main.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:context="com.erz.joystick.MainActivity">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_settings"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:title="@string/action_settings"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
</menu>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
9
app/src/main/res/values-v21/styles.xml
Normal file
9
app/src/main/res/values-v21/styles.xml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<resources>>
|
||||||
|
|
||||||
|
<style name="AppTheme.NoActionBar">
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||||
|
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
6
app/src/main/res/values-w820dp/dimens.xml
Normal file
6
app/src/main/res/values-w820dp/dimens.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<resources>
|
||||||
|
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||||
|
(such as screen margins) for screens with more than 820dp of available width. This
|
||||||
|
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||||
|
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||||
|
</resources>
|
6
app/src/main/res/values/colors.xml
Normal file
6
app/src/main/res/values/colors.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="colorPrimary">#3F51B5</color>
|
||||||
|
<color name="colorPrimaryDark">#303F9F</color>
|
||||||
|
<color name="colorAccent">#FF4081</color>
|
||||||
|
</resources>
|
6
app/src/main/res/values/dimens.xml
Normal file
6
app/src/main/res/values/dimens.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<resources>
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
|
</resources>
|
4
app/src/main/res/values/strings.xml
Normal file
4
app/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">JoyStick</string>
|
||||||
|
<string name="action_settings">Settings</string>
|
||||||
|
</resources>
|
24
app/src/main/res/values/styles.xml
Normal file
24
app/src/main/res/values/styles.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
|
<!-- Customize your theme here. -->
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="android:windowFullscreen">true</item>
|
||||||
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.NoActionBar">
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||||
|
|
||||||
|
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||||
|
|
||||||
|
</resources>
|
15
app/src/test/java/com/erz/joystick/ExampleUnitTest.java
Normal file
15
app/src/test/java/com/erz/joystick/ExampleUnitTest.java
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package com.erz.joystick;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To work on unit tests, switch the Test Artifact in the Build Variants view.
|
||||||
|
*/
|
||||||
|
public class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
public void addition_isCorrect() throws Exception {
|
||||||
|
assertEquals(4, 2 + 2);
|
||||||
|
}
|
||||||
|
}
|
23
build.gradle
Normal file
23
build.gradle
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.3.0'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
18
gradle.properties
Normal file
18
gradle.properties
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Project-wide Gradle settings.
|
||||||
|
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||||
|
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||||
|
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
# org.gradle.parallel=true
|
1
joysticklibrary/.gitignore
vendored
Normal file
1
joysticklibrary/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/build
|
25
joysticklibrary/build.gradle
Normal file
25
joysticklibrary/build.gradle
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 23
|
||||||
|
buildToolsVersion "23.0.1"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion 11
|
||||||
|
targetSdkVersion 23
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
testCompile 'junit:junit:4.12'
|
||||||
|
compile 'com.android.support:appcompat-v7:23.1.0'
|
||||||
|
}
|
17
joysticklibrary/proguard-rules.pro
vendored
Normal file
17
joysticklibrary/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /Users/edgarramirez/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.erz.joysticklibrary;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.test.ApplicationTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||||
|
*/
|
||||||
|
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||||
|
public ApplicationTest() {
|
||||||
|
super(Application.class);
|
||||||
|
}
|
||||||
|
}
|
11
joysticklibrary/src/main/AndroidManifest.xml
Normal file
11
joysticklibrary/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.erz.joysticklibrary">
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:supportsRtl="true">
|
||||||
|
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
|
@ -0,0 +1,148 @@
|
||||||
|
package com.erz.joysticklibrary;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by edgarramirez on 10/30/15.
|
||||||
|
*/
|
||||||
|
public class JoyStick extends View {
|
||||||
|
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
float centerX;
|
||||||
|
float centerY;
|
||||||
|
float min;
|
||||||
|
float posX;
|
||||||
|
float posY;
|
||||||
|
float radius;
|
||||||
|
float buttonRadius;
|
||||||
|
double power;
|
||||||
|
double radians;
|
||||||
|
int padColor;
|
||||||
|
int buttonColor;
|
||||||
|
Paint paint;
|
||||||
|
JoyStickListener listener;
|
||||||
|
|
||||||
|
public interface JoyStickListener {
|
||||||
|
void onMove(double radians, double power);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JoyStick(Context context) {
|
||||||
|
super(context);
|
||||||
|
init(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JoyStick(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context, AttributeSet attrs) {
|
||||||
|
paint = new Paint();
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
|
||||||
|
padColor = Color.BLACK;
|
||||||
|
buttonColor = Color.RED;
|
||||||
|
|
||||||
|
if (attrs != null) {
|
||||||
|
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.JoyStick);
|
||||||
|
if (typedArray != null) {
|
||||||
|
padColor = typedArray.getColor(R.styleable.JoyStick_padColor, Color.BLACK);
|
||||||
|
buttonColor = typedArray.getColor(R.styleable.JoyStick_buttonColor, Color.RED);
|
||||||
|
typedArray.recycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
width = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
height = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
centerX = width/2;
|
||||||
|
centerY = height/2;
|
||||||
|
min = Math.min(width, height);
|
||||||
|
posX = centerX;
|
||||||
|
posY = centerY;
|
||||||
|
buttonRadius = (min / 2 * 0.25f);
|
||||||
|
radius = (min / 2 * 0.75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
super.draw(canvas);
|
||||||
|
if (canvas == null) return;
|
||||||
|
paint.setColor(padColor);
|
||||||
|
canvas.drawCircle(centerX, centerY, radius, paint);
|
||||||
|
paint.setColor(buttonColor);
|
||||||
|
canvas.drawCircle(posX, posY, buttonRadius, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
posX = event.getX();
|
||||||
|
posY = event.getY();
|
||||||
|
float abs = (float) Math.sqrt((posX - centerX) * (posX - centerX)
|
||||||
|
+ (posY - centerY) * (posY - centerY));
|
||||||
|
if (abs > radius) {
|
||||||
|
posX = ((posX - centerX) * radius / abs + centerX);
|
||||||
|
posY = ((posY - centerY) * radius / abs + centerY);
|
||||||
|
}
|
||||||
|
|
||||||
|
radians = Math.atan2(centerY - posY, centerX - posX);
|
||||||
|
|
||||||
|
power = (100 * Math.sqrt((posX - centerX)
|
||||||
|
* (posX - centerX) + (posY - centerY)
|
||||||
|
* (posY - centerY)) / radius);
|
||||||
|
|
||||||
|
invalidate();
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
posX = centerX;
|
||||||
|
posY = centerY;
|
||||||
|
radians = 0;
|
||||||
|
power = 0;
|
||||||
|
invalidate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onMove(radians, power);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPadColor(int padColor) {
|
||||||
|
this.padColor = padColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setButtonColor(int buttonColor) {
|
||||||
|
this.buttonColor = buttonColor;
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setListener(JoyStickListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPower() {
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getRadians() {
|
||||||
|
return radians;
|
||||||
|
}
|
||||||
|
}
|
7
joysticklibrary/src/main/res/values/attrs.xml
Normal file
7
joysticklibrary/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="JoyStick">
|
||||||
|
<attr name="padColor" format="color" />
|
||||||
|
<attr name="buttonColor" format="color" />
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
4
joysticklibrary/src/main/res/values/strings.xml
Normal file
4
joysticklibrary/src/main/res/values/strings.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">JoyStick</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.erz.joysticklibrary;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To work on unit tests, switch the Test Artifact in the Build Variants view.
|
||||||
|
*/
|
||||||
|
public class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
public void addition_isCorrect() throws Exception {
|
||||||
|
assertEquals(4, 2 + 2);
|
||||||
|
}
|
||||||
|
}
|
1
settings.gradle
Normal file
1
settings.gradle
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include ':app', ':joysticklibrary'
|
Loading…
Reference in a new issue