mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-21 14:03:11 -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 android.view.View
|
||||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||||
import com.metallic.chiaki.R
|
import com.metallic.chiaki.R
|
||||||
import kotlin.math.abs
|
import kotlin.math.PI
|
||||||
|
import kotlin.math.atan2
|
||||||
|
|
||||||
class DPadView @JvmOverloads constructor(
|
class DPadView @JvmOverloads constructor(
|
||||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||||
) : View(context, attrs, defStyleAttr)
|
) : 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
|
var state: Direction? = null
|
||||||
private set
|
private set
|
||||||
|
@ -45,6 +60,7 @@ class DPadView @JvmOverloads constructor(
|
||||||
|
|
||||||
private val dpadIdleDrawable = VectorDrawableCompat.create(resources, R.drawable.control_dpad_idle, null)
|
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 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 {
|
private val touchTracker = TouchTracker().also {
|
||||||
it.positionChangedCallback = this::updateState
|
it.positionChangedCallback = this::updateState
|
||||||
|
@ -58,13 +74,13 @@ class DPadView @JvmOverloads constructor(
|
||||||
val drawable: VectorDrawableCompat?
|
val drawable: VectorDrawableCompat?
|
||||||
if(state != null)
|
if(state != null)
|
||||||
{
|
{
|
||||||
drawable = dpadLeftDrawable
|
drawable = if(state.isDiagonal) dpadLeftUpDrawable else dpadLeftDrawable
|
||||||
when(state)
|
when(state)
|
||||||
{
|
{
|
||||||
Direction.UP -> canvas.rotate(90f, 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 -> canvas.rotate(90f*3f, 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, Direction.LEFT_UP -> {}
|
||||||
Direction.RIGHT -> canvas.rotate(90f*2f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
|
Direction.RIGHT, Direction.RIGHT_DOWN -> canvas.rotate(90f*2f, width.toFloat() * 0.5f, height.toFloat() * 0.5f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -77,14 +93,20 @@ class DPadView @JvmOverloads constructor(
|
||||||
|
|
||||||
private fun directionForPosition(position: Vector): Direction
|
private fun directionForPosition(position: Vector): Direction
|
||||||
{
|
{
|
||||||
val dx = position.x - width * 0.5f
|
val dir = (position / Vector(width.toFloat(), height.toFloat()) - 0.5f) * 2.0f
|
||||||
val dy = position.y - height * 0.5f
|
val angleSection = PI.toFloat() * 2.0f / 8.0f
|
||||||
|
val angle = atan2(dir.x, dir.y) + PI + angleSection * 0.5f
|
||||||
return when
|
return when
|
||||||
{
|
{
|
||||||
dx > abs(dy) -> Direction.RIGHT
|
angle < 1.0f * angleSection -> Direction.UP
|
||||||
dx <= -abs(dy) -> Direction.LEFT
|
angle < 2.0f * angleSection -> Direction.LEFT_UP
|
||||||
dy >= abs(dx) -> Direction.DOWN
|
angle < 3.0f * angleSection -> Direction.LEFT
|
||||||
else /*dy < -abs(dx)*/ -> Direction.UP
|
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.DOWN -> ControllerState.BUTTON_DPAD_DOWN
|
||||||
DPadView.Direction.LEFT -> ControllerState.BUTTON_DPAD_LEFT
|
DPadView.Direction.LEFT -> ControllerState.BUTTON_DPAD_LEFT
|
||||||
DPadView.Direction.RIGHT -> ControllerState.BUTTON_DPAD_RIGHT
|
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
|
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 plus(o: Vector) = Vector(x + o.x, y + o.y)
|
||||||
operator fun minus(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 times(s: Float) = Vector(x * s, y * s)
|
||||||
operator fun div(s: Float) = this * (1f / 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 lengthSq get() = x*x + y*y
|
||||||
val length get() = sqrt(lengthSq)
|
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