Make Android DPad 8-Way

This commit is contained in:
Florian Märkl 2019-10-01 15:40:09 +02:00
commit b3a98352a4
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
4 changed files with 78 additions and 13 deletions

View file

@ -24,13 +24,28 @@ import android.view.MotionEvent
import android.view.View
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import com.metallic.chiaki.R
import kotlin.math.abs
import kotlin.math.PI
import kotlin.math.atan2
class DPadView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr)
{
enum class Direction { LEFT, RIGHT, UP, DOWN }
enum class Direction {
LEFT,
RIGHT,
UP,
DOWN,
LEFT_UP,
RIGHT_UP,
LEFT_DOWN,
RIGHT_DOWN;
val isDiagonal get() = when(this) {
LEFT_UP, RIGHT_UP, LEFT_DOWN, RIGHT_DOWN -> true
else -> false
}
}
var state: Direction? = null
private set
@ -45,6 +60,7 @@ class DPadView @JvmOverloads constructor(
private val dpadIdleDrawable = VectorDrawableCompat.create(resources, R.drawable.control_dpad_idle, null)
private val dpadLeftDrawable = VectorDrawableCompat.create(resources, R.drawable.control_dpad_left, null)
private val dpadLeftUpDrawable = VectorDrawableCompat.create(resources, R.drawable.control_dpad_left_up, null)
private val touchTracker = TouchTracker().also {
it.positionChangedCallback = this::updateState
@ -58,13 +74,13 @@ class DPadView @JvmOverloads constructor(
val drawable: VectorDrawableCompat?
if(state != null)
{
drawable = dpadLeftDrawable
drawable = if(state.isDiagonal) dpadLeftUpDrawable else dpadLeftDrawable
when(state)
{
Direction.UP -> canvas.rotate(90f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
Direction.DOWN -> canvas.rotate(90f*3f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
Direction.LEFT -> {}
Direction.RIGHT -> canvas.rotate(90f*2f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
Direction.UP, Direction.RIGHT_UP -> canvas.rotate(90f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
Direction.DOWN, Direction.LEFT_DOWN -> canvas.rotate(90f*3f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
Direction.LEFT, Direction.LEFT_UP -> {}
Direction.RIGHT, Direction.RIGHT_DOWN -> canvas.rotate(90f*2f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
}
}
else
@ -77,14 +93,20 @@ class DPadView @JvmOverloads constructor(
private fun directionForPosition(position: Vector): Direction
{
val dx = position.x - width * 0.5f
val dy = position.y - height * 0.5f
val dir = (position / Vector(width.toFloat(), height.toFloat()) - 0.5f) * 2.0f
val angleSection = PI.toFloat() * 2.0f / 8.0f
val angle = atan2(dir.x, dir.y) + PI + angleSection * 0.5f
return when
{
dx > abs(dy) -> Direction.RIGHT
dx <= -abs(dy) -> Direction.LEFT
dy >= abs(dx) -> Direction.DOWN
else /*dy < -abs(dx)*/ -> Direction.UP
angle < 1.0f * angleSection -> Direction.UP
angle < 2.0f * angleSection -> Direction.LEFT_UP
angle < 3.0f * angleSection -> Direction.LEFT
angle < 4.0f * angleSection -> Direction.LEFT_DOWN
angle < 5.0f * angleSection -> Direction.DOWN
angle < 6.0f * angleSection -> Direction.RIGHT_DOWN
angle < 7.0f * angleSection -> Direction.RIGHT
angle < 8.0f * angleSection -> Direction.RIGHT_UP
else -> Direction.UP
}
}

View file

@ -91,6 +91,10 @@ class TouchControlsFragment : Fragment()
DPadView.Direction.DOWN -> ControllerState.BUTTON_DPAD_DOWN
DPadView.Direction.LEFT -> ControllerState.BUTTON_DPAD_LEFT
DPadView.Direction.RIGHT -> ControllerState.BUTTON_DPAD_RIGHT
DPadView.Direction.LEFT_UP -> ControllerState.BUTTON_DPAD_LEFT or ControllerState.BUTTON_DPAD_UP
DPadView.Direction.LEFT_DOWN -> ControllerState.BUTTON_DPAD_LEFT or ControllerState.BUTTON_DPAD_DOWN
DPadView.Direction.RIGHT_UP -> ControllerState.BUTTON_DPAD_RIGHT or ControllerState.BUTTON_DPAD_UP
DPadView.Direction.RIGHT_DOWN -> ControllerState.BUTTON_DPAD_RIGHT or ControllerState.BUTTON_DPAD_DOWN
null -> 0U
})
}

View file

@ -23,9 +23,14 @@ data class Vector(val x: Float, val y: Float)
{
operator fun plus(o: Vector) = Vector(x + o.x, y + o.y)
operator fun minus(o: Vector) = Vector(x - o.x, y - o.y)
operator fun plus(s: Float) = Vector(x + s, y + s)
operator fun minus(s: Float) = Vector(x - s, y - s)
operator fun times(s: Float) = Vector(x * s, y * s)
operator fun div(s: Float) = this * (1f / s)
operator fun times(o: Vector) = Vector(x * o.x, y * o.y)
operator fun div(o: Vector) = this * Vector(1.0f / o.x, 1.0f / o.y)
val lengthSq get() = x*x + y*y
val length get() = sqrt(lengthSq)
val normalized get() = this / length
}

View file

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="512dp"
android:height="512dp"
android:viewportWidth="135.46667"
android:viewportHeight="135.46667">
<path
android:pathData="M45.244,0L45.244,36.263L62.162,53.181l11.144,0L90.223,36.263L90.223,0Z"
android:strokeAlpha="1"
android:strokeWidth="30.92149353"
android:fillColor="@color/control_pressed"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M0,45.244L0,90.223L36.263,90.223L53.181,73.305L53.181,62.162L36.263,45.244Z"
android:strokeAlpha="1"
android:strokeWidth="30.92149353"
android:fillColor="@color/control_pressed"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M99.203,45.244 L82.285,62.162l0,11.144L99.203,90.223L135.467,90.223L135.467,45.244Z"
android:strokeAlpha="1"
android:strokeWidth="30.92149353"
android:fillColor="@color/control_primary"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
<path
android:pathData="M62.162,82.285 L45.244,99.203L45.244,135.467L90.223,135.467L90.223,99.203L73.305,82.285Z"
android:strokeAlpha="1"
android:strokeWidth="30.92149353"
android:fillColor="@color/control_primary"
android:strokeColor="#00000000"
android:fillAlpha="1"/>
</vector>