mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 10:46:51 -07:00
Decent Touch Detection for Android DPad
This commit is contained in:
parent
2df51efa38
commit
b007f93d16
2 changed files with 69 additions and 11 deletions
|
@ -26,6 +26,7 @@ import android.view.View
|
|||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
|
||||
import com.metallic.chiaki.R
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.sqrt
|
||||
|
||||
class DPadView @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
|
@ -36,9 +37,17 @@ class DPadView @JvmOverloads constructor(
|
|||
var state: Direction? = null
|
||||
private set
|
||||
|
||||
/**
|
||||
* Radius (as a fraction of the entire DPad Radius)
|
||||
* to be used as a deadzone in the center on move events
|
||||
*/
|
||||
private val deadzoneRadius = 0.3f
|
||||
|
||||
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 var pointerId: Int? = null
|
||||
|
||||
override fun onDraw(canvas: Canvas)
|
||||
{
|
||||
super.onDraw(canvas)
|
||||
|
@ -64,7 +73,7 @@ class DPadView @JvmOverloads constructor(
|
|||
drawable?.draw(canvas)
|
||||
}
|
||||
|
||||
fun directionForPosition(x: Float, y: Float): Direction
|
||||
private fun directionForPosition(x: Float, y: Float): Direction
|
||||
{
|
||||
val dx = x - width * 0.5f
|
||||
val dy = y - height * 0.5f
|
||||
|
@ -72,19 +81,68 @@ class DPadView @JvmOverloads constructor(
|
|||
{
|
||||
dx > abs(dy) -> Direction.RIGHT
|
||||
dx <= -abs(dy) -> Direction.LEFT
|
||||
dy > abs(dx) -> Direction.DOWN
|
||||
else /*dy <= -abs(dx)*/ -> Direction.UP
|
||||
dy >= abs(dx) -> Direction.DOWN
|
||||
else /*dy < -abs(dx)*/ -> Direction.UP
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateState(x: Float?, y: Float?)
|
||||
{
|
||||
val newState =
|
||||
if(x == null || y == null)
|
||||
null
|
||||
else
|
||||
{
|
||||
val xFrac = 2.0f * (x / width.toFloat() - 0.5f)
|
||||
val yFrac = 2.0f * (y / height.toFloat() - 0.5f)
|
||||
val radiusSq = xFrac * xFrac + yFrac * yFrac
|
||||
if(radiusSq < deadzoneRadius * deadzoneRadius && state != null)
|
||||
state
|
||||
else
|
||||
directionForPosition(x, y)
|
||||
}
|
||||
|
||||
if(state != newState)
|
||||
{
|
||||
state = newState
|
||||
invalidate()
|
||||
// TODO: callback
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean
|
||||
{
|
||||
val dir = directionForPosition(event.x, event.y)
|
||||
if(event.action == MotionEvent.ACTION_UP)
|
||||
state = null
|
||||
else if(event.action == MotionEvent.ACTION_DOWN)
|
||||
state = dir
|
||||
invalidate()
|
||||
when(event.actionMasked)
|
||||
{
|
||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN ->
|
||||
{
|
||||
if(pointerId == null)
|
||||
{
|
||||
pointerId = event.getPointerId(event.actionIndex)
|
||||
updateState(event.x, event.y)
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP ->
|
||||
{
|
||||
if(event.getPointerId(event.actionIndex) == pointerId)
|
||||
{
|
||||
pointerId = null
|
||||
updateState(null, null)
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_MOVE ->
|
||||
{
|
||||
val pointerId = pointerId
|
||||
if(pointerId != null)
|
||||
{
|
||||
val pointerIndex = event.findPointerIndex(pointerId)
|
||||
if(pointerIndex >= 0)
|
||||
updateState(event.getX(pointerIndex), event.getY(pointerIndex))
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@
|
|||
app:layout_constraintTop_toBottomOf="@+id/morningEditText" />
|
||||
|
||||
<com.metallic.chiaki.touchcontrols.DPadView
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="32dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue