Small adjustments to OnScreenController sample

This commit is contained in:
soywiz
2019-03-02 21:01:37 +01:00
parent 8f06506540
commit 68c0b3830f
2 changed files with 64 additions and 101 deletions

View File

@@ -3,118 +3,77 @@ import com.soywiz.korev.*
import com.soywiz.korge.input.*
import com.soywiz.korge.view.*
import com.soywiz.korim.color.*
import com.soywiz.korio.async.*
import com.soywiz.korio.lang.*
import com.soywiz.korma.geom.vector.*
import com.soywiz.korma.geom.*
import com.soywiz.korma.geom.vector.*
import kotlin.math.*
fun Container.addTouchGamepad(width: Double = 320.0, height: Double = 224.0, radius: Double = height / 8, onStick: (x: Double, y: Double) -> Unit = { x, y -> }, onButton: (button: Int, pressed: Boolean) -> Unit = { button, pressed -> }) {
val view = this
lateinit var ball: View
container {
position(+radius * 1.1, height - radius * 1.1)
graphics { fill(Colors.BLACK) { circle(0, 0, radius) } }.alpha(0.2)
ball = graphics { fill(Colors.WHITE) { circle(0, 0, radius * 0.7) } }.alpha(0.2)
}
val view = this
lateinit var ball: View
val diameter = radius * 2
container {
position(+radius * 1.1, height - radius * 1.1)
graphics { fill(Colors.BLACK) { circle(0, 0, radius) } }.alpha(0.2)
ball = graphics { fill(Colors.WHITE) { circle(0, 0, radius * 0.7) } }.alpha(0.2)
}
val button = graphics { position(width - radius * 1.1, height - radius * 1.1).fill(Colors.WHITE) { circle(0, 0, radius * 0.7) } }.alpha(0.2)
fun <T : View> T.decorateButton(button: Int) = this.apply {
var pressing = false
onDown {
pressing = true
alpha = 0.3
onButton(button, true)
}
onUpAnywhere {
if (pressing) {
pressing = false
alpha = 0.2
onButton(button, false)
}
}
}
var dragging = false
var startX = 0.0
var startY = 0.0
val directions = LinkedHashSet<Gestures.Direction>()
val lastDirections = LinkedHashSet<Gestures.Direction>()
for (n in 0 until 2) {
val button = graphics { position(width - radius * 1.1 - (diameter * n), height - radius * 1.1).fill(Colors.WHITE) { circle(0, 0, radius * 0.7) } }.alpha(0.2).decorateButton(n)
}
val keyEvent = KeyEvent()
var dragging = false
val start = Point(0, 0)
fun dispatchKey(key: Key, pressed: Boolean) {
val views = stage?.views ?: return
launchAsap(views.coroutineContext) {
try {
views.dispatch(keyEvent.apply {
this.key = key
this.type = if (pressed) KeyEvent.Type.DOWN else KeyEvent.Type.UP
//println(this)
})
} catch (e: Throwable) {
e.printStackTrace() // @TODO: Check
}
}
}
view.addEventListener<MouseEvent> {
val px = view.globalMatrixInv.transformX(it.x, it.y)
val py = view.globalMatrixInv.transformY(it.x, it.y)
button
.onDown {
button.alpha = 0.3
onButton(0, true)
}
.onUpAnywhere {
//button.alpha = 1.0
button.alpha = 0.2
onButton(0, false)
}
view.addEventListener<MouseEvent> {
val px = view.globalMatrixInv.transformX(it.x, it.y)
val py = view.globalMatrixInv.transformY(it.x, it.y)
directions.clear()
val stage = view.stage ?: return@addEventListener
when (it.type) {
MouseEvent.Type.DOWN -> {
if (px >= width / 2) return@addEventListener
startX = px
startY = py
ball.alpha = 0.3
dragging = true
}
MouseEvent.Type.DRAG -> {
if (dragging) {
val deltaX = px - startX
val deltaY = py - startY
val length = hypot(deltaX, deltaY)
val maxLength = radius * 0.3
val lengthClamped = length.clamp(0.0, maxLength)
val angle = Angle.between(startX, startY, px, py)
ball.position(cos(angle) * lengthClamped, sin(angle) * lengthClamped)
if (lengthClamped >= maxLength * 0.5) {
val quadrant = ((angle + 90.degrees + 45.degrees).normalized.degrees) / 90.0
//println(quadrant)
if (quadrant >= 3.9 || quadrant <= 1.1) directions.add(Gestures.Direction.Up)
if (quadrant in 0.9..2.1) directions.add(Gestures.Direction.Right)
if (quadrant in 1.9..3.1) directions.add(Gestures.Direction.Down)
if (quadrant in 2.9..4.1) directions.add(Gestures.Direction.Left)
}
when (it.type) {
MouseEvent.Type.DOWN -> {
if (px >= width / 2) return@addEventListener
start.x = px
start.y = py
ball.alpha = 0.3
dragging = true
}
MouseEvent.Type.DRAG -> {
if (dragging) {
val deltaX = px - start.x
val deltaY = py - start.y
val length = hypot(deltaX, deltaY)
val maxLength = radius * 0.3
val lengthClamped = length.clamp(0.0, maxLength)
val angle = Angle.between(start.x, start.y, px, py)
ball.position(cos(angle) * lengthClamped, sin(angle) * lengthClamped)
val lengthNormalized = lengthClamped / maxLength
onStick(cos(angle) * lengthNormalized, sin(angle) * lengthNormalized)
}
}
MouseEvent.Type.UP -> {
ball.position(0, 0)
ball.alpha = 0.2
dragging = false
}
MouseEvent.Type.UP -> {
ball.position(0, 0)
ball.alpha = 0.2
dragging = false
onStick(0.0, 0.0)
}
}
//// Release old keys
//for (dir in lastDirections) if (dir !in directions) dispatchKeyForDirection(dir, false)
//// Press new keys
//for (dir in directions) if (dir !in lastDirections) dispatchKeyForDirection(dir, true)
lastDirections.clear()
lastDirections.addAll(directions)
}
//view.addEventListener<ReshapeEvent> {
// println("reshaped ${view.width}x${view.height}")
//}
}
else -> Unit
}
}
}

View File

@@ -1,17 +1,21 @@
import com.soywiz.klock.*
import com.soywiz.korge.*
import com.soywiz.korge.particle.*
import com.soywiz.korge.view.*
import com.soywiz.korim.color.*
import com.soywiz.korio.async.*
import com.soywiz.korio.file.std.*
import com.soywiz.korio.util.*
suspend fun main() = Korge(bgcolor = Colors.DARKBLUE) {
val text1 = text("-").position(0, 0).also { it.filtering = false }
val text2 = text("-").position(0, 15).also { it.filtering = false }
val buttonTexts = (0 until 2).map {
text("-").position(0, 15 * (it + 1)).also { it.filtering = false }
}
addTouchGamepad(
views.virtualWidth.toDouble(), views.virtualHeight.toDouble(),
onStick = { x, y -> text1.setText("Stick: (${x.toStringDecimal(2)}, ${y.toStringDecimal(2)})") },
onButton = { button, pressed -> text2.setText("Button: $button, $pressed") }
onButton = { button, pressed -> buttonTexts[button].setText("Button: $button, $pressed") }
)
}