mirror of
https://github.com/jlengrand/korge-samples.git
synced 2026-03-10 08:31:18 +00:00
Remove kuyo sample temporarily until it is fixed
This commit is contained in:
13
game/kuyo/.gitignore
vendored
13
game/kuyo/.gitignore
vendored
@@ -1,13 +0,0 @@
|
||||
/build
|
||||
/classes
|
||||
/out
|
||||
/.gradle
|
||||
/.gradle
|
||||
/.idea
|
||||
/build
|
||||
/classes
|
||||
/out
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
log.txt
|
||||
@@ -1,6 +0,0 @@
|
||||
apply plugin: com.soywiz.korge.gradle.KorgeGradlePlugin
|
||||
|
||||
korge {
|
||||
id = "org.korge.samples.kuyo"
|
||||
targetDefault()
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import org.korge.sample.kuyo.*
|
||||
|
||||
suspend fun main() = Kuyo.main(arrayOf())
|
||||
@@ -1,356 +0,0 @@
|
||||
package org.korge.sample.kuyo
|
||||
|
||||
import com.soywiz.kds.*
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.korev.*
|
||||
import com.soywiz.korge.animate.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.input.keys
|
||||
import com.soywiz.korge.input.mouse
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korge.time.*
|
||||
import com.soywiz.korge.tween.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korge.view.tween.*
|
||||
import com.soywiz.korim.bitmap.*
|
||||
import com.soywiz.korim.font.*
|
||||
import com.soywiz.korim.format.*
|
||||
import com.soywiz.korio.async.*
|
||||
import com.soywiz.korio.lang.*
|
||||
import com.soywiz.korma.geom.*
|
||||
import com.soywiz.korma.geom.ds.*
|
||||
import com.soywiz.korma.interpolation.*
|
||||
import com.soywiz.korma.random.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.korge.sample.kuyo.*
|
||||
import org.korge.sample.kuyo.model.*
|
||||
import org.korge.sample.kuyo.util.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.random.*
|
||||
|
||||
class KuyoScene(val seed: Long = Random.nextLong()) : Scene() {
|
||||
lateinit var board: KuyoBoardView
|
||||
|
||||
override suspend fun Container.sceneInit() {
|
||||
println("KuyoScene.init()")
|
||||
val rand1 = Random(seed)
|
||||
val rand2 = Random(seed)
|
||||
val font1 = resourcesRoot["kuyo/font1.fnt"].readBitmapFont()
|
||||
|
||||
val tiles = KuyoTiles(resourcesRoot["kuyo/kuyos.png"].readBitmapSlice())
|
||||
val bg = resourcesRoot["kuyo/bg.png"].readBitmapSlice()
|
||||
root += Image(bg).apply {
|
||||
gamepad {
|
||||
connection {
|
||||
println("connection: $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
board = KuyoBoardView(0, KuyoBoard(), tiles, font1, rand = rand1, coroutineContext).position(64, 64).addTo(containerRoot)
|
||||
//KuyoBoardView(1, KuyoBoard(), tiles, font1, rand = rand2).also { it.position(640, 64); root += it }
|
||||
}
|
||||
}
|
||||
|
||||
val DEFAULT_EASING = Easing.LINEAR
|
||||
|
||||
class KuyoDropView(val board: KuyoBoardView, private var model: KuyoDrop, val coroutineContext: CoroutineContext) : Container() {
|
||||
val dropModel get() = model
|
||||
val boardModel get() = board.model
|
||||
val views = (0 until 4).map { ViewKuyo(PointInt(0, 0), 0, board).also { addChild(it) } }
|
||||
val queue get() = board.queue
|
||||
|
||||
fun rotateRight() {
|
||||
set(model.rotateOrHold(+1, board.model), time = 0.1.seconds)
|
||||
}
|
||||
|
||||
fun rotateLeft() {
|
||||
set(model.rotateOrHold(-1, board.model), time = 0.1.seconds)
|
||||
}
|
||||
|
||||
fun moveBy(delta: PointInt, easing: Easing = DEFAULT_EASING): Boolean {
|
||||
val newModel = model.tryMove(delta, board.model) ?: return false
|
||||
set(newModel, time = if (delta.x == 0) 0.05.seconds else 0.1.seconds, easing = easing)
|
||||
return true
|
||||
}
|
||||
|
||||
fun setImmediate(newDrop: KuyoDrop) {
|
||||
model = newDrop
|
||||
for ((index, item) in newDrop.transformedItems.withIndex()) {
|
||||
val view = views[index]
|
||||
view.set(item.color)
|
||||
view.moveToImmediate(item.pos)
|
||||
}
|
||||
setHints()
|
||||
}
|
||||
|
||||
fun setHints() {
|
||||
board.setHints(boardModel.place(model).dst.gravity().transforms.map { it.cdst })
|
||||
}
|
||||
|
||||
fun set(newDrop: KuyoDrop, time: TimeSpan = 0.1.seconds, easing: Easing = DEFAULT_EASING) {
|
||||
queue.discard {
|
||||
model = newDrop
|
||||
|
||||
setHints()
|
||||
|
||||
launchImmediately(coroutineContext) {
|
||||
animateParallel {
|
||||
for ((index, item) in newDrop.transformedItems.withIndex()) {
|
||||
val view = views[index]
|
||||
view.set(item.color)
|
||||
sequence {
|
||||
view.moveTo(this, item.pos, time = time, easing = easing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun place() {
|
||||
queue.discard {
|
||||
//println("------")
|
||||
alpha = 0.0
|
||||
val placement = listOf(PointInt(0, 0), PointInt(0, 1), PointInt(0, 2), PointInt(0, 3)).firstNotNullOrNull {
|
||||
dropModel.tryMove(it, boardModel)?.let { if (boardModel.canPlace(it)) it else null }
|
||||
} ?: error("GAME OVER!")
|
||||
board.applyStep(boardModel.place(placement))
|
||||
var chains = 1
|
||||
do {
|
||||
board.applyStep(boardModel.gravity())
|
||||
val explosions = boardModel.explode()
|
||||
board.applyStep(explosions)
|
||||
if (explosions.transforms.isNotEmpty()) {
|
||||
launchImmediately(coroutineContext) { board.chain(chains) }
|
||||
chains++
|
||||
}
|
||||
} while (explosions.transforms.isNotEmpty())
|
||||
alpha = 1.0
|
||||
setImmediate(KuyoDrop(PointInt(2, 0), board.generateRandShape()))
|
||||
queue.discard()
|
||||
}
|
||||
}
|
||||
|
||||
fun moveLeft() {
|
||||
moveBy(PointInt(-1, 0))
|
||||
}
|
||||
|
||||
fun moveRight() {
|
||||
moveBy(PointInt(+1, 0))
|
||||
}
|
||||
|
||||
fun moveDownOrPlace() {
|
||||
downTimer.close()
|
||||
if (!moveBy(PointInt(0, +1), easing = Easing.LINEAR)) {
|
||||
place()
|
||||
}
|
||||
}
|
||||
|
||||
lateinit var downTimer: Closeable
|
||||
|
||||
init {
|
||||
setImmediate(model)
|
||||
keys {
|
||||
down(Key.RIGHT) { moveRight() }
|
||||
down(Key.LEFT) { moveLeft() }
|
||||
down(Key.DOWN) { moveDownOrPlace() }
|
||||
down(Key.Z) { rotateLeft() }
|
||||
down(Key.X) { rotateRight() }
|
||||
down(Key.ENTER) { rotateRight() }
|
||||
//down(Key.UP) { moveBy(IPoint(0, -1)) } // Only debug
|
||||
//down(Key.SPACE) { place() } // Only debug
|
||||
}
|
||||
gamepad {
|
||||
stick(board.playerId, GameStick.LEFT) { x, y ->
|
||||
if (queue.size < 1) {
|
||||
when {
|
||||
x < -0.25 -> moveLeft()
|
||||
x > +0.25 -> moveRight()
|
||||
}
|
||||
}
|
||||
if (y < -0.25) moveDownOrPlace()
|
||||
}
|
||||
down(board.playerId, GameButton.LEFT) {
|
||||
moveLeft()
|
||||
}
|
||||
down(board.playerId, GameButton.RIGHT) {
|
||||
moveRight()
|
||||
}
|
||||
down(board.playerId, GameButton.BUTTON2) {
|
||||
rotateRight()
|
||||
}
|
||||
down(board.playerId, GameButton.BUTTON1) {
|
||||
rotateLeft()
|
||||
}
|
||||
}
|
||||
downTimer = timers.timeout(1.0.seconds) {
|
||||
moveDownOrPlace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val NCOLORS = 4
|
||||
|
||||
class KuyoBoardView(
|
||||
val playerId: Int,
|
||||
var model: KuyoBoard,
|
||||
val tiles: KuyoTiles,
|
||||
val font: BitmapFont,
|
||||
val rand: Random = Random,
|
||||
val coroutineContext: CoroutineContext
|
||||
) : Container() {
|
||||
val mwidth get() = model.width
|
||||
val mheight get() = model.height
|
||||
val queue = JobQueue()
|
||||
val hints = container()
|
||||
//val kuyos = Array2<ViewKuyo?>(model.width, model.height) { index ->
|
||||
// //ViewKuyo(IPoint(x, y), 0, this@KuyoBoardView).apply { this@KuyoBoardView.addChild(this) }
|
||||
// null as ViewKuyo?
|
||||
//}
|
||||
|
||||
val kuyos = Array2<ViewKuyo?>(model.width, model.height, arrayOfNulls(model.width * model.height))
|
||||
|
||||
fun generateRandShape() = KuyoShape2(rand[1..NCOLORS], rand[1..NCOLORS])
|
||||
|
||||
val dropping = KuyoDropView(this, KuyoDrop(PointInt(2, 0), generateRandShape()), coroutineContext).apply {
|
||||
this@KuyoBoardView.addChild(this)
|
||||
}
|
||||
|
||||
fun updateTexs() {
|
||||
for (y in 0 until mheight) {
|
||||
for (x in 0 until mwidth) {
|
||||
val p = PointInt(x, y)
|
||||
val kuyo = kuyos[p]
|
||||
if (kuyo != null) {
|
||||
val c = model[p]
|
||||
val left = model[PointInt(x - 1, y)] == c
|
||||
val right = model[PointInt(x + 1, y)] == c
|
||||
val up = model[PointInt(x, y - 1)] == c
|
||||
val down = model[PointInt(x, y + 1)] == c
|
||||
kuyo.bitmap = tiles.getTex(c, up, left, right, down)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun chain(count: Int) {
|
||||
val text = Text("$count chains!", textSize = 32.0, font = font).also {
|
||||
this += it
|
||||
it.position(16, 96)
|
||||
}
|
||||
text.show(time = 0.3.seconds, easing = Easing.EASE_IN_OUT_QUAD)
|
||||
animateParallel {
|
||||
sequence { text.moveBy(0.0, -64.0, time = 0.3.seconds) }
|
||||
sequence { text.hide(time = 0.3.seconds) }
|
||||
}
|
||||
text.removeFromParent()
|
||||
}
|
||||
|
||||
fun setHints(points: List<ColoredPoint>) {
|
||||
hints.removeChildren()
|
||||
for (p in points) {
|
||||
hints += Image(tiles.getHintTex(p.color)).also {
|
||||
it.x = p.pos.x * 32.0 + 8.0
|
||||
it.y = p.pos.y * 32.0 + 8.0
|
||||
it.alpha = 0.6
|
||||
it.scale = 0.75
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun applyStep(step: KuyoStep<out KuyoTransform>) {
|
||||
model = step.dst
|
||||
//println(model.toBoardString())
|
||||
|
||||
animateParallel {
|
||||
for (transform in step.transforms) {
|
||||
//println("TRANSFORM : $transform")
|
||||
when (transform) {
|
||||
is KuyoTransform.Place -> {
|
||||
val item = transform.item
|
||||
//println("PLACED: $item")
|
||||
sequence {
|
||||
kuyos[item.pos] =
|
||||
ViewKuyo(item.pos, item.color, this@KuyoBoardView).addTo(this@KuyoBoardView).also { alpha = 1.0 }
|
||||
}
|
||||
}
|
||||
is KuyoTransform.Move -> {
|
||||
val kuyo = kuyos[transform.src]
|
||||
kuyos[transform.src] = null
|
||||
kuyos[transform.dst] = kuyo
|
||||
sequence {
|
||||
kuyo?.moveTo(this, transform.dst, time = 0.3.seconds, easing = Easing.EASE_IN_QUAD)
|
||||
}
|
||||
}
|
||||
is KuyoTransform.Explode -> {
|
||||
for (item in transform.items) {
|
||||
val kuyo = kuyos[item] ?: continue
|
||||
sequence {
|
||||
wait(0.1.seconds)
|
||||
block { kuyo.bitmap = tiles.getDestroyTex(kuyo.color) }
|
||||
tween(kuyo::scale[1.5], time = 0.3.seconds, easing = Easing.EASE_IN_QUAD)
|
||||
val destroyEasing = Easing.EASE_OUT_QUAD
|
||||
parallel {
|
||||
sequence {
|
||||
tween(kuyo::scale[0.5], time = 0.1.seconds, easing = destroyEasing)
|
||||
tween(kuyo::scaleY[0.1], time = 0.1.seconds, easing = Easing.EASE_OUT_QUAD)
|
||||
}
|
||||
sequence {
|
||||
kuyo.hide(time = 0.15.seconds, easing = destroyEasing)
|
||||
//kuyo.delay(time = 0.2)
|
||||
}
|
||||
}
|
||||
block { kuyo.removeFromParent() }
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
println("Unhandled transform : $transform")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateTexs()
|
||||
}
|
||||
}
|
||||
|
||||
class ViewKuyo(var ipos: PointInt, var color: Int, val board: KuyoBoardView) : BaseImage(board.tiles.empty) {
|
||||
val tiles get() = board.tiles
|
||||
|
||||
init {
|
||||
anchor(0.5, 0.5)
|
||||
set(color)
|
||||
moveToImmediate(ipos)
|
||||
mouse {
|
||||
click {
|
||||
println("kuyo $ipos!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getRPos(pos: PointInt) = (pos * PointInt(32, 32)) + PointInt(16, 16)
|
||||
|
||||
fun moveTo(animator: Animator, npos: PointInt, time: TimeSpan = 0.1.seconds, easing: Easing = DEFAULT_EASING) {
|
||||
ipos = npos
|
||||
val screenPos = getRPos(npos)
|
||||
animator.apply {
|
||||
this@ViewKuyo.moveTo(screenPos.x.toDouble(), screenPos.y.toDouble(), time = time, easing = easing)
|
||||
}
|
||||
}
|
||||
|
||||
fun moveToImmediate(npos: PointInt) {
|
||||
ipos = npos
|
||||
val screenPos = getRPos(ipos)
|
||||
x = screenPos.x.toDouble()
|
||||
y = screenPos.y.toDouble()
|
||||
}
|
||||
|
||||
fun set(value: Int) {
|
||||
this.color = value
|
||||
bitmap = when (value) {
|
||||
0 -> tiles.empty
|
||||
in 0 until 5 -> tiles.colors[value]
|
||||
else -> tiles.default
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package org.korge.sample.kuyo
|
||||
|
||||
import com.soywiz.kds.*
|
||||
import com.soywiz.korim.bitmap.*
|
||||
|
||||
class KuyoTiles(val tex: BitmapSlice<Bitmap>) {
|
||||
val tiles = Array2(16, 16) { tex }
|
||||
|
||||
//val tile = tex.sliceSize(0, 0, 32, 32)
|
||||
//val tile = arrayListOf<SceneTexture>()
|
||||
init {
|
||||
for (y in 0 until 16) {
|
||||
for (x in 0 until 16) {
|
||||
tiles[x, y] = tex.sliceWithSize(x * 32, y * 32, 32, 32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getTex(
|
||||
color: Int,
|
||||
up: Boolean = false,
|
||||
left: Boolean = false,
|
||||
right: Boolean = false,
|
||||
down: Boolean = false
|
||||
): BmpSlice {
|
||||
if (color <= 0) return tiles[5, 15]
|
||||
val combinable = true
|
||||
//val combinable = false
|
||||
var offset = 0
|
||||
if (combinable) {
|
||||
offset += if (down) 1 else 0
|
||||
offset += if (up) 2 else 0
|
||||
offset += if (right) 4 else 0
|
||||
offset += if (left) 8 else 0
|
||||
}
|
||||
return tiles[offset, color - 1]
|
||||
}
|
||||
|
||||
fun getDestroyTex(color: Int): BmpSlice {
|
||||
return when (color) {
|
||||
1 -> tiles[0, 12]
|
||||
2 -> tiles[0, 13]
|
||||
3 -> tiles[2, 12]
|
||||
4 -> tiles[2, 13]
|
||||
5 -> tiles[4, 12]
|
||||
else -> tiles[5, 15]
|
||||
}
|
||||
}
|
||||
|
||||
fun getHintTex(color: Int): BmpSlice {
|
||||
return tiles[5 + color - 1, 11]
|
||||
}
|
||||
|
||||
val default = getTex(1)
|
||||
val colors = listOf(tiles[0, 0]) + (0 until 5).map { getTex(it + 1) }
|
||||
val empty = getTex(0)
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package org.korge.sample.kuyo
|
||||
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korim.format.*
|
||||
import com.soywiz.korinject.*
|
||||
import com.soywiz.korma.geom.*
|
||||
import org.korge.sample.kuyo.model.*
|
||||
import kotlin.jvm.*
|
||||
import kotlin.reflect.*
|
||||
|
||||
object Kuyo {
|
||||
//val WINDOW_CONFIG = WindowConfig(
|
||||
// width = (1280 * 0.7).toInt(),
|
||||
// height = (720 * 0.7).toInt(),
|
||||
// title = "Kuyo!"
|
||||
//)
|
||||
|
||||
@JvmStatic
|
||||
suspend fun main(args: Array<String>) {
|
||||
Korge(Korge.Config(object : Module() {
|
||||
override val mainScene: KClass<out Scene> = KuyoScene::class
|
||||
override val size: SizeInt = SizeInt(896, 504)
|
||||
|
||||
override suspend fun AsyncInjector.configure() {
|
||||
mapPrototype { KuyoScene() }
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
//object MainMenu {
|
||||
// @JvmStatic
|
||||
// fun main(args: Array<String>) {
|
||||
// SceneApplication(WINDOW_CONFIG) { MainMenuScene() }
|
||||
// }
|
||||
//}
|
||||
|
||||
object SkinTester {
|
||||
@JvmStatic
|
||||
suspend fun main(args: Array<String>) {
|
||||
Korge(Korge.Config(object : Module() {
|
||||
override val mainScene: KClass<out Scene> = TestPuyoScene::class
|
||||
|
||||
override suspend fun AsyncInjector.configure() {
|
||||
mapPrototype { TestPuyoScene() }
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestPuyoScene : Scene() {
|
||||
override suspend fun Container.sceneInit() {
|
||||
//val tiles = KuyoTiles(resourcesRoot["kuyo/kuyos.png"].readBitmapNoNative(defaultImageFormats).slice())
|
||||
val tiles = KuyoTiles(resourcesRoot["kuyo/kuyos.png"].readBitmapSlice())
|
||||
val board = board(
|
||||
"1.11.111...........",
|
||||
".............1.....",
|
||||
"1.11.11.11..111....",
|
||||
"1.1...1.11...1.....",
|
||||
"...................",
|
||||
"1.1...1.111.111....",
|
||||
"1.11.11.1.1.111....",
|
||||
"1.......111.111...."
|
||||
)
|
||||
for (y in 0 until board.height) {
|
||||
for (x in 0 until board.width) {
|
||||
val c = board[PointInt(x, y)]
|
||||
val up = board[PointInt(x, y - 1)] == c
|
||||
val down = board[PointInt(x, y + 1)] == c
|
||||
val left = board[PointInt(x - 1, y)] == c
|
||||
val right = board[PointInt(x + 1, y)] == c
|
||||
if (c != 0) {
|
||||
Image(tiles.getTex(c, up, left, right, down)).also {
|
||||
it.position(x * 32.0, y * 32.0)
|
||||
root += it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package org.korge.sample.kuyo
|
||||
|
||||
/*
|
||||
import com.soywiz.korge.bitmapfont.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korge.view.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class MainMenuScene : Scene() {
|
||||
val queue = JobQueue()
|
||||
|
||||
override suspend fun Container.sceneInit() {
|
||||
val font = resourcesRoot["font1.fnt"].readBitmapFont()
|
||||
val endless = Text("ENDLESS", 96.0, font = font).apply {
|
||||
position(448, 64 + 128 * 0)
|
||||
//anchor(0.5, 0.5)
|
||||
//elasticButton(queue)
|
||||
}
|
||||
val localCoOp = Text(font, "LOCAL CO-OP", 96).apply {
|
||||
position(448, 64 + 128 * 1)
|
||||
//anchor(0.5, 0.5)
|
||||
//elasticButton(queue)
|
||||
}
|
||||
val credits = Text(font, "CREDITS", 96).apply {
|
||||
position(448, 64 + 128 * 2)
|
||||
//anchor(0.5, 0.5)
|
||||
//elasticButton(queue)
|
||||
}
|
||||
this.root += endless
|
||||
this.root += localCoOp
|
||||
this.root += credits
|
||||
|
||||
launch(coroutineContext) {
|
||||
val result = optionSelector(
|
||||
root, listOf(
|
||||
endless to "endless",
|
||||
localCoOp to "localcoop",
|
||||
credits to "credits"
|
||||
)
|
||||
)
|
||||
println(result)
|
||||
changeSceneTo(KuyoScene())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun optionSelector(events: Container, options: List<Pair<View, String>>) = suspendCoroutine<String> { c ->
|
||||
val queue: JobQueue = JobQueue()
|
||||
var index = 0
|
||||
|
||||
fun activate(aindex: Int) {
|
||||
//queue.cancel().queue {
|
||||
queue.queue {
|
||||
|
||||
parallel {
|
||||
for ((index, option) in options.withIndex()) {
|
||||
val view = option.first
|
||||
sequence {
|
||||
//println("aaa: $index, $aindex")
|
||||
if (index == aindex) {
|
||||
view.tween(view::scale[1.2], time = 0.1, easing = Easing.ELASTIC_EASE_OUT)
|
||||
} else {
|
||||
view.tween(view::scale[1.0], time = 0.1, easing = Easing.ELASTIC_EASE_OUT)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun move(delta: Int) {
|
||||
val oldIndex = index
|
||||
val newIndex = (index + delta) umod options.size
|
||||
//println("$oldIndex -> $newIndex")
|
||||
//deactivate(options[oldIndex].first)
|
||||
index = newIndex
|
||||
activate(newIndex)
|
||||
}
|
||||
|
||||
events.apply {
|
||||
val view = View()
|
||||
addChild(view)
|
||||
view.keys {
|
||||
down(Key.UP) { move(-1) }
|
||||
down(Key.DOWN) { move(+1) }
|
||||
down(Key.LEFT) { move(-1) }
|
||||
down(Key.RIGHT) { move(+1) }
|
||||
down(Key.ENTER) {
|
||||
removeChild(view)
|
||||
c.resume(options[index].second)
|
||||
}
|
||||
}
|
||||
}
|
||||
activate(0)
|
||||
}
|
||||
|
||||
fun View.elasticButton(queue: JobQueue) {
|
||||
mouse {
|
||||
over { queue.discard { tween(::scale[2.0], time = 0.3, easing = Easing.ELASTIC_EASE_OUT) } }
|
||||
out { queue.discard { tween(::scale[1.0], time = 0.3, easing = Easing.ELASTIC_EASE_OUT) } }
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,236 +0,0 @@
|
||||
package org.korge.sample.kuyo.model
|
||||
|
||||
import com.soywiz.kds.*
|
||||
import com.soywiz.korma.geom.*
|
||||
import org.korge.sample.kuyo.model.KuyoBoard.Companion.EMPTY
|
||||
|
||||
data class KuyoItem(val pos: PointInt, val color: Int)
|
||||
|
||||
interface KuyoShape {
|
||||
val items: List<KuyoItem>
|
||||
fun rotatedLeft(): KuyoShape = rotatedRight().rotatedRight().rotatedRight()
|
||||
fun rotatedRight(): KuyoShape
|
||||
}
|
||||
|
||||
data class KuyoShape2(val k1: KuyoItem, val k2: KuyoItem) : KuyoShape {
|
||||
constructor(c1: Int, c2: Int) : this(KuyoItem(PointInt(0, 0), c1), KuyoItem(PointInt(0, -1), c2))
|
||||
|
||||
override val items = listOf(k1, k2)
|
||||
override fun rotatedRight(): KuyoShape2 {
|
||||
return when (k2.pos) {
|
||||
PointInt(0, 1) -> KuyoShape2(k1, k2.copy(pos = PointInt(-1, 0)))
|
||||
PointInt(-1, 0) -> KuyoShape2(k1, k2.copy(pos = PointInt(0, -1)))
|
||||
PointInt(0, -1) -> KuyoShape2(k1, k2.copy(pos = PointInt(+1, 0)))
|
||||
PointInt(+1, 0) -> KuyoShape2(k1, k2.copy(pos = PointInt(0, +1)))
|
||||
else -> TODO("${k2.pos}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class KuyoDrop(val pos: PointInt, val shape: KuyoShape) {
|
||||
val transformedItems get() = shape.items.map { it.copy(pos = pos + it.pos) }
|
||||
fun displaced(delta: PointInt): KuyoDrop = copy(pos = pos + delta)
|
||||
fun rotated(direction: Int): KuyoDrop = if (direction < 0) rotatedLeft() else rotatedRight()
|
||||
fun rotatedLeft(): KuyoDrop = copy(shape = shape.rotatedLeft())
|
||||
fun rotatedRight(): KuyoDrop = copy(shape = shape.rotatedRight())
|
||||
}
|
||||
|
||||
data class KuyoBoard(val board: Array2<Int> = Array2(6, 12) { 0 }) {
|
||||
companion object {
|
||||
const val EMPTY = 0
|
||||
const val BORDER = -1
|
||||
}
|
||||
|
||||
val width get() = board.width
|
||||
val height get() = board.height
|
||||
operator fun get(x: Int, y: Int): Int {
|
||||
if ((x !in 0 until width) || (y !in 0 until height)) return BORDER
|
||||
return board.tryGet(x, y) ?: EMPTY
|
||||
}
|
||||
operator fun get(pos: PointInt): Int = get(pos.x, pos.y)
|
||||
operator fun set(pos: PointInt, value: Int) = run { board.trySet(pos.x, pos.y, value) }
|
||||
fun clone() = KuyoBoard(board.clone())
|
||||
}
|
||||
|
||||
data class KuyoStep<TKuyoTransform : KuyoTransform>(
|
||||
val src: KuyoBoard,
|
||||
val dst: KuyoBoard,
|
||||
val transforms: List<TKuyoTransform>
|
||||
)
|
||||
|
||||
data class ColoredPoint(val pos: PointInt, val color: Int)
|
||||
|
||||
interface KuyoTransform {
|
||||
data class Move(val src: PointInt, val dst: PointInt, val color: Int) : KuyoTransform {
|
||||
val csrc = ColoredPoint(src, color)
|
||||
val cdst = ColoredPoint(dst, color)
|
||||
}
|
||||
|
||||
data class Swap(val src: ColoredPoint, val dst: ColoredPoint) : KuyoTransform
|
||||
data class Explode(val items: List<PointInt>) : KuyoTransform
|
||||
data class Place(val item: KuyoItem) : KuyoTransform
|
||||
}
|
||||
|
||||
fun KuyoBoard.swap(p1: PointInt, p2: PointInt): KuyoStep<KuyoTransform.Swap> {
|
||||
return kuyoStep { dst, transforms ->
|
||||
val c1 = dst[p1]
|
||||
val c2 = dst[p2]
|
||||
dst[p1] = c2
|
||||
dst[p2] = c1
|
||||
transforms += KuyoTransform.Swap(ColoredPoint(p1, c1), ColoredPoint(p2, c2))
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : KuyoTransform> KuyoBoard.kuyoStep(callback: (dst: KuyoBoard, transforms: ArrayList<T>) -> Unit): KuyoStep<T> {
|
||||
val src = this
|
||||
val dst = this.clone()
|
||||
val transforms = arrayListOf<T>()
|
||||
callback(dst, transforms)
|
||||
return KuyoStep(src, dst, transforms)
|
||||
}
|
||||
|
||||
fun KuyoBoard.gravity(): KuyoStep<KuyoTransform.Move> {
|
||||
val src = this
|
||||
val dst = this.clone()
|
||||
val transforms = arrayListOf<KuyoTransform.Move>()
|
||||
for (x in 0 until width) {
|
||||
for (y in height - 1 downTo 0) {
|
||||
val posSrc = PointInt(x, y)
|
||||
val color = dst[posSrc]
|
||||
// We have a chip here
|
||||
if (color != EMPTY) {
|
||||
// Try moving down as much as possible
|
||||
for (y2 in 1 until height + 1 - y) {
|
||||
val posDst = PointInt(x, y + y2)
|
||||
val posDstPrev = PointInt(x, y + y2 - 1)
|
||||
val c = dst[posDst]
|
||||
if (c != EMPTY) {
|
||||
if (posSrc != posDstPrev) {
|
||||
dst[posSrc] = EMPTY
|
||||
dst[posDstPrev] = color
|
||||
transforms += KuyoTransform.Move(posSrc, posDstPrev, color)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return KuyoStep(src, dst, transforms)
|
||||
}
|
||||
|
||||
fun KuyoBoard.explode(): KuyoStep<KuyoTransform.Explode> {
|
||||
val src = this
|
||||
val dst = this.clone()
|
||||
val transforms = arrayListOf<KuyoTransform.Explode>()
|
||||
val explored = hashSetOf<PointInt>()
|
||||
|
||||
fun explore(p: PointInt): List<PointInt> {
|
||||
if (p in explored) return listOf()
|
||||
explored += p
|
||||
val color = dst[p]
|
||||
|
||||
val deltas = listOf(PointInt(-1, 0), PointInt(+1, 0), PointInt(0, -1), PointInt(0, +1))
|
||||
val nexts = deltas.map { p + it }
|
||||
|
||||
return listOf(p) + nexts.filter { dst[it] == color }.flatMap { explore(it) }
|
||||
}
|
||||
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until height) {
|
||||
val p = PointInt(x, y)
|
||||
if (p !in explored && dst[p] != EMPTY) {
|
||||
val items = explore(p)
|
||||
if (items.size >= 4) {
|
||||
transforms += KuyoTransform.Explode(items)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (pos in transforms.flatMap { it.items }) {
|
||||
dst[pos] = EMPTY
|
||||
}
|
||||
|
||||
return KuyoStep(src, dst, transforms)
|
||||
}
|
||||
|
||||
fun KuyoBoard._canPlace(drop: KuyoDrop, placing: Boolean): Boolean {
|
||||
for (item in drop.shape.items) {
|
||||
val puyoPos = drop.pos + item.pos
|
||||
if (placing && puyoPos.y < 0) return false
|
||||
if (this[puyoPos] != EMPTY) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun KuyoBoard.canMove(drop: KuyoDrop): Boolean = _canPlace(drop, false)
|
||||
fun KuyoBoard.canPlace(drop: KuyoDrop): Boolean = _canPlace(drop, true)
|
||||
|
||||
fun KuyoBoard.place(drop: KuyoDrop): KuyoStep<KuyoTransform.Place> {
|
||||
val src = this
|
||||
val dst = this.clone()
|
||||
val transforms = arrayListOf<KuyoTransform.Place>()
|
||||
for (item in drop.transformedItems) {
|
||||
dst[item.pos] = item.color
|
||||
transforms += KuyoTransform.Place(item)
|
||||
}
|
||||
return KuyoStep(src, dst, transforms)
|
||||
}
|
||||
|
||||
fun KuyoDrop.tryMove(delta: PointInt, board: KuyoBoard): KuyoDrop? {
|
||||
val newDrop = this.displaced(delta)
|
||||
return if (board.canMove(newDrop)) newDrop else null
|
||||
}
|
||||
|
||||
fun KuyoDrop.tryRotate(direction: Int, board: KuyoBoard): KuyoDrop? {
|
||||
val deltas = listOf(PointInt(0, 0), PointInt(-1, 0), PointInt(+1, 0), PointInt(0, -1))
|
||||
for (delta in deltas) {
|
||||
val newDrop = this.displaced(delta).rotated(direction)
|
||||
if (board.canMove(newDrop)) return newDrop
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun KuyoDrop.moveOrHold(delta: PointInt, board: KuyoBoard): KuyoDrop = tryMove(delta, board) ?: this
|
||||
fun KuyoDrop.rotateOrHold(direction: Int, board: KuyoBoard): KuyoDrop = tryRotate(direction, board) ?: this
|
||||
|
||||
/////////////// UTILS
|
||||
|
||||
fun boardString(vararg lines: String): String = board(*lines).toBoardString()
|
||||
|
||||
fun board(vararg lines: String): KuyoBoard {
|
||||
fun Char.toId(): Int = when (this) {
|
||||
'1' -> 1
|
||||
'2' -> 2
|
||||
'3' -> 3
|
||||
'4' -> 4
|
||||
'5' -> 5
|
||||
'0', '.' -> 0
|
||||
else -> 0
|
||||
}
|
||||
|
||||
val board = KuyoBoard(Array2(lines.first().length, lines.size) { 0 })
|
||||
for (y in 0 until board.height) {
|
||||
for (x in 0 until board.width) {
|
||||
board.board[x, y] = lines[y][x].toId()
|
||||
}
|
||||
}
|
||||
return board
|
||||
}
|
||||
|
||||
fun KuyoBoard.toBoardString(): String {
|
||||
val out = arrayListOf<String>()
|
||||
for (y in 0 until height) {
|
||||
var line = ""
|
||||
for (x in 0 until width) {
|
||||
val v = this[PointInt(x, y)]
|
||||
line += when (v) {
|
||||
0 -> '.'
|
||||
else -> '0' + v
|
||||
}
|
||||
}
|
||||
out += line
|
||||
}
|
||||
return out.joinToString("\n")
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package org.korge.sample.kuyo.util
|
||||
|
||||
import com.soywiz.korio.async.*
|
||||
import com.soywiz.korio.concurrent.lock.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class JobQueue(val context: CoroutineContext = EmptyCoroutineContext) {
|
||||
private val lock = Lock()
|
||||
private val tasks = arrayListOf<suspend () -> Unit>()
|
||||
var running = false; private set
|
||||
private var currentJob: Job? = null
|
||||
val size: Int get() = tasks.size + (if (running) 1 else 0)
|
||||
|
||||
private suspend fun run() {
|
||||
running = true
|
||||
try {
|
||||
|
||||
while (true) {
|
||||
val task = lock { if (tasks.isNotEmpty()) tasks.removeAt(0) else null } ?: break
|
||||
val job = launch(context) { task() }
|
||||
currentJob = job
|
||||
job.join()
|
||||
currentJob = null
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
println(e)
|
||||
} finally {
|
||||
currentJob = null
|
||||
running = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards all the queued but non running tasks
|
||||
*/
|
||||
fun discard(): JobQueue {
|
||||
lock { tasks.clear() }
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards all the queued tasks and cancels the running one, sending a complete signal.
|
||||
* If complete=true, a tween for example will be set directly to the end step
|
||||
* If complete=false, a tween for example will stop to the current step
|
||||
*/
|
||||
fun cancel(complete: Boolean = false): JobQueue {
|
||||
currentJob?.cancel(CancelException(complete))
|
||||
return this
|
||||
}
|
||||
|
||||
fun cancelComplete() = cancel(true)
|
||||
|
||||
fun queue(callback: suspend () -> Unit) {
|
||||
lock { tasks += callback }
|
||||
if (!running) launch(context) { run() }
|
||||
}
|
||||
|
||||
fun discard(callback: suspend () -> Unit) {
|
||||
discard()
|
||||
queue(callback)
|
||||
}
|
||||
|
||||
operator fun invoke(callback: suspend () -> Unit) = queue(callback)
|
||||
}
|
||||
|
||||
open class CancelException(val complete: Boolean = false) : kotlinx.coroutines.CancellationException(null)
|
||||
@@ -1,51 +0,0 @@
|
||||
package org.korge.sample.kuyo.util
|
||||
|
||||
import com.soywiz.kds.iterators.*
|
||||
|
||||
/*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korio.error.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
class ParallelJob {
|
||||
@PublishedApi
|
||||
internal val jobs = arrayListOf<suspend () -> Unit>()
|
||||
|
||||
fun sequence(job: suspend () -> Unit) {
|
||||
jobs += job
|
||||
}
|
||||
}
|
||||
|
||||
suspend inline fun parallel(callback: ParallelJob.() -> Unit) {
|
||||
val pj = ParallelJob()
|
||||
callback(pj)
|
||||
parallel(*pj.jobs.toTypedArray())
|
||||
}
|
||||
|
||||
fun JobQueue.discard(callback: suspend () -> Unit) = discard().queue(callback)
|
||||
|
||||
fun View.timer(time: Double, callback: (TimerComponent) -> Unit): TimerComponent {
|
||||
val component = TimerComponent(this, time, callback)
|
||||
addComponent(component)
|
||||
return component
|
||||
}
|
||||
|
||||
suspend fun View.delay(time: Double) = suspendCoroutine<Unit> { c ->
|
||||
timer(time) {
|
||||
it.setTime()
|
||||
c.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun JobQueue.await() = suspendCoroutine<Unit> { c ->
|
||||
queue { c.resume(Unit) }
|
||||
}
|
||||
*/
|
||||
|
||||
inline fun <T, R> List<T>.firstNotNullOrNull(block: (T) -> R?): R? {
|
||||
this.fastForEach {
|
||||
val result = block(it)
|
||||
if (result != null) return result
|
||||
}
|
||||
return null
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 818 KiB |
@@ -1,164 +0,0 @@
|
||||
info face="Arial" size=50 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=0,0
|
||||
common lineHeight=58 base=49 scaleW=384 scaleH=320 pages=1 packed=0
|
||||
page id=0 file="font1.png"
|
||||
chars count=95
|
||||
char id=32 x=48 y=98 width=0 height=0 xoffset=0 yoffset=46 xadvance=14 page=0 chnl=0
|
||||
char id=33 x=42 y=274 width=10 height=40 xoffset=5 yoffset=10 xadvance=14 page=0 chnl=0
|
||||
char id=34 x=356 y=130 width=18 height=18 xoffset=3 yoffset=8 xadvance=18 page=0 chnl=0
|
||||
char id=35 x=348 y=2 width=32 height=42 xoffset=1 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=36 x=96 y=46 width=28 height=50 xoffset=2 yoffset=5 xadvance=28 page=0 chnl=0
|
||||
char id=37 x=2 y=98 width=44 height=42 xoffset=3 yoffset=9 xadvance=45 page=0 chnl=0
|
||||
char id=38 x=56 y=214 width=36 height=42 xoffset=3 yoffset=8 xadvance=34 page=0 chnl=0
|
||||
char id=39 x=236 y=298 width=10 height=18 xoffset=3 yoffset=8 xadvance=10 page=0 chnl=0
|
||||
char id=40 x=210 y=228 width=16 height=52 xoffset=4 yoffset=8 xadvance=17 page=0 chnl=0
|
||||
char id=41 x=210 y=174 width=16 height=52 xoffset=4 yoffset=8 xadvance=17 page=0 chnl=0
|
||||
char id=42 x=210 y=282 width=22 height=20 xoffset=2 yoffset=8 xadvance=20 page=0 chnl=0
|
||||
char id=43 x=326 y=164 width=28 height=28 xoffset=3 yoffset=16 xadvance=30 page=0 chnl=0
|
||||
char id=44 x=368 y=164 width=10 height=18 xoffset=5 yoffset=39 xadvance=14 page=0 chnl=0
|
||||
char id=45 x=126 y=306 width=18 height=10 xoffset=2 yoffset=29 xadvance=17 page=0 chnl=0
|
||||
char id=46 x=146 y=306 width=10 height=10 xoffset=5 yoffset=40 xadvance=14 page=0 chnl=0
|
||||
char id=47 x=264 y=240 width=18 height=42 xoffset=0 yoffset=8 xadvance=14 page=0 chnl=0
|
||||
char id=48 x=158 y=176 width=28 height=42 xoffset=3 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=49 x=320 y=196 width=18 height=40 xoffset=6 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=50 x=218 y=88 width=28 height=40 xoffset=2 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=51 x=158 y=132 width=28 height=42 xoffset=3 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=52 x=126 y=88 width=30 height=40 xoffset=1 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=53 x=188 y=88 width=28 height=40 xoffset=3 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=54 x=158 y=88 width=28 height=42 xoffset=2 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=55 x=158 y=262 width=28 height=40 xoffset=3 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=56 x=126 y=262 width=28 height=42 xoffset=3 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=57 x=126 y=218 width=28 height=42 xoffset=3 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=58 x=356 y=164 width=10 height=30 xoffset=5 yoffset=20 xadvance=14 page=0 chnl=0
|
||||
char id=59 x=368 y=88 width=10 height=38 xoffset=5 yoffset=19 xadvance=14 page=0 chnl=0
|
||||
char id=60 x=296 y=164 width=28 height=30 xoffset=3 yoffset=14 xadvance=30 page=0 chnl=0
|
||||
char id=61 x=316 y=238 width=28 height=20 xoffset=3 yoffset=19 xadvance=30 page=0 chnl=0
|
||||
char id=62 x=266 y=164 width=28 height=30 xoffset=3 yoffset=14 xadvance=30 page=0 chnl=0
|
||||
char id=63 x=126 y=174 width=28 height=42 xoffset=3 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=64 x=2 y=2 width=52 height=52 xoffset=3 yoffset=8 xadvance=51 page=0 chnl=0
|
||||
char id=65 x=56 y=128 width=38 height=40 xoffset=0 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=66 x=272 y=46 width=32 height=40 xoffset=4 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=67 x=56 y=170 width=36 height=42 xoffset=3 yoffset=8 xadvance=37 page=0 chnl=0
|
||||
char id=68 x=126 y=46 width=34 height=40 xoffset=4 yoffset=10 xadvance=37 page=0 chnl=0
|
||||
char id=69 x=238 y=46 width=32 height=40 xoffset=4 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=70 x=348 y=46 width=30 height=40 xoffset=5 yoffset=10 xadvance=31 page=0 chnl=0
|
||||
char id=71 x=2 y=274 width=38 height=42 xoffset=3 yoffset=8 xadvance=39 page=0 chnl=0
|
||||
char id=72 x=312 y=2 width=34 height=40 xoffset=5 yoffset=10 xadvance=37 page=0 chnl=0
|
||||
char id=73 x=44 y=232 width=10 height=40 xoffset=5 yoffset=10 xadvance=14 page=0 chnl=0
|
||||
char id=74 x=210 y=130 width=24 height=42 xoffset=2 yoffset=8 xadvance=25 page=0 chnl=0
|
||||
char id=75 x=276 y=2 width=34 height=40 xoffset=4 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=76 x=158 y=220 width=28 height=40 xoffset=4 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=77 x=2 y=232 width=40 height=40 xoffset=4 yoffset=10 xadvance=42 page=0 chnl=0
|
||||
char id=78 x=240 y=2 width=34 height=40 xoffset=4 yoffset=10 xadvance=37 page=0 chnl=0
|
||||
char id=79 x=2 y=188 width=40 height=42 xoffset=3 yoffset=8 xadvance=39 page=0 chnl=0
|
||||
char id=80 x=204 y=46 width=32 height=40 xoffset=4 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=81 x=2 y=142 width=40 height=44 xoffset=3 yoffset=8 xadvance=39 page=0 chnl=0
|
||||
char id=82 x=56 y=258 width=36 height=40 xoffset=4 yoffset=10 xadvance=37 page=0 chnl=0
|
||||
char id=83 x=132 y=2 width=34 height=42 xoffset=3 yoffset=8 xadvance=34 page=0 chnl=0
|
||||
char id=84 x=204 y=2 width=34 height=40 xoffset=2 yoffset=10 xadvance=31 page=0 chnl=0
|
||||
char id=85 x=96 y=2 width=34 height=42 xoffset=4 yoffset=8 xadvance=37 page=0 chnl=0
|
||||
char id=86 x=56 y=86 width=38 height=40 xoffset=1 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=87 x=2 y=56 width=52 height=40 xoffset=1 yoffset=10 xadvance=48 page=0 chnl=0
|
||||
char id=88 x=56 y=44 width=38 height=40 xoffset=1 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=89 x=56 y=2 width=38 height=40 xoffset=1 yoffset=10 xadvance=34 page=0 chnl=0
|
||||
char id=90 x=168 y=2 width=34 height=40 xoffset=2 yoffset=10 xadvance=31 page=0 chnl=0
|
||||
char id=91 x=300 y=238 width=14 height=50 xoffset=4 yoffset=9 xadvance=14 page=0 chnl=0
|
||||
char id=92 x=264 y=196 width=18 height=42 xoffset=0 yoffset=8 xadvance=14 page=0 chnl=0
|
||||
char id=93 x=284 y=250 width=14 height=50 xoffset=1 yoffset=9 xadvance=14 page=0 chnl=0
|
||||
char id=94 x=340 y=196 width=26 height=24 xoffset=2 yoffset=9 xadvance=24 page=0 chnl=0
|
||||
char id=95 x=306 y=78 width=34 height=8 xoffset=0 yoffset=51 xadvance=28 page=0 chnl=0
|
||||
char id=96 x=158 y=304 width=14 height=12 xoffset=3 yoffset=8 xadvance=17 page=0 chnl=0
|
||||
char id=97 x=296 y=130 width=28 height=32 xoffset=2 yoffset=18 xadvance=28 page=0 chnl=0
|
||||
char id=98 x=126 y=130 width=28 height=42 xoffset=4 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=99 x=266 y=130 width=28 height=32 xoffset=2 yoffset=18 xadvance=25 page=0 chnl=0
|
||||
char id=100 x=96 y=274 width=28 height=42 xoffset=2 yoffset=8 xadvance=28 page=0 chnl=0
|
||||
char id=101 x=236 y=130 width=28 height=32 xoffset=2 yoffset=18 xadvance=28 page=0 chnl=0
|
||||
char id=102 x=188 y=238 width=20 height=42 xoffset=1 yoffset=8 xadvance=14 page=0 chnl=0
|
||||
char id=103 x=96 y=230 width=28 height=42 xoffset=2 yoffset=18 xadvance=28 page=0 chnl=0
|
||||
char id=104 x=276 y=88 width=26 height=40 xoffset=4 yoffset=10 xadvance=28 page=0 chnl=0
|
||||
char id=105 x=44 y=188 width=10 height=40 xoffset=4 yoffset=10 xadvance=12 page=0 chnl=0
|
||||
char id=106 x=284 y=196 width=14 height=52 xoffset=-2 yoffset=8 xadvance=12 page=0 chnl=0
|
||||
char id=107 x=248 y=88 width=26 height=40 xoffset=4 yoffset=10 xadvance=25 page=0 chnl=0
|
||||
char id=108 x=44 y=142 width=10 height=40 xoffset=4 yoffset=10 xadvance=12 page=0 chnl=0
|
||||
char id=109 x=162 y=46 width=40 height=32 xoffset=4 yoffset=18 xadvance=42 page=0 chnl=0
|
||||
char id=110 x=236 y=264 width=26 height=32 xoffset=4 yoffset=18 xadvance=28 page=0 chnl=0
|
||||
char id=111 x=304 y=88 width=30 height=32 xoffset=2 yoffset=18 xadvance=28 page=0 chnl=0
|
||||
char id=112 x=96 y=186 width=28 height=42 xoffset=4 yoffset=17 xadvance=28 page=0 chnl=0
|
||||
char id=113 x=96 y=142 width=28 height=42 xoffset=2 yoffset=17 xadvance=28 page=0 chnl=0
|
||||
char id=114 x=188 y=282 width=20 height=32 xoffset=4 yoffset=18 xadvance=17 page=0 chnl=0
|
||||
char id=115 x=236 y=230 width=26 height=32 xoffset=2 yoffset=18 xadvance=25 page=0 chnl=0
|
||||
char id=116 x=300 y=196 width=18 height=40 xoffset=1 yoffset=10 xadvance=14 page=0 chnl=0
|
||||
char id=117 x=236 y=196 width=26 height=32 xoffset=4 yoffset=18 xadvance=28 page=0 chnl=0
|
||||
char id=118 x=236 y=164 width=28 height=30 xoffset=1 yoffset=20 xadvance=25 page=0 chnl=0
|
||||
char id=119 x=306 y=46 width=40 height=30 xoffset=1 yoffset=20 xadvance=37 page=0 chnl=0
|
||||
char id=120 x=336 y=88 width=30 height=30 xoffset=1 yoffset=20 xadvance=25 page=0 chnl=0
|
||||
char id=121 x=96 y=98 width=28 height=42 xoffset=1 yoffset=18 xadvance=25 page=0 chnl=0
|
||||
char id=122 x=326 y=130 width=28 height=30 xoffset=1 yoffset=20 xadvance=25 page=0 chnl=0
|
||||
char id=123 x=188 y=184 width=20 height=52 xoffset=2 yoffset=8 xadvance=17 page=0 chnl=0
|
||||
char id=124 x=316 y=260 width=8 height=52 xoffset=5 yoffset=8 xadvance=13 page=0 chnl=0
|
||||
char id=125 x=188 y=130 width=20 height=52 xoffset=2 yoffset=8 xadvance=17 page=0 chnl=0
|
||||
char id=126 x=56 y=300 width=30 height=14 xoffset=3 yoffset=22 xadvance=30 page=0 chnl=0
|
||||
kernings count=64
|
||||
kerning first=86 second=117 amount=-1
|
||||
kerning first=84 second=97 amount=-5
|
||||
kerning first=84 second=99 amount=-5
|
||||
kerning first=87 second=65 amount=-1
|
||||
kerning first=80 second=65 amount=-3
|
||||
kerning first=86 second=101 amount=-2
|
||||
kerning first=89 second=111 amount=-4
|
||||
kerning first=87 second=44 amount=-2
|
||||
kerning first=84 second=111 amount=-5
|
||||
kerning first=89 second=112 amount=-3
|
||||
kerning first=84 second=65 amount=-3
|
||||
kerning first=80 second=44 amount=-6
|
||||
kerning first=87 second=46 amount=-2
|
||||
kerning first=89 second=113 amount=-4
|
||||
kerning first=76 second=84 amount=-3
|
||||
kerning first=80 second=46 amount=-6
|
||||
kerning first=76 second=121 amount=-1
|
||||
kerning first=76 second=86 amount=-3
|
||||
kerning first=84 second=114 amount=-1
|
||||
kerning first=76 second=87 amount=-3
|
||||
kerning first=84 second=58 amount=-5
|
||||
kerning first=84 second=44 amount=-5
|
||||
kerning first=84 second=115 amount=-5
|
||||
kerning first=76 second=89 amount=-3
|
||||
kerning first=84 second=46 amount=-5
|
||||
kerning first=89 second=117 amount=-2
|
||||
kerning first=89 second=97 amount=-3
|
||||
kerning first=119 second=44 amount=-2
|
||||
kerning first=84 second=117 amount=-1
|
||||
kerning first=89 second=118 amount=-2
|
||||
kerning first=114 second=44 amount=-2
|
||||
kerning first=89 second=101 amount=-4
|
||||
kerning first=49 second=49 amount=-3
|
||||
kerning first=86 second=121 amount=-1
|
||||
kerning first=119 second=46 amount=-2
|
||||
kerning first=84 second=119 amount=-2
|
||||
kerning first=84 second=101 amount=-5
|
||||
kerning first=114 second=46 amount=-2
|
||||
kerning first=86 second=97 amount=-3
|
||||
kerning first=89 second=65 amount=-3
|
||||
kerning first=89 second=105 amount=-1
|
||||
kerning first=118 second=44 amount=-3
|
||||
kerning first=65 second=84 amount=-3
|
||||
kerning first=84 second=105 amount=-1
|
||||
kerning first=65 second=86 amount=-3
|
||||
kerning first=65 second=87 amount=-1
|
||||
kerning first=118 second=46 amount=-3
|
||||
kerning first=65 second=89 amount=-3
|
||||
kerning first=70 second=65 amount=-2
|
||||
kerning first=89 second=58 amount=-2
|
||||
kerning first=89 second=44 amount=-6
|
||||
kerning first=86 second=65 amount=-3
|
||||
kerning first=86 second=111 amount=-2
|
||||
kerning first=89 second=46 amount=-6
|
||||
kerning first=121 second=44 amount=-3
|
||||
kerning first=87 second=97 amount=-1
|
||||
kerning first=70 second=44 amount=-5
|
||||
kerning first=84 second=121 amount=-2
|
||||
kerning first=86 second=114 amount=-1
|
||||
kerning first=86 second=58 amount=-1
|
||||
kerning first=86 second=44 amount=-4
|
||||
kerning first=70 second=46 amount=-5
|
||||
kerning first=121 second=46 amount=-3
|
||||
kerning first=86 second=46 amount=-4
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 120 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 195 KiB |
@@ -1,231 +0,0 @@
|
||||
package mmo.minigames.kuyo
|
||||
|
||||
import com.soywiz.korma.geom.*
|
||||
import org.korge.sample.kuyo.model.*
|
||||
import kotlin.test.*
|
||||
|
||||
class KuyoModelTest {
|
||||
@Test
|
||||
fun gravity1() {
|
||||
boardShouldBe(
|
||||
board(
|
||||
".3.5",
|
||||
"1...",
|
||||
"...4",
|
||||
".2.."
|
||||
),
|
||||
{ it.gravity().dst },
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
".3.5",
|
||||
"12.4"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun gravity2() {
|
||||
boardShouldBe(
|
||||
board(
|
||||
"1111",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
),
|
||||
{ it.gravity().dst },
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"1111"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun gravity3() {
|
||||
transformsShouldBe(
|
||||
board(
|
||||
"1111",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
),
|
||||
{ it.gravity().transforms },
|
||||
"[Move(src=(0, 0), dst=(0, 3), color=1), Move(src=(1, 0), dst=(1, 3), color=1), Move(src=(2, 0), dst=(2, 3), color=1), Move(src=(3, 0), dst=(3, 3), color=1)]"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun explode1() {
|
||||
boardShouldBe(
|
||||
board(
|
||||
"1111",
|
||||
"2222",
|
||||
"3331",
|
||||
".111"
|
||||
),
|
||||
{ it.explode().dst },
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"333.",
|
||||
"...."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun explode2() {
|
||||
transformsShouldBe(
|
||||
board(
|
||||
"1111",
|
||||
"1...",
|
||||
"...1",
|
||||
".111"
|
||||
),
|
||||
{ it.explode().transforms },
|
||||
"[Explode(items=[(0, 0), (1, 0), (2, 0), (3, 0), (0, 1)]), Explode(items=[(1, 3), (2, 3), (3, 3), (3, 2)])]"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun place1() {
|
||||
val drop = KuyoDrop(PointInt(0, 1), KuyoShape2(1, 2))
|
||||
|
||||
boardShouldBe(
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
),
|
||||
{ it.place(drop).dst },
|
||||
board(
|
||||
"2...",
|
||||
"1...",
|
||||
"....",
|
||||
"...."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun place2() {
|
||||
val drop = KuyoDrop(PointInt(0, 0), KuyoShape2(1, 2))
|
||||
|
||||
boardShouldBe(
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
),
|
||||
{ it.place(drop.rotatedRight()).dst },
|
||||
board(
|
||||
"12..",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun place3() {
|
||||
val drop = KuyoDrop(PointInt(0, 0), KuyoShape2(1, 2))
|
||||
|
||||
boardShouldBe(
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
),
|
||||
{ it.place(drop.moveOrHold(PointInt(0, +1), it)).dst },
|
||||
board(
|
||||
"2...",
|
||||
"1...",
|
||||
"....",
|
||||
"...."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun place4() {
|
||||
boardShouldBe(
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"...."
|
||||
),
|
||||
{ it.place(KuyoDrop(PointInt(1, 1), KuyoShape2(1, 2))).dst },
|
||||
board(
|
||||
".2..",
|
||||
".1..",
|
||||
"....",
|
||||
"...."
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun swap2() {
|
||||
boardShouldBe(
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"1234"
|
||||
),
|
||||
{ it.swap(PointInt(1, 3), PointInt(2, 3)).dst },
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"1324"
|
||||
)
|
||||
)
|
||||
transformsShouldBe(
|
||||
board(
|
||||
"....",
|
||||
"....",
|
||||
"....",
|
||||
"1234"
|
||||
),
|
||||
{ it.swap(PointInt(1, 3), PointInt(2, 3)).transforms },
|
||||
"[Swap(src=ColoredPoint(pos=(1, 3), color=2), dst=ColoredPoint(pos=(2, 3), color=3))]"
|
||||
)
|
||||
}
|
||||
|
||||
//@Test
|
||||
//fun placeGravity1() {
|
||||
// val drop = KuyoDrop(IPoint(1, 0), KuyoShape2(1, 2))
|
||||
|
||||
// val board = board(
|
||||
// "....",
|
||||
// "....",
|
||||
// "....",
|
||||
// "...."
|
||||
// )
|
||||
|
||||
// assertEquals(
|
||||
// "...",
|
||||
// //board.place(drop).dst.gravity().transforms.toString()
|
||||
// board.place(drop).dst.gravity().dst.toBoardString()
|
||||
// )
|
||||
//}
|
||||
}
|
||||
|
||||
fun boardShouldBe(src: KuyoBoard, transform: (KuyoBoard) -> KuyoBoard, dst: KuyoBoard) {
|
||||
assertEquals(dst.toBoardString(), transform(src).toBoardString())
|
||||
}
|
||||
|
||||
fun transformsShouldBe(src: KuyoBoard, transform: (KuyoBoard) -> List<KuyoTransform>, dst: String) {
|
||||
assertEquals(dst, transform(src).toString().simplifyVectorToString())
|
||||
}
|
||||
|
||||
private fun String.simplifyVectorToString() = this.replace(Regex("IVector2Int\\(x=(\\d+), y=(\\d+)\\)"), "($1, $2)")
|
||||
@@ -1,21 +0,0 @@
|
||||
package mmo.minigames.kuyo
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
/*
|
||||
class KuyoTest {
|
||||
@Test
|
||||
fun name() = testSceneApplication(KuyoScene(seed = 0L)) {
|
||||
board.dropping.moveDownOrPlace()
|
||||
board.queue.await()
|
||||
assertEquals("(80.0, 48.0)", "(${board.dropping.views[0].x}, ${board.dropping.views[0].y})")
|
||||
board.dropping.moveDownOrPlace()
|
||||
board.queue.await()
|
||||
assertEquals(
|
||||
"KuyoDrop(pos=(2, 2), shape=KuyoShape2(k1=KuyoItem(pos=(0, 0), color=1), k2=KuyoItem(pos=(0, -1), color=1)))",
|
||||
board.dropping.dropModel.toString()
|
||||
)
|
||||
assertEquals("(80.0, 80.0)", "(${board.dropping.views[0].x}, ${board.dropping.views[0].y})")
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -1,6 +0,0 @@
|
||||
package mmo.minigames.kuyo
|
||||
|
||||
import org.korge.sample.kuyo.*
|
||||
|
||||
//fun main(args: Array<String>) = Kuyo.SkinTester.main(args)
|
||||
//suspend fun main(args: Array<String>) = Kuyo.main(args)
|
||||
@@ -1,23 +0,0 @@
|
||||
package mmo.minigames.kuyo
|
||||
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korinject.*
|
||||
import kotlinx.coroutines.*
|
||||
import org.korge.sample.kuyo.*
|
||||
import kotlin.reflect.*
|
||||
|
||||
object SkinTester {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
runBlocking {
|
||||
Korge(Korge.Config(object : Module() {
|
||||
override val mainScene: KClass<out Scene> = TestPuyoScene::class
|
||||
|
||||
override suspend fun AsyncInjector.configure() {
|
||||
mapPrototype { TestPuyoScene() }
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user