diff --git a/android/app/src/main/java/com/metallic/chiaki/touchcontrols/DPadView.kt b/android/app/src/main/java/com/metallic/chiaki/touchcontrols/DPadView.kt index d02b5c7..06829ec 100644 --- a/android/app/src/main/java/com/metallic/chiaki/touchcontrols/DPadView.kt +++ b/android/app/src/main/java/com/metallic/chiaki/touchcontrols/DPadView.kt @@ -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 } } diff --git a/android/app/src/main/java/com/metallic/chiaki/touchcontrols/TouchControlsFragment.kt b/android/app/src/main/java/com/metallic/chiaki/touchcontrols/TouchControlsFragment.kt index a4794d3..8736c5b 100644 --- a/android/app/src/main/java/com/metallic/chiaki/touchcontrols/TouchControlsFragment.kt +++ b/android/app/src/main/java/com/metallic/chiaki/touchcontrols/TouchControlsFragment.kt @@ -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 }) } diff --git a/android/app/src/main/java/com/metallic/chiaki/touchcontrols/Vector.kt b/android/app/src/main/java/com/metallic/chiaki/touchcontrols/Vector.kt index 96c236b..be1fe4d 100644 --- a/android/app/src/main/java/com/metallic/chiaki/touchcontrols/Vector.kt +++ b/android/app/src/main/java/com/metallic/chiaki/touchcontrols/Vector.kt @@ -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 } \ No newline at end of file diff --git a/android/app/src/main/res/drawable/control_dpad_left_up.xml b/android/app/src/main/res/drawable/control_dpad_left_up.xml new file mode 100644 index 0000000..69644e7 --- /dev/null +++ b/android/app/src/main/res/drawable/control_dpad_left_up.xml @@ -0,0 +1,34 @@ + + + + + +