mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-21 05:53:12 -07:00
Make Android DPad 8-Way
This commit is contained in:
parent
08456d56b5
commit
b3a98352a4
4 changed files with 78 additions and 13 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
34
android/app/src/main/res/drawable/control_dpad_left_up.xml
Normal file
34
android/app/src/main/res/drawable/control_dpad_left_up.xml
Normal 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>
|
Loading…
Add table
Add a link
Reference in a new issue