first commit

This commit is contained in:
edgar 2015-10-30 21:13:41 -07:00
commit 66126df543
37 changed files with 795 additions and 0 deletions

40
.gitignore vendored Normal file
View 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
View file

@ -0,0 +1 @@
/build

28
app/build.gradle Normal file
View 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
View 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 *;
#}

View file

@ -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);
}
}

View 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>

View 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) {}
}
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View 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>

View 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>

View 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>

View 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>

View file

@ -0,0 +1,4 @@
<resources>
<string name="app_name">JoyStick</string>
<string name="action_settings">Settings</string>
</resources>

View 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>

View 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
View 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
View 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
View file

@ -0,0 +1 @@
/build

View 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
View 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 *;
#}

View file

@ -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);
}
}

View 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>

View file

@ -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;
}
}

View 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>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">JoyStick</string>
</resources>

View file

@ -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
View file

@ -0,0 +1 @@
include ':app', ':joysticklibrary'