mirror of
https://github.com/jlengrand/korge-samples.git
synced 2026-03-10 08:31:18 +00:00
Many fixes and improvements for samples (#30)
* Update deprecated stuff * Improve output formatting in input sample * Update bmpfont sample * Remove korio sample * Update filter sample * Translate comments and fix code in minesweeper sample * Stylish fixes in onscreen-controller sample * Stylish fixes in pong sample * Support replaying voice on click in lipsync sample * Move graphics view from box2d sample to shapes sample, add a few other shapes * Small improvements for spriteanim and sprites10k samples * Small stylish improvements for tictactoe-swf sample * Small improvements for triangulation and ui samples * Update korgePluginVersion
This commit is contained in:
committed by
GitHub
parent
f373adaef8
commit
0372c748c7
@@ -1,6 +1,5 @@
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.tween.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korim.color.*
|
||||
import com.soywiz.korge.animate.*
|
||||
@@ -27,14 +26,14 @@ suspend fun main() = Korge(width = 512, height = 512, virtualWidth = 512, virtua
|
||||
wait()
|
||||
parallel {
|
||||
//rect1.moveTo(0, 150)
|
||||
rect1.moveToWithSpeed(512 - 100, 0)
|
||||
rect2.moveToWithSpeed(0, 512 - 100 - 100)
|
||||
rect1.moveToWithSpeed(512.0 - 100, 0.0)
|
||||
rect2.moveToWithSpeed(0.0, 512.0 - 100 - 100)
|
||||
//rect1.moveTo(0, height - 100)
|
||||
}
|
||||
parallel {
|
||||
//rect1.moveTo(0, 150)
|
||||
rect1.moveTo(512 - 100, 512 - 100)
|
||||
rect2.moveTo(512 - 100, 512 - 100)
|
||||
rect1.moveTo(512.0 - 100, 512.0 - 100)
|
||||
rect2.moveTo(512.0 - 100, 512.0 - 100)
|
||||
//rect1.moveTo(0, height - 100)
|
||||
}
|
||||
parallel(time = 1.seconds) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import com.soywiz.kds.*
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.klock.hr.hrMicroseconds
|
||||
import com.soywiz.klock.hr.hrMilliseconds
|
||||
import com.soywiz.klock.hr.*
|
||||
import com.soywiz.korev.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.view.*
|
||||
@@ -89,7 +88,7 @@ suspend fun main() = Korge(
|
||||
// bullet.delayFrame()
|
||||
// }
|
||||
//}
|
||||
bullet.addUpdater { bulletFrame(it) }
|
||||
bullet.addUpdater { bulletFrame(it) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +97,7 @@ suspend fun main() = Korge(
|
||||
|
||||
class Asteroid(val assets: Assets, val asteroidSize: Int = 3) : Image(assets.asteroidBitmap) {
|
||||
var angle = 30.degrees
|
||||
|
||||
init {
|
||||
anchor(.5, .5)
|
||||
scale = asteroidSize.toDouble() / 3.0
|
||||
@@ -144,8 +144,6 @@ fun View.advance(amount: Double, rot: Angle = (-90).degrees) = this.apply {
|
||||
y += (this.rotation + rot).sine * amount
|
||||
}
|
||||
|
||||
inline fun View.advance(amount: Number, rot: Angle = (-90).degrees) = advance(amount.toDouble(), rot)
|
||||
|
||||
class Assets(val views: Views, val shipSize: Int = 24) {
|
||||
val asteroidSize = shipSize * 2
|
||||
val shipBitmap = NativeImage(shipSize, shipSize).context2d {
|
||||
@@ -164,8 +162,8 @@ class Assets(val views: Views, val shipSize: Int = 24) {
|
||||
lineWidth = 1.0
|
||||
lineCap = LineCap.ROUND
|
||||
stroke(Colors.WHITE) {
|
||||
moveTo(width / 2, 0)
|
||||
lineToV(height)
|
||||
moveTo(width / 2.0, 0.0)
|
||||
lineToV(height.toDouble())
|
||||
}
|
||||
}
|
||||
val asteroidBitmap = Bitmap32(asteroidSize, asteroidSize).context2d { // Let's use software vector rendering here, for testing purposes
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.atlas.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korio.*
|
||||
import com.soywiz.korio.dynamic.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
|
||||
suspend fun main() = Korge(width = 640, height = 480, virtualWidth = 320, virtualHeight = 240) {
|
||||
@@ -10,7 +8,7 @@ suspend fun main() = Korge(width = 640, height = 480, virtualWidth = 320, virtua
|
||||
}
|
||||
|
||||
suspend fun Stage.atlasMain() {
|
||||
val logos = resourcesVfs["logos.atlas.json"].readAtlas(views)
|
||||
val logos = resourcesVfs["logos.atlas.json"].readAtlas()
|
||||
image(logos["korau.png"]).position(0, 0)
|
||||
image(logos["korim.png"]).position(64, 32)
|
||||
image(logos["korge.png"]).position(128, 64)
|
||||
|
||||
@@ -9,19 +9,22 @@ import com.soywiz.korio.file.std.*
|
||||
|
||||
suspend fun main() = Korge(bgcolor = Colors["#333"]) {
|
||||
val font1 = resourcesVfs["font1.fnt"].readBitmapFont()
|
||||
text("Hello World!", textSize = 128.0, font = font1)
|
||||
val text1 = text("Hello World!", textSize = 96.0, font = font1)
|
||||
val text2 = text("Hello World!", textSize = 96.0, font = font1) {
|
||||
filtering = false
|
||||
alignTopToBottomOf(text1)
|
||||
}
|
||||
val text3 = text("Hello World!", textSize = 96.0, font = font1) {
|
||||
filter = Convolute3Filter(Convolute3Filter.KERNEL_GAUSSIAN_BLUR)
|
||||
alignTopToBottomOf(text2)
|
||||
}
|
||||
text("Hello World 2!", textSize = 32.0, font = font1) {
|
||||
val text = this
|
||||
fun center() {
|
||||
position(views.virtualWidth / 2 - width.toInt() / 2, views.virtualHeight / 2)
|
||||
}
|
||||
//filter = Convolute3Filter(Convolute3Filter.KERNEL_GAUSSIAN_BLUR)
|
||||
center()
|
||||
launchImmediately {
|
||||
var n = 0
|
||||
while (true) {
|
||||
text.text = "Hello World! ${n++}"
|
||||
center()
|
||||
centerOn(root)
|
||||
delay(1.milliseconds)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "My
|
||||
|
||||
println("STARTED!")
|
||||
|
||||
addUpdatable {
|
||||
addUpdater {
|
||||
//println("FRAME!")
|
||||
}
|
||||
|
||||
@@ -33,28 +33,16 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "My
|
||||
}
|
||||
|
||||
views.clearColor = Colors.DARKGREEN
|
||||
solidRect(300, 200, Colors.DARKCYAN)
|
||||
sgraphics {
|
||||
fill(Colors.DARKCYAN) {
|
||||
rect(-1, -1, 3, 2)
|
||||
}
|
||||
fill(Colors.AQUAMARINE) {
|
||||
circle(0, 0, 1)
|
||||
}
|
||||
fill(Colors.AQUAMARINE) {
|
||||
circle(1, 0, 1)
|
||||
}
|
||||
position(100, 100)
|
||||
}.scale(100, 100).interactive()
|
||||
|
||||
worldView {
|
||||
position(400, 400).scale(20)
|
||||
position(400, 400).scale(20.0)
|
||||
|
||||
createBody {
|
||||
setPosition(0, -10)
|
||||
}.fixture {
|
||||
shape = BoxShape(100, 20)
|
||||
density = 0f
|
||||
}.setViewWithContainer(solidRect(100, 20, Colors.RED).position(-50, -10).interactive())
|
||||
}.setView(solidRect(100, 20, Colors.RED).position(-50, -10).interactive())
|
||||
|
||||
// Dynamic Body
|
||||
createBody {
|
||||
@@ -64,7 +52,7 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "My
|
||||
shape = BoxShape(2f, 2f)
|
||||
density = 0.5f
|
||||
friction = 0.2f
|
||||
}.setView(solidRect(2f, 2f, Colors.GREEN).anchor(.5, .5).interactive())
|
||||
}.setView(solidRect(2.0, 2.0, Colors.GREEN).anchor(.5, .5).interactive())
|
||||
|
||||
createBody {
|
||||
type = BodyType.DYNAMIC
|
||||
@@ -88,11 +76,11 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "My
|
||||
friction = 3f
|
||||
}.setView(sgraphics {
|
||||
fillStroke(ColorPaint(Colors.BLUE), ColorPaint(Colors.RED), Context2d.StrokeInfo(thickness = 0.3)) {
|
||||
circle(0, 0, 2)
|
||||
circle(0.0, 0.0, 2.0)
|
||||
//rect(0, 0, 400, 20)
|
||||
}
|
||||
fill(Colors.DARKCYAN) {
|
||||
circle(1, 1, 0.2)
|
||||
circle(1.0, 1.0, 0.2)
|
||||
}
|
||||
hitTestUsingShapes = true
|
||||
}.interactive())
|
||||
@@ -100,7 +88,7 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "My
|
||||
image(resourcesVfs["korge.png"].readBitmap())
|
||||
}
|
||||
|
||||
fun <T : View> T.interactive(): T = this.apply {
|
||||
fun <T : View> T.interactive(): T = apply {
|
||||
alpha = 0.5
|
||||
onOver { alpha = 1.0 }
|
||||
onOut { alpha = 0.5 }
|
||||
|
||||
@@ -1,29 +1,86 @@
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.animate.*
|
||||
import com.soywiz.korge.tween.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korge.view.filter.*
|
||||
import com.soywiz.korim.color.*
|
||||
import com.soywiz.korim.format.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
import com.soywiz.korma.geom.*
|
||||
import com.soywiz.korma.interpolation.*
|
||||
|
||||
suspend fun main() = Korge(width = 512, height = 512, bgcolor = Colors["#2b2b2b"]) {
|
||||
val minDegrees = (-16).degrees
|
||||
val maxDegrees = (+16).degrees
|
||||
suspend fun main() = Korge(width = 768, height = 512, bgcolor = Colors["#2b2b2b"]) {
|
||||
val bitmap = resourcesVfs["korge.png"].readBitmap()
|
||||
|
||||
val wave = WaveFilter()
|
||||
val image = image(resourcesVfs["korge.png"].readBitmap()) {
|
||||
rotation = maxDegrees
|
||||
anchor(.5, .5)
|
||||
scale(.8)
|
||||
position(256, 256)
|
||||
image(bitmap) {
|
||||
scale(.5)
|
||||
position(0, 0)
|
||||
filter = wave
|
||||
}
|
||||
|
||||
while (true) {
|
||||
image.tween(image::rotation[minDegrees], wave::time[1.seconds], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
image.tween(image::rotation[maxDegrees], wave::time[0.seconds], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
val blur = BlurFilter()
|
||||
image(bitmap) {
|
||||
scale(.5)
|
||||
position(256, 0)
|
||||
filter = blur
|
||||
}
|
||||
|
||||
val color = ColorMatrixFilter(ColorMatrixFilter.GRAYSCALE_MATRIX)
|
||||
image(bitmap) {
|
||||
scale(.5)
|
||||
position(512, 0)
|
||||
filter = color
|
||||
}
|
||||
|
||||
val page = PageFilter()
|
||||
image(bitmap) {
|
||||
scale(.5)
|
||||
position(0, 256)
|
||||
filter = page
|
||||
}
|
||||
|
||||
val conImg = image(bitmap) {
|
||||
scale(.5)
|
||||
position(256, 256)
|
||||
filter = Convolute3Filter(Convolute3Filter.KERNEL_SHARPEN)
|
||||
}
|
||||
|
||||
val swizzle = SwizzleColorsFilter()
|
||||
image(bitmap) {
|
||||
scale(.5)
|
||||
position(512, 256)
|
||||
filter = swizzle
|
||||
}
|
||||
|
||||
animateParallel {
|
||||
sequence(looped = true) {
|
||||
tween(wave::time[1.seconds], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
tween(wave::time[0.seconds], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
}
|
||||
sequence(looped = true) {
|
||||
tween(blur::radius[16], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
tween(blur::radius[0], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
}
|
||||
sequence(looped = true) {
|
||||
tween(color::blendRatio[0], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
tween(color::blendRatio[1], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
}
|
||||
sequence(looped = true) {
|
||||
tween(page::hratio[0], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
tween(page::hratio[1], time = 1.seconds, easing = Easing.EASE_IN_OUT)
|
||||
}
|
||||
sequence(looped = true) {
|
||||
block { conImg.filter = Convolute3Filter(Convolute3Filter.KERNEL_SHARPEN) }
|
||||
wait(1.seconds)
|
||||
block { conImg.filter = Convolute3Filter(Convolute3Filter.KERNEL_IDENTITY) }
|
||||
wait(1.seconds)
|
||||
}
|
||||
sequence(looped = true) {
|
||||
arrayOf("rgga", "bgga", "bgba", "grba", "gbba", "gbga", "bbga").forEach {
|
||||
block { swizzle.swizzle = it }
|
||||
wait(0.5.seconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
korgePluginVersion=1.13.3.0
|
||||
korgePluginVersion=1.13.8.0
|
||||
#korgeVersion=1.13.3-SNAPSHOT
|
||||
#korviVersion=0.2.1-SNAPSHOT
|
||||
#korimVersion=1.12.25-SNAPSHOT
|
||||
|
||||
@@ -6,14 +6,14 @@ import com.soywiz.korge.view.*
|
||||
|
||||
suspend fun main() = Korge {
|
||||
var line = 0
|
||||
fun textLine(text: String) = text(text).position(0, line++ * 16).apply { this.filtering = false }
|
||||
fun nowUnix() = DateTime.now().unixMillisLong
|
||||
fun textLine(text: String) = text(text).position(2, line++ * 20 + 5).apply { filtering = false }
|
||||
fun nowTime() = DateTime.now().local.format(DateFormat("HH:mm:ss.SSS"))
|
||||
|
||||
textLine("Events :")
|
||||
val keysEvText = textLine("KeysEv")
|
||||
val keysEvText = textLine("Keys")
|
||||
val keysDownText = textLine("Keys:Down")
|
||||
val keysUpText = textLine("Keys:Up")
|
||||
val mouseEvText = textLine("Mouse1")
|
||||
val mouseEvText = textLine("Mouse")
|
||||
val mouseMoveText = textLine("MouseMove")
|
||||
val mouseDownText = textLine("MouseDown")
|
||||
val mouseUpText = textLine("MouseUp")
|
||||
@@ -25,12 +25,12 @@ suspend fun main() = Korge {
|
||||
val gamepadUpdateText = textLine("GamepadUpdateEv")
|
||||
val gamepadUpdate2Text = textLine("GamepadUpdate2Ev")
|
||||
|
||||
//stage.addEventListener<KeyEvent> { keysEvText.text = "${nowUnix()}:$it" }
|
||||
//stage.addEventListener<MouseEvent> { mouseEvText.text = "${nowUnix()}:$it" }
|
||||
//stage.addEventListener<ReshapeEvent> { resizeText.text = "${nowUnix()}:$it" }
|
||||
//stage.addEventListener<GamePadConnectionEvent> { gamepadConnectedText.text = "${nowUnix()}:$it" }
|
||||
//stage.addEventListener<KeyEvent> { keysEvText.text = "${nowTime()}:$it" }
|
||||
//stage.addEventListener<MouseEvent> { mouseEvText.text = "${nowTime()}:$it" }
|
||||
stage.addEventListener<ReshapeEvent> { resizeText.text = "Resize ${nowTime()} $it" }
|
||||
//stage.addEventListener<GamePadConnectionEvent> { gamepadConnectedText.text = "${nowTime()}:$it" }
|
||||
//stage.addEventListener<GamePadUpdateEvent> {
|
||||
// gamepadUpdateText.text = "${nowUnix()}:$it"
|
||||
// gamepadUpdateText.text = "${nowTime()}:$it"
|
||||
// gamepadUpdate2Text.text = "" + it.gamepads.lastOrNull { it.connected }?.rawButtonsPressed
|
||||
//}
|
||||
|
||||
@@ -40,14 +40,14 @@ suspend fun main() = Korge {
|
||||
}
|
||||
|
||||
keys {
|
||||
onKeyDown { keysDownText.text = "Key:Down:${nowUnix()}:${it.key}" }
|
||||
onKeyUp { keysUpText.text = "Key:Up:${nowUnix()}:${it.key}" }
|
||||
onKeyDown { keysDownText.text = "Key:Down ${nowTime()} ${it.key}" }
|
||||
onKeyUp { keysUpText.text = "Key:Up ${nowTime()} ${it.key}" }
|
||||
}
|
||||
|
||||
mouse {
|
||||
onMove { mouseMoveText.text = "Mouse:Move:${nowUnix()}:$it" }
|
||||
onDown { mouseDownText.text = "Mouse:Down:${nowUnix()}:$it" }
|
||||
onUp { mouseUpText.text = "Mouse:Up:${nowUnix()}:$it" }
|
||||
onClick { mouseClickText.text = "Mouse:Click:${nowUnix()}:$it" }
|
||||
onMove { mouseMoveText.text = "Mouse:Move ${nowTime()} $it" }
|
||||
onDown { mouseDownText.text = "Mouse:Down ${nowTime()} $it" }
|
||||
onUp { mouseUpText.text = "Mouse:Up ${nowTime()} $it" }
|
||||
onClick { mouseClickText.text = "Mouse:Click ${nowTime()} $it" }
|
||||
}
|
||||
}
|
||||
|
||||
1
korio/.gitignore
vendored
1
korio/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/build
|
||||
@@ -1,7 +0,0 @@
|
||||
import com.soywiz.korge.gradle.*
|
||||
|
||||
apply<KorgeGradlePlugin>()
|
||||
|
||||
korge {
|
||||
id = "com.soywiz.samples.korio"
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import com.soywiz.korio.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
|
||||
suspend fun main() = Korio {
|
||||
println(resourcesVfs["hello.txt"].readString())
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
HELLO WORLD
|
||||
@@ -1,7 +0,0 @@
|
||||
import kotlin.test.*
|
||||
|
||||
class SimpleTest {
|
||||
@Test
|
||||
fun test() {
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import com.soywiz.korio.dynamic.*
|
||||
import java.net.*
|
||||
|
||||
object Main2 {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
val cl = ClassLoader.getSystemClassLoader()
|
||||
val data = KDynamic { cl["ucp"]["path"] } as List<URL>
|
||||
println(data)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.korev.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.atlas.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.lipsync.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korio.async.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
|
||||
suspend fun main() = Korge {
|
||||
val atlas = resourcesVfs["lips.atlas.json"].readAtlas(views)
|
||||
val atlas = resourcesVfs["lips.atlas.json"].readAtlas()
|
||||
val lips = image(atlas["lisa-A.png"])
|
||||
val lips2 = image(atlas["lisa-A.png"]).position(400, 0)
|
||||
addEventListener<LipSyncEvent> {
|
||||
@@ -16,10 +18,12 @@ suspend fun main() = Korge {
|
||||
lips2.texture = atlas["lisa-${it.lip}.png"]
|
||||
}
|
||||
}
|
||||
launchImmediately {
|
||||
fun handler(it: LipSyncEvent) {
|
||||
views.dispatch(it)
|
||||
lips.texture = atlas["lisa-${it.lip}.png"]
|
||||
var playing = true
|
||||
fun play() = launchImmediately {
|
||||
fun handler(event: LipSyncEvent) {
|
||||
views.dispatch(event)
|
||||
lips.texture = atlas["lisa-${event.lip}.png"]
|
||||
playing = event.time > 0.milliseconds
|
||||
}
|
||||
|
||||
resourcesVfs["001.voice.wav"].readVoice().play("lisa") { handler(it) }
|
||||
@@ -28,4 +32,9 @@ suspend fun main() = Korge {
|
||||
//resourcesVfs["004.voice.wav"].readVoice().play("lisa") { handler(it) }
|
||||
//resourcesVfs["simple.voice.mp3"].readVoice().play("lisa") { handler(it) }
|
||||
}
|
||||
|
||||
onClick {
|
||||
if (!playing) play()
|
||||
}
|
||||
play()
|
||||
}
|
||||
|
||||
@@ -10,177 +10,171 @@ import com.soywiz.korio.lang.*
|
||||
import com.soywiz.korma.random.*
|
||||
import kotlin.random.*
|
||||
|
||||
// Proceso que se encarga del tablero
|
||||
open class Board(
|
||||
// Process of the board
|
||||
class Board(
|
||||
parent: Container,
|
||||
val imageset: BmpSlice,
|
||||
val imagenes: List<BmpSlice>,
|
||||
val imageSet: BmpSlice,
|
||||
val imageSlices: List<BmpSlice>,
|
||||
val click: NativeSound,
|
||||
val boom: NativeSound,
|
||||
// Se establecen el ancho, el alto y la cantidad de minas
|
||||
// Características del tablero: ancho, alto, cantidad de minas
|
||||
var bwidth: Int,
|
||||
var bheight: Int,
|
||||
var minas: Int
|
||||
// Width, height and quantity of mines are established
|
||||
// Board characteristics: width, height, number of mines
|
||||
val bwidth: Int,
|
||||
val bheight: Int,
|
||||
var mineNumber: Int
|
||||
) : Process(parent) {
|
||||
// Matriz con el tablero
|
||||
// Matrix with board
|
||||
var board: Array<IntArray> = arrayOf()
|
||||
// Matriz de máscara (indica que partes del tablero están destapadas)
|
||||
// Mask matrix (indicates which parts of the board are uncovered)
|
||||
var mask: Array<BooleanArray> = arrayOf()
|
||||
// Matriz de marcado (indica que partes del tablero están marcadas como "posible mina") (click derecho)
|
||||
// Marking matrix (indicates which parts of the board are marked as "possible mine") (right click)
|
||||
var mark: Array<BooleanArray> = arrayOf()
|
||||
|
||||
// Variables utilizadas para el contador
|
||||
var stime: DateTime = DateTime.EPOCH
|
||||
// Variables used for the counter
|
||||
var tstart: DateTime = DateTime.EPOCH
|
||||
var tstop: DateTime = DateTime.EPOCH
|
||||
var timeText: Text
|
||||
|
||||
var lastx: Int = 0
|
||||
var lasty: Int = 0
|
||||
|
||||
// Constructor del proceso en el cual se le pasan el ancho, el alto y la cantidad de minas
|
||||
override var width = bwidth * imageSet.height.toDouble()
|
||||
override var height = bheight * imageSet.height.toDouble()
|
||||
|
||||
init {
|
||||
// Se crea el texto del contador
|
||||
// Creating text with time
|
||||
//timeText = new Text("", 50, 50, Text.Align.center, Text.Align.middle, Color.white, new Font("Arial", 40));
|
||||
//timeText = Text("", 50, 50, Text.Align.center, Text.Align.middle, Color.white, Font.fromResource("font.ttf", 40));
|
||||
val FONT_HEIGHT = 32.0
|
||||
timeText = text("", textSize = FONT_HEIGHT).xy((bwidth * imageset.height) / 2, -FONT_HEIGHT).apply {
|
||||
format = Html.Format(align = Html.Alignment.CENTER, size = FONT_HEIGHT.toInt())
|
||||
//format = Html.Format(align = Html.Alignment.CENTER, face = defaultUIFont)
|
||||
val FONT_HEIGHT = 24.0
|
||||
timeText = text("00:00", textSize = FONT_HEIGHT).apply {
|
||||
centerXBetween(0.0, this@Board.width)
|
||||
y = -FONT_HEIGHT - 5
|
||||
format.align = Html.Alignment.CENTER
|
||||
}
|
||||
// Se pinta el contador como hijo del tablero
|
||||
//timeText.group.z = this;
|
||||
// Y se actualiza su texto
|
||||
updateTimeText()
|
||||
|
||||
// Se centra el tablero en la pantalla
|
||||
x = Screen.width / 2 - (bwidth * imageset.height) / 2
|
||||
y = Screen.height / 2 - (bheight * imageset.height - 10 - FONT_HEIGHT) / 2
|
||||
//The board is centered on the screen
|
||||
//x = screen.width / 2 - width / 2
|
||||
//y = screen.height / 2 - (height - 10 - FONT_HEIGHT) / 2
|
||||
centerOnStage()
|
||||
y += FONT_HEIGHT / 2
|
||||
|
||||
// Se establecen algunas características del texto, posición, borde y sombra
|
||||
//timeText.shadow = 5;
|
||||
//timeText.border = 1;
|
||||
|
||||
// Se reinicia el tablero
|
||||
clear()
|
||||
// Restart board
|
||||
restart()
|
||||
}
|
||||
|
||||
// Destructor, aquí se quita el texto cuando se borra el tablero
|
||||
override protected fun onDestroy() {
|
||||
// Destructor, the text is removed when the board is being destroyed
|
||||
override fun onDestroy() {
|
||||
timeText.removeFromParent()
|
||||
}
|
||||
|
||||
// Devuelve el tiempo actual (en milisegundos)
|
||||
// Returns the current time
|
||||
val time: DateTime get() = DateTime.now()
|
||||
|
||||
// Resetea el contador
|
||||
fun resetTimer() {
|
||||
stime = time
|
||||
tstart = time
|
||||
tstop = DateTime.EPOCH
|
||||
}
|
||||
|
||||
// Para el contador
|
||||
fun stopTimer() {
|
||||
tstop = time
|
||||
}
|
||||
|
||||
// Devuelve el tiempo ha pasado en segundos desde que se inició el contador
|
||||
// Returns the time in seconds that has passed since the timer started
|
||||
val elapsed: Int
|
||||
get() = run {
|
||||
var ctime = time
|
||||
if (tstop != DateTime.EPOCH) ctime = tstop
|
||||
return (ctime - stime).seconds.toInt()
|
||||
return (ctime - tstart).seconds.toInt()
|
||||
}
|
||||
|
||||
// Actualiza el texto del contador con el formato %02d:%02d MM:SS
|
||||
// Update the counter text in the format %02d:%02d MM:SS
|
||||
fun updateTimeText() {
|
||||
timeText.text = "%02d:%02d".format(elapsed / 60, elapsed % 60)
|
||||
}
|
||||
|
||||
// Función que se encarga de borrar el tablero y crear uno nuevo
|
||||
fun clear() {
|
||||
// Ahora que vamos a borrar un nuevo tablero (y que vamos a crear una nueva partida)
|
||||
// reiniciamos el contador
|
||||
// Function that is responsible for deleting the board and creating a new one
|
||||
fun restart() {
|
||||
//Now that we are going to delete a new board (and that we are going to create a new game)
|
||||
//we reset the timer
|
||||
resetTimer()
|
||||
|
||||
// Creamos las matrices con el tablero, la máscara de visión y la máscara de marcado (de posibles minas)
|
||||
// We create the matrices with the board, the vision mask and the marking mask (of possible mines)
|
||||
board = Array(bheight) { IntArray(bwidth) }
|
||||
mask = Array(bheight) { BooleanArray(bwidth) }
|
||||
mark = Array(bheight) { BooleanArray(bwidth) }
|
||||
|
||||
// Comprobamos que no se intenten colocar mas minas que posiciones hay, evitando así un bucle infinito
|
||||
// en realidad solo se colocan como mucho una cantidad de minas igual a las posiciones del tablero - 1
|
||||
// para que pueda haber partida (si no se ganaría directamente)
|
||||
if (minas > bwidth * bheight - 1) minas = bwidth * bheight - 1
|
||||
// We check that there are no attempts to place more mines than there are positions, thus avoiding an infinite loop
|
||||
// actually only a maximum number of mines equal to the board positions - 1 are placed
|
||||
if (mineNumber > bwidth * bheight - 1) mineNumber = bwidth * bheight - 1
|
||||
|
||||
// Ahora procederemos a colocar las minas en el tablero
|
||||
for (n in 0 until minas) {
|
||||
// Declaramos px, py que utilizaremos para almacenar las posiciones temporales de la mina
|
||||
var px: Int = 0
|
||||
var py: Int = 0
|
||||
// Now we will proceed to place the mines on the board
|
||||
repeat(mineNumber) {
|
||||
// We declare px and py that we will use to store the temporary positions of a mine
|
||||
var px: Int
|
||||
var py: Int
|
||||
do {
|
||||
// Obtenemos una posible posición de la mina
|
||||
// We get a possible mine position
|
||||
px = Random[0, bwidth - 1]
|
||||
py = Random[0, bheight - 1]
|
||||
// Comprobamos si en esa posición hay una mina y estaremos buscando posiciones hasta
|
||||
// que en esa posición no haya mina
|
||||
// We check if there is a mine in that position and we will be looking for positions until
|
||||
// there is no mine in that position
|
||||
} while (board[py][px] == 10)
|
||||
|
||||
// Ahora que sabemos que en esa posición no hay mina, colocamos una
|
||||
// Now that we know that there is no mine in that position, we place it
|
||||
board[py][px] = 10
|
||||
}
|
||||
|
||||
// Ahora que hemos colocado las minas, vamos a colocar los números alrededor de ellas
|
||||
// Esta es una parte interesante del buscaminas, aquí se colcan los numeros alrededor de las minas
|
||||
// Now that we have placed the mines, we are going to place the numbers around them
|
||||
// This is an interesting part of the minesweeper, here the numbers are placed around the mines
|
||||
|
||||
// Nos recorremos el tablero entero
|
||||
// We go over the entire board
|
||||
for (y in 0 until bheight) {
|
||||
for (x in 0 until bwidth) {
|
||||
// Comprobamos que en esa posición no haya mina, si hay mina, "pasamos", hacemos un continue y seguimos a la siguiente posición
|
||||
// sin ejecutar lo que viene después
|
||||
// We check that there is no mine in that position, if there is a mine, we "pass":
|
||||
// we continue to the next position without processing this one
|
||||
if (board[y][x] == 10) continue
|
||||
|
||||
// Ahora vamos a contar las minas que hay alrededor de esta posición (ya que en esta posición no hay mina y es posible que tengamos
|
||||
// que poner un número si tiene alguna mina contigua)
|
||||
// Now we are going to count the mines around this position
|
||||
// (since there is no mine in this position and we may have to put a number if it has a contiguous mine)
|
||||
var count = 0
|
||||
// Recorremos con x1 € [-1,1], y1 € [-1, 1]
|
||||
for (y1 in -1..+1) {
|
||||
for (x1 in -1..+1) {
|
||||
// Ahora x + x1 y y + y1 tomaran posiciones de la matriz contiguas a la posición actual
|
||||
// empezando por x - 1, y - 1 para acabar en x + 1, y + 1
|
||||
// Comprobamos que la posición esté dentro de la matriz, ya que por ejemplo en la posición 0
|
||||
// la posición 0 - 1, 0 - 1, sería la -1, -1, que no está dentro de la matriz y si no está dentro
|
||||
// de los límites de la matriz, pasamos
|
||||
if (!in_bounds(x + x1, y + y1)) continue
|
||||
// Si en esta posición contigua hay una mina entonces incrementamos el contador
|
||||
// Now x + x1 and y + y1 will take matrix positions contiguous to the current position
|
||||
// from x - 1, y - 1 to x + 1, y + 1
|
||||
// We check that the position is inside the matrix, since for example in position 0
|
||||
// 0 - 1, 0 - 1 would be -1, -1, which is not inside the matrix
|
||||
// so if it is not inside the limits of the matrix, we pass
|
||||
if (!inBounds(x + x1, y + y1)) continue
|
||||
// If there is a mine in this adjacent position, we increase the counter
|
||||
if (board[y + y1][x + x1] == 10) count++
|
||||
}
|
||||
}
|
||||
|
||||
// Introducimos en el tablero la nueva imagen (puesto que la imagen con 0 posiciones es la 1 y las siguientes
|
||||
// son 1, 2, 3, 4, 5, 6, 7, 8) ponemos la imagen correspondiente a count + 1
|
||||
// We introduce the new image on the board (since the image with 0 positions is 1
|
||||
// and the following are 1, 2, 3, 4, 5, 6, 7, 8) we put the corresponding image to count + 1
|
||||
board[y][x] = count + 1
|
||||
}
|
||||
}
|
||||
|
||||
// Ahora ya tenemos el tablero preparado
|
||||
// Now we have the board ready
|
||||
}
|
||||
|
||||
// Indica si una posición está dentro de la matriz
|
||||
fun in_bounds(px: Int, py: Int): Boolean {
|
||||
// Si la posición es negativa o si la posición está mas a la derecha del ancho del tablero, devuelve false (no está dentro)
|
||||
// Indicates if a position is inside the matrix
|
||||
fun inBounds(px: Int, py: Int): Boolean {
|
||||
// If the x position is negative or if the position is more to the right of the width of the board,
|
||||
// it returns false (it is not inside)
|
||||
if (px < 0 || px >= bwidth) return false
|
||||
// Si ocurre lo mismo con la posición y, también devolvemos false
|
||||
// If the same thing happens with the y position, we also return false
|
||||
if (py < 0 || py >= bheight) return false
|
||||
// Si no hemos devuelto ya false, quiere decir que la posición si que está dentro del tablero, así que devolvemos true
|
||||
// If we have not already returned false, it means the position is inside the board, so we return true
|
||||
return true
|
||||
}
|
||||
|
||||
var fillpos = 0
|
||||
|
||||
// Rellena una posición (recursivamente; la forma mas clara y sencilla)
|
||||
// Fill in a position (recursively, the clearest and simplest form)
|
||||
suspend fun fill(px: Int, py: Int) {
|
||||
if (!in_bounds(px, py)) return
|
||||
if (!inBounds(px, py)) return
|
||||
if (mask[py][px] || mark[py][px]) return
|
||||
mask[py][px] = true
|
||||
|
||||
@@ -199,17 +193,15 @@ open class Board(
|
||||
fill(px - 1, py + 1)
|
||||
}
|
||||
|
||||
suspend fun show_board_lose() {
|
||||
// Subfunción de show_board_lose que se encarga de
|
||||
// desenmascarar una posición despues de comprobar
|
||||
// si es correcta
|
||||
suspend fun showBoardLose() {
|
||||
// It's a sub-function that unmasks a position after checking for correctness
|
||||
fun unmask(x: Int, y: Int): Boolean {
|
||||
if (!in_bounds(x, y)) return false
|
||||
if (!inBounds(x, y)) return false
|
||||
mask[y][x] = true
|
||||
return true
|
||||
}
|
||||
|
||||
// Propagación con forma de diamante
|
||||
// Diamond shaped propagation
|
||||
var dist = 0
|
||||
while (true) {
|
||||
var drawing = false
|
||||
@@ -225,11 +217,10 @@ open class Board(
|
||||
|
||||
dist++
|
||||
frame()
|
||||
//if (dist >= max(width * 2, height * 2)) break;
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun show_board_win() {
|
||||
suspend fun showBoardWin() {
|
||||
for (y in 0 until bheight) {
|
||||
for (x in 0 until bwidth) {
|
||||
if (board[y][x] == 10) {
|
||||
@@ -244,15 +235,15 @@ open class Board(
|
||||
}
|
||||
|
||||
suspend fun check(px: Int, py: Int): Boolean {
|
||||
if (!in_bounds(px, py)) return false
|
||||
if (!inBounds(px, py)) return false
|
||||
|
||||
// Guardamos la última posición en la que hicimos click
|
||||
// We save the last position that was clicked
|
||||
lastx = px; lasty = py
|
||||
|
||||
// Estamos ante una mina
|
||||
// The next is a mine
|
||||
if (board[py][px] == 10) return true
|
||||
|
||||
// Estamos ante una casilla vacía
|
||||
// The next is an empty box
|
||||
if (board[py][px] == 1) {
|
||||
fps = 140.0
|
||||
fillpos = 0
|
||||
@@ -269,8 +260,8 @@ open class Board(
|
||||
return false
|
||||
}
|
||||
|
||||
// Comprueba si el tablero está en un estado en el cual podemos dar por ganada la partida
|
||||
fun check_win(): Boolean {
|
||||
// Check if the board is in a state when we can consider the game won
|
||||
fun checkWin(): Boolean {
|
||||
var count = 0
|
||||
for (y in 0 until bheight) {
|
||||
for (x in 0 until bwidth) {
|
||||
@@ -278,30 +269,30 @@ open class Board(
|
||||
}
|
||||
}
|
||||
|
||||
return (count == bwidth * bheight - minas)
|
||||
return (count == bwidth * bheight - mineNumber)
|
||||
}
|
||||
|
||||
// La acción principal redirecciona a la acción de juego
|
||||
// The main action redirects to the game action
|
||||
override suspend fun main() = action(::play)
|
||||
|
||||
// La acción principal de juego que se encarga de gestionar los clicks de ratón
|
||||
// The main game action that is responsible for managing mouse clicks
|
||||
suspend fun play() {
|
||||
while (true) {
|
||||
//println("Mouse.x: ${Mouse.x}, x=$x")
|
||||
if (Mouse.x >= x && Mouse.x < x + bwidth * imageset.height) {
|
||||
if (Mouse.y >= y && Mouse.y < y + bheight * imageset.height) {
|
||||
val px = ((Mouse.x - x) / imageset.height).toInt()
|
||||
val py = ((Mouse.y - y) / imageset.height).toInt()
|
||||
if (mouse.x >= x && mouse.x < x + bwidth * imageSet.height) {
|
||||
if (mouse.y >= y && mouse.y < y + bheight * imageSet.height) {
|
||||
val px = ((mouse.x - x) / imageSet.height).toInt()
|
||||
val py = ((mouse.y - y) / imageSet.height).toInt()
|
||||
|
||||
if (Mouse.released[0]) {
|
||||
if (mouse.released[0]) {
|
||||
if (!mark[py][px]) {
|
||||
if (check(px, py)) {
|
||||
action(::lose)
|
||||
} else if (check_win()) {
|
||||
} else if (checkWin()) {
|
||||
action(::win)
|
||||
}
|
||||
}
|
||||
} else if (Mouse.released[1] || Mouse.released[2]) {
|
||||
} else if (mouse.released[1] || mouse.released[2]) {
|
||||
mark[py][px] = !mark[py][px]
|
||||
}
|
||||
}
|
||||
@@ -311,15 +302,15 @@ open class Board(
|
||||
}
|
||||
}
|
||||
|
||||
// Acción del tablero que ocurre cuando el jugador ha perdido
|
||||
// Board action that occurs when the player has lost
|
||||
suspend fun lose() {
|
||||
audio.play(boom, 0)
|
||||
stopTimer()
|
||||
show_board_lose()
|
||||
showBoardLose()
|
||||
|
||||
while (true) {
|
||||
if (Mouse.left || Mouse.right) {
|
||||
clear()
|
||||
if (mouse.left || mouse.right) {
|
||||
restart()
|
||||
for (n in 0 until 10) frame()
|
||||
action(::play)
|
||||
}
|
||||
@@ -327,14 +318,14 @@ open class Board(
|
||||
}
|
||||
}
|
||||
|
||||
// Acción del tablero que ocurre cuando el jugador ha ganado
|
||||
// Board action that occurs when the player has won
|
||||
suspend fun win() {
|
||||
stopTimer()
|
||||
show_board_win()
|
||||
showBoardWin()
|
||||
|
||||
while (true) {
|
||||
if (Mouse.left || Mouse.right) {
|
||||
clear()
|
||||
if (mouse.left || mouse.right) {
|
||||
restart()
|
||||
for (n in 0 until 10) frame()
|
||||
action(::play)
|
||||
}
|
||||
@@ -344,7 +335,7 @@ open class Board(
|
||||
|
||||
val images = Array(bheight) { py ->
|
||||
Array(bwidth) { px ->
|
||||
image(Bitmaps.transparent).xy(px * imageset.height, py * imageset.height).scale(0.9)
|
||||
image(Bitmaps.transparent).xy(px * imageSet.height, py * imageSet.height).scale(0.9)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,15 +343,14 @@ open class Board(
|
||||
for (py in 0 until bheight) {
|
||||
for (px in 0 until bwidth) {
|
||||
val image = if (!mask[py][px]) {
|
||||
imagenes[if (mark[py][px]) 11 else 0]
|
||||
imageSlices[if (mark[py][px]) 11 else 0]
|
||||
} else {
|
||||
imagenes[board[py][px]]
|
||||
imageSlices[board[py][px]]
|
||||
}
|
||||
|
||||
images[py][px].texture = image
|
||||
}
|
||||
}
|
||||
|
||||
super.renderInternal(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.soywiz.korge.samples.minesweeper
|
||||
|
||||
import com.soywiz.kds.*
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.kmem.*
|
||||
import com.soywiz.korau.sound.*
|
||||
import com.soywiz.korev.*
|
||||
@@ -11,7 +10,6 @@ import com.soywiz.korge.view.*
|
||||
import com.soywiz.korim.format.*
|
||||
import com.soywiz.korio.async.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
import com.soywiz.korma.geom.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.reflect.*
|
||||
|
||||
@@ -25,14 +23,11 @@ abstract class Process(parent: Container) : Container() {
|
||||
var fps: Double = 60.0
|
||||
|
||||
val key get() = stage.views.key
|
||||
val Mouse get() = views.mouseV
|
||||
val Screen get() = views.screenV
|
||||
val mouse get() = views.mouseV
|
||||
val audio get() = views.audioV
|
||||
|
||||
suspend fun frame() {
|
||||
delayFrame()
|
||||
//views.stage.delayFrame()
|
||||
//delay((1.0 / fps).seconds)
|
||||
}
|
||||
|
||||
fun action(action: KSuspendFunction0<Unit>) {
|
||||
@@ -78,23 +73,7 @@ abstract class Process(parent: Container) : Container() {
|
||||
|
||||
class ChangeActionException(val action: KSuspendFunction0<Unit>) : Exception()
|
||||
|
||||
inline fun <reified T : View> collision(): T? = views.stage.findCollision<T>(this)
|
||||
fun collision(matcher: (View) -> Boolean): View? = views.stage.findCollision(this, matcher)
|
||||
}
|
||||
|
||||
|
||||
inline fun <reified T : View> Container.findCollision(subject: View): T? = findCollision(subject) { it is T && it != subject } as T?
|
||||
|
||||
fun Container.findCollision(subject: View, matcher: (View) -> Boolean): View? {
|
||||
var collides: View? = null
|
||||
this.foreachDescendant {
|
||||
if (matcher(it)) {
|
||||
if (subject.collidesWith(it)) {
|
||||
collides = it
|
||||
}
|
||||
}
|
||||
}
|
||||
return collides
|
||||
inline fun <reified T : View> collision(): T? = views.stage.findCollision(this)
|
||||
}
|
||||
|
||||
class KeyV(val views: Views) {
|
||||
@@ -113,13 +92,10 @@ class MouseV(val views: Views) {
|
||||
val _released = BooleanArray(8)
|
||||
}
|
||||
|
||||
class ScreenV(val views: Views) {
|
||||
val width: Double get() = views.virtualWidth.toDouble()
|
||||
val height: Double get() = views.virtualHeight.toDouble()
|
||||
}
|
||||
|
||||
class AudioV(val views: Views) {
|
||||
fun play(sound: NativeSound, repeat: Int = 0) {
|
||||
val times = (1 + repeat).playbackTimes
|
||||
sound.play(times)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +103,6 @@ val Views.keysPressed by Extra.Property { LinkedHashMap<Key, Boolean>() }
|
||||
val Views.key by Extra.PropertyThis<Views, KeyV> { KeyV(this) }
|
||||
|
||||
val Views.mouseV by Extra.PropertyThis<Views, MouseV> { MouseV(this) }
|
||||
val Views.screenV by Extra.PropertyThis<Views, ScreenV> { ScreenV(this) }
|
||||
val Views.audioV by Extra.PropertyThis<Views, AudioV> { AudioV(this) }
|
||||
|
||||
fun Views.registerProcessSystem() {
|
||||
@@ -165,4 +140,4 @@ fun Views.registerProcessSystem() {
|
||||
}
|
||||
|
||||
suspend fun readImage(path: String) = resourcesVfs[path].readBitmapSlice()
|
||||
suspend fun readSound(path: String) = resourcesVfs[path].readNativeSoundOptimized()
|
||||
suspend fun readSound(path: String) = resourcesVfs[path].readSound()
|
||||
|
||||
@@ -22,18 +22,17 @@ class RandomLight(
|
||||
|
||||
init {
|
||||
image(light, 0.5, 0.5).apply {
|
||||
this.blendMode = BlendMode.ADD
|
||||
blendMode = BlendMode.ADD
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun main() {
|
||||
sx = random[-w2, w2]
|
||||
sy = random[-h2, h2]
|
||||
inca = random[0.0001, 0.03]
|
||||
incs = random[0.5, 2.0]
|
||||
excx = random[0.7, 1.3]
|
||||
excy = random[0.7, 1.3]
|
||||
alpha = random[0.4, 0.7]
|
||||
sx = random[-w2, w2]
|
||||
sy = random[-h2, h2]
|
||||
inca = random[0.0001, 0.03]
|
||||
incs = random[0.5, 2.0]
|
||||
excx = random[0.7, 1.3]
|
||||
excy = random[0.7, 1.3]
|
||||
alpha = 0.1
|
||||
|
||||
while (true) {
|
||||
@@ -42,8 +41,8 @@ class RandomLight(
|
||||
y = h2 - sin(rotationDegrees) * h2 * excy + sy
|
||||
scale = 1 + (cos(rotationDegrees) / 6) * incs
|
||||
|
||||
// Comprueba si una esfera de luz ha chocado con otra
|
||||
// El sistema de colisión por defecto es inner circle
|
||||
// Check if a light sphere collided with another one
|
||||
// The default collision system is inner circle
|
||||
if (this.collision<RandomLight>() != null) {
|
||||
alpha = (alpha + 0.01).coerceIn(0.1, 0.8)
|
||||
} else {
|
||||
@@ -53,15 +52,4 @@ class RandomLight(
|
||||
frame()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun fadeout() {
|
||||
while (alpha > 0) {
|
||||
alpha -= 0.1
|
||||
frame()
|
||||
}
|
||||
}
|
||||
|
||||
fun draw() {
|
||||
//graph.draw(__x, __y, alpha, 0, size, alpha, alpha, alpha, GL_ONE, GL_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,22 +27,21 @@ class MainProcess(parent: Container) : Process(parent) {
|
||||
override suspend fun main() {
|
||||
image(readImage("bg.jpg")).dockedTo(Anchor.TOP_LEFT, ScaleMode.EXACT)
|
||||
val light = readImage("light.png")
|
||||
val imageset = readImage("buscaminas.png")
|
||||
val imagenes = imageset.split(imageset.height, imageset.height)
|
||||
val imageSet = readImage("cells.png")
|
||||
val images = imageSet.split(imageSet.height, imageSet.height)
|
||||
val click = readSound("click.wav")
|
||||
val boom = readSound("boom.wav")
|
||||
|
||||
for (n in 0 until 20) {
|
||||
repeat(20) {
|
||||
lights += RandomLight(this, light)
|
||||
}
|
||||
|
||||
val board = Board(this, imageset, imagenes, click, boom, 22, 15, 40)
|
||||
val board = Board(this, imageSet, images, click, boom, 22, 15, 40)
|
||||
val nativeProcess = NativeProcess(views)
|
||||
|
||||
while (true) {
|
||||
if (key[Key.ESCAPE]) {
|
||||
nativeProcess.close()
|
||||
|
||||
}
|
||||
if (key[Key.UP]) {
|
||||
lights += RandomLight(this, light)
|
||||
|
||||
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
@@ -8,14 +8,27 @@ 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 -> }) {
|
||||
fun Container.addTouchGamepad(
|
||||
width: Double = 320.0,
|
||||
height: Double = 224.0,
|
||||
radius: Double = height / 8,
|
||||
onStick: (x: Double, y: Double) -> Unit = { _, _ -> },
|
||||
onButton: (button: Int, pressed: Boolean) -> Unit = { _, _ -> }
|
||||
) {
|
||||
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)
|
||||
position(radius * 1.1, height - radius * 1.1)
|
||||
graphics {
|
||||
fill(Colors.BLACK) { circle(0.0, 0.0, radius) }
|
||||
alpha(0.2)
|
||||
}
|
||||
ball = graphics {
|
||||
fill(Colors.WHITE) { circle(0.0, 0.0, radius * 0.7) }
|
||||
alpha(0.2)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : View> T.decorateButton(button: Int) = this.apply {
|
||||
@@ -35,7 +48,12 @@ fun Container.addTouchGamepad(width: Double = 320.0, height: Double = 224.0, rad
|
||||
}
|
||||
|
||||
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)
|
||||
graphics {
|
||||
position(width - radius * 1.1 - (diameter * n), height - radius * 1.1)
|
||||
fill(Colors.WHITE) { circle(0.0, 0.0, radius * 0.7) }
|
||||
alpha(0.2)
|
||||
decorateButton(n)
|
||||
}
|
||||
}
|
||||
|
||||
var dragging = false
|
||||
@@ -44,19 +62,19 @@ fun Container.addTouchGamepad(width: Double = 320.0, height: Double = 224.0, rad
|
||||
view.addComponent(object : MouseComponent {
|
||||
override val view: View = view
|
||||
|
||||
override fun onMouseEvent(views: Views, it: MouseEvent) {
|
||||
val px = view.globalMatrixInv.transformX(it.x.toDouble(), it.y.toDouble())
|
||||
val py = view.globalMatrixInv.transformY(it.x.toDouble(), it.y.toDouble())
|
||||
override fun onMouseEvent(views: Views, event: MouseEvent) {
|
||||
val px = view.globalMatrixInv.transformX(event.x.toDouble(), event.y.toDouble())
|
||||
val py = view.globalMatrixInv.transformY(event.x.toDouble(), event.y.toDouble())
|
||||
|
||||
when (it.type) {
|
||||
when (event.type) {
|
||||
MouseEvent.Type.DOWN -> {
|
||||
if (px >= width / 2) return@onMouseEvent
|
||||
if (px >= width / 2) return
|
||||
start.x = px
|
||||
start.y = py
|
||||
ball.alpha = 0.3
|
||||
dragging = true
|
||||
}
|
||||
MouseEvent.Type.DRAG -> {
|
||||
MouseEvent.Type.MOVE, MouseEvent.Type.DRAG -> {
|
||||
if (dragging) {
|
||||
val deltaX = px - start.x
|
||||
val deltaY = py - start.y
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
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 text1 = text("-").position(5, 5).apply { filtering = false }
|
||||
val buttonTexts = (0 until 2).map {
|
||||
text("-").position(0, 15 * (it + 1)).also { it.filtering = false }
|
||||
text("-").position(5, 20 * (it + 1) + 5).apply { filtering = false }
|
||||
}
|
||||
|
||||
addTouchGamepad(
|
||||
|
||||
@@ -1,37 +1,33 @@
|
||||
import com.soywiz.korev.Key
|
||||
import com.soywiz.korge.input.keys
|
||||
import com.soywiz.korge.input.onClick
|
||||
import com.soywiz.korge.scene.Scene
|
||||
import com.soywiz.korge.view.Container
|
||||
import com.soywiz.korge.view.text
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korge.ui.*
|
||||
import com.soywiz.korge.view.position
|
||||
import com.soywiz.korim.color.Colors
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korim.color.*
|
||||
|
||||
class MenuScene() : Scene() {
|
||||
suspend override fun Container.sceneInit() {
|
||||
// set a background color
|
||||
views.clearColor = Colors.BLACK
|
||||
suspend override fun Container.sceneInit() {
|
||||
// set a background color
|
||||
views.clearColor = Colors.BLACK
|
||||
|
||||
// Add a text to show the name of the game
|
||||
var gameNameText = text("Super Pong Bros II") {
|
||||
position(views.virtualWidth/2 - 128, views.virtualHeight/2 - 128)
|
||||
}
|
||||
// Add a text to show the name of the game
|
||||
var gameNameText = text("Super Pong Bros II") {
|
||||
position(views.virtualWidth / 2 - 128, views.virtualHeight / 2 - 128)
|
||||
}
|
||||
|
||||
var playButton = textButton(256.0, 32.0) {
|
||||
text = "Play"
|
||||
position(views.virtualWidth/2 - 128, views.virtualHeight/2 - 64)
|
||||
onClick {
|
||||
sceneContainer.changeToAsync<PlayScene>()
|
||||
}
|
||||
}
|
||||
var exitButton = textButton(256.0, 32.0) {
|
||||
text = "Exit"
|
||||
position(views.virtualWidth/2 - 128, views.virtualHeight/2)
|
||||
onClick {
|
||||
views.gameWindow.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
var playButton = textButton(256.0, 32.0) {
|
||||
text = "Play"
|
||||
position(views.virtualWidth / 2 - 128, views.virtualHeight / 2 - 64)
|
||||
onClick {
|
||||
sceneContainer.changeTo<PlayScene>()
|
||||
}
|
||||
}
|
||||
var exitButton = textButton(256.0, 32.0) {
|
||||
text = "Exit"
|
||||
position(views.virtualWidth / 2 - 128, views.virtualHeight / 2)
|
||||
onClick {
|
||||
views.gameWindow.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,208 +6,193 @@ import com.soywiz.korim.color.Colors
|
||||
import kotlin.math.*
|
||||
import kotlin.random.Random.Default.nextDouble
|
||||
|
||||
/* Define the various states that the game can be in */
|
||||
// Define the various states that the game can be in
|
||||
enum class GameStates {
|
||||
Starting, // The game is just starting and some helptext will be shown. Ball will not be moving
|
||||
Playing, // in this state the ball will be moving and player can score against each other
|
||||
Scored, // in this state the game will pause and show that a goal was cored
|
||||
Starting, // The game is just starting and some help text will be shown. Ball will not be moving
|
||||
Playing, // in this state the ball will be moving and player can score against each other
|
||||
Scored, // in this state the game will pause and show that a goal was cored
|
||||
}
|
||||
|
||||
class PlayScene() : Scene() {
|
||||
suspend override fun Container.sceneInit() {
|
||||
var fpsText: Text
|
||||
var scoredYellText: Text
|
||||
var tickSizeText: Text
|
||||
var helpText: Text
|
||||
var scoreLeftText: Text
|
||||
var scoreRightText: Text
|
||||
var paddleLeft: SolidRect
|
||||
var paddleRight: SolidRect
|
||||
var ball: Circle
|
||||
suspend override fun Container.sceneInit() {
|
||||
// Initialize the variables which will capture the game state
|
||||
var scorePlayerLeft = 0
|
||||
var scorePlayerRight = 0
|
||||
var playState = GameStates.Starting
|
||||
|
||||
/* Initialize the variables which will capture the game state*/
|
||||
var scorePlayerLeft = 0
|
||||
var scorePlayerRight = 0
|
||||
var playState = GameStates.Starting
|
||||
// Initialize the starting game state values
|
||||
val paddlePosYAtStart = views.virtualHeight / 2 - 50.0
|
||||
val ballPosXAtStart = views.virtualWidth / 2 - 10.0
|
||||
val ballPosYAtStart = views.virtualWidth / 2 + 10.0
|
||||
val ballSpeedAtStart = 200.0
|
||||
|
||||
/* Initialize the starting game state values */
|
||||
val paddlePosYAtStart = views.virtualHeight / 2 - 50.0
|
||||
val ballPosXAtStart = views.virtualWidth / 2 - 10.0
|
||||
val ballPosYAtStart = views.virtualWidth / 2 + 10.0
|
||||
val ballSpeedAtStart = 200.0
|
||||
// Initialize the variables defining the paddle and ball parameters
|
||||
val paddleWidth = 10.0
|
||||
val paddleHeight = 100.0
|
||||
val paddleDistanceFromWall = 10.0
|
||||
val paddleMoveSpeed = 10.0
|
||||
val ballRadius = 10.0
|
||||
val ballSpeedIncrease = 50.0
|
||||
|
||||
/* Initialize the variables to be used to define the paddle and ball size */
|
||||
val paddleWidth = 10.0
|
||||
val paddleHeight = 100.0
|
||||
val paddleDistanceFromWall = 10.0
|
||||
val paddleMoveSpeed = 10.0
|
||||
val ballRadius = 10.0
|
||||
val ballSpeedIncrease = 50.0
|
||||
// Add a HUD for reporting the FPS
|
||||
val fpsText = text("FPS: 0") {
|
||||
position(10, 30)
|
||||
addUpdater {
|
||||
text = "FPS: " + views.gameWindow.fps.toString()
|
||||
}
|
||||
}
|
||||
|
||||
// Add a HUD for reporting the ticks/frame length
|
||||
val tickSizeText = text("Tick: 0") {
|
||||
position(10, 50)
|
||||
addUpdater {
|
||||
text = "Tick: " + views.gameWindow.timePerFrame.toString()
|
||||
}
|
||||
}
|
||||
|
||||
// Add a HUD for reporting the FPS
|
||||
fpsText = text("FPS: 0") {
|
||||
position(10, 30)
|
||||
addUpdater {
|
||||
text = "FPS: " + views.gameWindow.fps.toString()
|
||||
}
|
||||
}
|
||||
// Add a help text which explains the rules of the game
|
||||
val helpText = text("") {
|
||||
position(10, 100)
|
||||
addUpdater {
|
||||
// this text is only visible if the game is not in Playing state
|
||||
visible = (playState != GameStates.Playing)
|
||||
|
||||
// Add a HUD for reporting the ticks/frame length
|
||||
tickSizeText = text("Tick: 0") {
|
||||
position(10, 50)
|
||||
addUpdater {
|
||||
text = "Tick: " + views.gameWindow.timePerFrame.toString()
|
||||
}
|
||||
}
|
||||
// show a different text if the game is just starting
|
||||
if (playState == GameStates.Starting) {
|
||||
text = "Welcome to the PONG Game!\n\n" +
|
||||
"-- To move the Left Paddle, use the keys [W] and [S].\n\n" +
|
||||
"-- To move the Right Paddle, use the keys [UP] and [DOWN]\n\n" +
|
||||
"-- To go back to Main Menu, use [ESC]\n\n" +
|
||||
"-- To Start the game, use [SPACE]"
|
||||
// show a different text if the game is in Scored state
|
||||
} else if (playState == GameStates.Scored) {
|
||||
text = "Press [SPACE] for the next round!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a help text which explains the rules of the game
|
||||
helpText = text("") {
|
||||
position(10, 100)
|
||||
addUpdater {
|
||||
// this text is only visible if the game is not in Playing state
|
||||
visible = (playState != GameStates.Playing)
|
||||
// A simple flavour text informing that a goal was scored
|
||||
val scoredYellText = text("SCORED!!!\n\n") {
|
||||
position(views.virtualWidth / 2 - 100, views.virtualHeight / 2 - 20)
|
||||
addUpdater {
|
||||
// this is only visible when the game is in Scored state
|
||||
visible = (playState == GameStates.Scored)
|
||||
}
|
||||
}
|
||||
|
||||
// show a different text if the game is just starting
|
||||
if (playState == GameStates.Starting) {
|
||||
text = "Welcome to the PONG Game!\n\n" +
|
||||
"-- To move the Left Paddle, use the keys [W] and [S].\n\n" +
|
||||
"-- To move the Right Paddle, use the keys [UP] and [DOWN]\n\n" +
|
||||
"-- To go back to Main Menu, use [ESC]\n\n" +
|
||||
"-- To Start the game, use [SPACE]"
|
||||
// show a different text if the game is in Scored state
|
||||
} else if (playState == GameStates.Scored) {
|
||||
text = "Press [SPACE] for the next round!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A simple flavour text informing that a goal was scored
|
||||
scoredYellText = text("SCORED!!!\n\n") {
|
||||
position(views.virtualWidth / 2 - 100, views.virtualHeight / 2 - 20)
|
||||
addUpdater {
|
||||
// this is only visible when the game is in Scored state
|
||||
visible = (playState == GameStates.Scored)
|
||||
}
|
||||
}
|
||||
|
||||
// text to show the score of the player on the Left side
|
||||
scoreLeftText = text("0") {
|
||||
// text to show the score of the player on the Left side
|
||||
val scoreLeftText = text("0") {
|
||||
// textSize = 24.0
|
||||
position(views.virtualWidth / 4, views.virtualHeight / 2)
|
||||
addUpdater {
|
||||
text = scorePlayerLeft.toString()
|
||||
}
|
||||
}
|
||||
// text to show the score of the player on the Right side
|
||||
scoreRightText = text("0") {
|
||||
position(views.virtualWidth * 3 / 4, views.virtualHeight / 2)
|
||||
addUpdater {
|
||||
text = scorePlayerRight.toString()
|
||||
}
|
||||
}
|
||||
position(views.virtualWidth / 4, views.virtualHeight / 2)
|
||||
addUpdater {
|
||||
text = scorePlayerLeft.toString()
|
||||
}
|
||||
}
|
||||
// text to show the score of the player on the Right side
|
||||
val scoreRightText = text("0") {
|
||||
position(views.virtualWidth * 3 / 4, views.virtualHeight / 2)
|
||||
addUpdater {
|
||||
text = scorePlayerRight.toString()
|
||||
}
|
||||
}
|
||||
|
||||
// the left paddle
|
||||
paddleLeft = solidRect(paddleWidth, paddleHeight, Colors.RED) {
|
||||
position(paddleDistanceFromWall, paddlePosYAtStart)
|
||||
addUpdater {
|
||||
// move the paddle up or down as long as it doesn't leaves the bounds of the game window
|
||||
val keys = views.input.keys
|
||||
if (keys[Key.W] && y > 0) {
|
||||
y -= paddleMoveSpeed
|
||||
}
|
||||
if (keys[Key.S] && y < views.virtualHeight - paddleHeight) {
|
||||
y += paddleMoveSpeed
|
||||
}
|
||||
}
|
||||
}
|
||||
// the left paddle
|
||||
val paddleLeft = solidRect(paddleWidth, paddleHeight, Colors.RED) {
|
||||
position(paddleDistanceFromWall, paddlePosYAtStart)
|
||||
addUpdater {
|
||||
// move the paddle up or down as long as it doesn't leaves the bounds of the game window
|
||||
val keys = views.input.keys
|
||||
if (keys[Key.W] && y > 0) {
|
||||
y -= paddleMoveSpeed
|
||||
}
|
||||
if (keys[Key.S] && y < views.virtualHeight - paddleHeight) {
|
||||
y += paddleMoveSpeed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the right paddle
|
||||
paddleRight = solidRect(paddleWidth, paddleHeight, Colors.BLUE) {
|
||||
position(views.virtualWidth - paddleDistanceFromWall - paddleWidth, paddlePosYAtStart)
|
||||
addUpdater {
|
||||
// move the paddle up or down as long as it doesn't leaves the bounds of the game window
|
||||
val keys = views.input.keys
|
||||
if (keys[Key.UP] && y > 0) {
|
||||
y -= paddleMoveSpeed
|
||||
}
|
||||
if (keys[Key.DOWN] && y < views.virtualHeight - paddleHeight) {
|
||||
y += paddleMoveSpeed
|
||||
}
|
||||
}
|
||||
}
|
||||
// the right paddle
|
||||
val paddleRight = solidRect(paddleWidth, paddleHeight, Colors.BLUE) {
|
||||
position(views.virtualWidth - paddleDistanceFromWall - paddleWidth, paddlePosYAtStart)
|
||||
addUpdater {
|
||||
// move the paddle up or down as long as it doesn't leaves the bounds of the game window
|
||||
val keys = views.input.keys
|
||||
if (keys[Key.UP] && y > 0) {
|
||||
y -= paddleMoveSpeed
|
||||
}
|
||||
if (keys[Key.DOWN] && y < views.virtualHeight - paddleHeight) {
|
||||
y += paddleMoveSpeed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ball = circle(ballRadius, Colors.WHITE) {
|
||||
position(ballPosXAtStart, ballPosYAtStart)
|
||||
val ball = circle(ballRadius, Colors.WHITE) {
|
||||
position(ballPosXAtStart, ballPosYAtStart)
|
||||
|
||||
// define the mutable data defning the ball's state
|
||||
var spd = ballSpeedAtStart
|
||||
var ang = nextDouble() * 2 * PI
|
||||
// mutable data defining the ball state
|
||||
var spd = ballSpeedAtStart
|
||||
var ang = nextDouble() * 2 * PI
|
||||
|
||||
// function to reset the ball
|
||||
var resetRound = fun () {
|
||||
x = ballPosXAtStart
|
||||
y = ballPosYAtStart
|
||||
spd = ballSpeedAtStart
|
||||
ang = nextDouble() * 2 * PI
|
||||
// function to reset the ball
|
||||
fun resetRound() {
|
||||
x = ballPosXAtStart
|
||||
y = ballPosYAtStart
|
||||
spd = ballSpeedAtStart
|
||||
ang = nextDouble() * 2 * PI
|
||||
|
||||
// Change game state to Scored. Game will be paused till players start the next round.
|
||||
playState = GameStates.Scored
|
||||
}
|
||||
// Change game state to Scored. Game will be paused till players start the next round.
|
||||
playState = GameStates.Scored
|
||||
}
|
||||
|
||||
addUpdater {
|
||||
// only move ball if the game is in Playing state
|
||||
if (playState == GameStates.Playing) {
|
||||
addUpdater {
|
||||
// only move ball if the game is in Playing state
|
||||
if (playState == GameStates.Playing) {
|
||||
|
||||
// convert the ball's velocity vector (speed, angle) to a point to move to
|
||||
x += spd * cos(ang) * it.seconds;
|
||||
y += spd * sin(ang) * it.seconds;
|
||||
// convert the ball's velocity vector (speed, angle) to a point to move to
|
||||
x += spd * cos(ang) * it.seconds;
|
||||
y += spd * sin(ang) * it.seconds;
|
||||
|
||||
// if the ball hits the paddles, flip its direction and increase speed
|
||||
if ((x < paddleLeft.x + 10 && y > paddleLeft.y && y < paddleLeft.y + 100) ||
|
||||
(x > paddleRight.x - 20 && y > paddleRight.y && y < paddleRight.y + 100)) {
|
||||
spd += ballSpeedIncrease
|
||||
ang = PI - ang
|
||||
}
|
||||
// if the ball hits the paddles, flip its direction and increase speed
|
||||
if ((x < paddleLeft.x + 10 && y > paddleLeft.y && y < paddleLeft.y + 100) ||
|
||||
(x > paddleRight.x - 20 && y > paddleRight.y && y < paddleRight.y + 100)) {
|
||||
spd += ballSpeedIncrease
|
||||
ang = PI - ang
|
||||
}
|
||||
|
||||
// if ball hits the walls, flip its direction and increase speed
|
||||
if (y < 0 || y > views.virtualHeight - 20) {
|
||||
spd += 10
|
||||
ang *= -1
|
||||
}
|
||||
// if ball hits the walls, flip its direction and increase speed
|
||||
if (y < 0 || y > views.virtualHeight - 20) {
|
||||
spd += 10
|
||||
ang *= -1
|
||||
}
|
||||
|
||||
// if ball goes through the vertical walls/goalpost, handle scoring and reset the round
|
||||
if (x < -20) {
|
||||
/* Reset the Ball */
|
||||
resetRound()
|
||||
// if ball goes through the vertical walls/goalpost, handle scoring and reset the round
|
||||
if (x < -20) {
|
||||
// Reset the Ball
|
||||
resetRound()
|
||||
|
||||
// Update the score
|
||||
scorePlayerRight++
|
||||
scoredYellText.text = "Right SCORED!!!"
|
||||
} else if (x > views.virtualWidth) {
|
||||
/* Reset the Ball */
|
||||
resetRound()
|
||||
// Update the score
|
||||
scorePlayerRight++
|
||||
scoredYellText.text = "Right SCORED!!!"
|
||||
} else if (x > views.virtualWidth) {
|
||||
// Reset the Ball
|
||||
resetRound()
|
||||
|
||||
// Update the score
|
||||
playState = GameStates.Scored
|
||||
scorePlayerLeft++
|
||||
scoredYellText.text = "Left SCORED!!!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update the score
|
||||
playState = GameStates.Scored
|
||||
scorePlayerLeft++
|
||||
scoredYellText.text = "Left SCORED!!!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the keys needed to run the game*/
|
||||
keys {
|
||||
onKeyDown {
|
||||
when (it.key) {
|
||||
Key.ESCAPE -> sceneContainer.changeToAsync<MenuScene>()
|
||||
Key.SPACE -> playState = GameStates.Playing
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Add the keys needed to run the game
|
||||
onKeyDown {
|
||||
when (it.key) {
|
||||
Key.ESCAPE -> sceneContainer.changeTo<MenuScene>()
|
||||
Key.SPACE -> playState = GameStates.Playing
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import com.soywiz.korge.Korge
|
||||
import com.soywiz.korge.scene.Module
|
||||
import com.soywiz.korge.scene.Scene
|
||||
import com.soywiz.korinject.AsyncInjector
|
||||
import com.soywiz.korma.geom.SizeInt
|
||||
import kotlin.reflect.KClass
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korinject.*
|
||||
import com.soywiz.korma.geom.*
|
||||
|
||||
suspend fun main() = Korge(Korge.Config(module = MyModule))
|
||||
|
||||
|
||||
@@ -1,24 +1,68 @@
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korgw.*
|
||||
import com.soywiz.korim.color.*
|
||||
import com.soywiz.korio.async.*
|
||||
import com.soywiz.korma.geom.*
|
||||
import com.soywiz.korma.geom.vector.*
|
||||
|
||||
suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "My Awesome Box2D Game!") {
|
||||
suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "KorGE Shapes!") {
|
||||
setupCircle()
|
||||
setupRects()
|
||||
|
||||
solidRect(300, 200, Colors.DARKCYAN)
|
||||
sgraphics {
|
||||
fill(Colors.DARKCYAN) {
|
||||
rect(-1.0, -1.0, 3.0, 2.0)
|
||||
}
|
||||
fill(Colors.AQUAMARINE) {
|
||||
circle(0.0, 0.0, 1.0)
|
||||
}
|
||||
fill(Colors.AQUAMARINE) {
|
||||
circle(1.0, 0.0, 1.0)
|
||||
}
|
||||
position(100, 100)
|
||||
}.scale(100.0, 100.0).interactive()
|
||||
}
|
||||
|
||||
fun Stage.setupCircle() {
|
||||
val circle = Circle(radius = 32.0)
|
||||
addChild(circle)
|
||||
circle.position(512, 256)
|
||||
var growing = true
|
||||
launch {
|
||||
while (true) {
|
||||
circle.x++
|
||||
circle.y++
|
||||
circle.radius++
|
||||
when {
|
||||
circle.radius > 128.0 -> {
|
||||
growing = false
|
||||
circle.radius--
|
||||
}
|
||||
circle.radius < 32.0 -> {
|
||||
growing = true
|
||||
circle.radius++
|
||||
}
|
||||
else -> if (growing) circle.radius++ else circle.radius--
|
||||
}
|
||||
delay(16.milliseconds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Stage.setupRects() {
|
||||
val rect1 = roundRect(80.0, 100.0, 5.0, color = Colors.GREEN).position(820, 128)
|
||||
val rect2 = roundRect(80.0, 100.0, 5.0, color = Colors.GREEN).position(1020, 128).anchor(0.5, 0.5)
|
||||
addFixedUpdater(60.timesPerSecond) {
|
||||
rect1.rotation += 1.degrees
|
||||
rect2.rotation += 1.degrees
|
||||
//no need for delay
|
||||
//delay(16.milliseconds)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : View> T.interactive(): T = apply {
|
||||
alpha = 0.5
|
||||
onOver { alpha = 1.0 }
|
||||
onOut { alpha = 0.5 }
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import com.soywiz.korev.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korim.bitmap.*
|
||||
import com.soywiz.korim.format.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
|
||||
@@ -51,12 +50,12 @@ suspend fun main() = Korge(width = 512, height = 512) {
|
||||
)
|
||||
|
||||
val player1 = Sprite(spriteAnimationDown).apply {
|
||||
scale(3)
|
||||
xy(100,200)
|
||||
scale(3.0)
|
||||
xy(100, 200)
|
||||
}
|
||||
val player2 = Sprite(spriteAnimationDown).apply {
|
||||
scale(3)
|
||||
xy(100,100)
|
||||
scale(3.0)
|
||||
xy(100, 100)
|
||||
}
|
||||
|
||||
addChild(player1)
|
||||
@@ -66,37 +65,34 @@ suspend fun main() = Korge(width = 512, height = 512) {
|
||||
val scale = 16.milliseconds / time
|
||||
val disp = 2 * scale
|
||||
val keys = views.input.keys
|
||||
if (keys[Key.LEFT]) {player1.playAnimation(spriteAnimationLeft); player1.x-=disp }
|
||||
if (keys[Key.RIGHT]) { player1.playAnimation(spriteAnimationRight); player1.x+=disp}
|
||||
if (keys[Key.DOWN]) {player1.playAnimation(spriteAnimationDown); player1.y+=disp}
|
||||
if (keys[Key.UP]) {player1.playAnimation(spriteAnimationUp); player1.y-=disp}
|
||||
if (keys[Key.A]) {player2.playAnimation(spriteAnimationLeft); player2.x-=disp }
|
||||
if (keys[Key.D]) { player2.playAnimation(spriteAnimationRight); player2.x+=disp}
|
||||
if (keys[Key.S]) {player2.playAnimation(spriteAnimationDown); player2.y+=disp}
|
||||
if (keys[Key.W]) {player2.playAnimation(spriteAnimationUp); player2.y-=disp}
|
||||
if (keys[Key.L]) {player1.playAnimationLooped(spriteAnimationDown, 100.milliseconds)}
|
||||
if (keys[Key.T]) {player1.playAnimation(spriteAnimation = spriteAnimationDown, times = 3, spriteDisplayTime = 200.milliseconds)}
|
||||
if (keys[Key.C]) {player1.playAnimationForDuration(1.seconds, spriteAnimationDown); player1.y-=2}
|
||||
if (keys[Key.ESCAPE]) {player1.stopAnimation()}
|
||||
if (keys[Key.LEFT]) { player1.playAnimation(spriteAnimationLeft); player1.x-=disp }
|
||||
if (keys[Key.RIGHT]) { player1.playAnimation(spriteAnimationRight); player1.x+=disp }
|
||||
if (keys[Key.DOWN]) { player1.playAnimation(spriteAnimationDown); player1.y+=disp }
|
||||
if (keys[Key.UP]) { player1.playAnimation(spriteAnimationUp); player1.y-=disp }
|
||||
if (keys[Key.A]) { player2.playAnimation(spriteAnimationLeft); player2.x-=disp }
|
||||
if (keys[Key.D]) { player2.playAnimation(spriteAnimationRight); player2.x+=disp }
|
||||
if (keys[Key.S]) { player2.playAnimation(spriteAnimationDown); player2.y+=disp }
|
||||
if (keys[Key.W]) { player2.playAnimation(spriteAnimationUp); player2.y-=disp }
|
||||
if (keys[Key.L]) { player1.playAnimationLooped(spriteAnimationDown, 100.milliseconds) }
|
||||
if (keys[Key.T]) { player1.playAnimation(spriteAnimation = spriteAnimationDown, times = 3, spriteDisplayTime = 200.milliseconds) }
|
||||
if (keys[Key.C]) { player1.playAnimationForDuration(1.seconds, spriteAnimationDown); player1.y-=2 }
|
||||
if (keys[Key.ESCAPE]) { player1.stopAnimation() }
|
||||
}
|
||||
|
||||
//keys {
|
||||
// onKeyDown{
|
||||
// when (it.key){
|
||||
// Key.LEFT -> {player1.playAnimation(spriteAnimationLeft); player1.x-=2 }
|
||||
// Key.RIGHT ->{ player1.playAnimation(spriteAnimationRight); player1.x+=2}
|
||||
// Key.DOWN -> {player1.playAnimation(spriteAnimationDown); player1.y+=2}
|
||||
// Key.UP -> {player1.playAnimation(spriteAnimationUp); player1.y-=2}
|
||||
// Key.A -> {player2.playAnimation(spriteAnimationLeft); player2.x-=2 }
|
||||
// Key.D ->{ player2.playAnimation(spriteAnimationRight); player2.x+=2}
|
||||
// Key.S -> {player2.playAnimation(spriteAnimationDown); player2.y+=2}
|
||||
// Key.W -> {player2.playAnimation(spriteAnimationUp); player2.y-=2}
|
||||
// Key.L -> {player1.playAnimationLooped(spriteAnimationDown, 100.milliseconds)}
|
||||
// Key.T -> {player1.playAnimation(spriteAnimation = spriteAnimationDown, times = 3, spriteDisplayTime = 200.milliseconds)}
|
||||
// Key.C -> {player1.playAnimationForDuration(1.seconds, spriteAnimationDown); player1.y-=2}
|
||||
// Key.ESCAPE -> {player1.stopAnimation()}
|
||||
// else -> {}
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
/*onKeyDown {
|
||||
when (it.key) {
|
||||
Key.LEFT -> {player1.playAnimation(spriteAnimationLeft); player1.x-=2}
|
||||
Key.RIGHT ->{player1.playAnimation(spriteAnimationRight); player1.x+=2}
|
||||
Key.DOWN -> {player1.playAnimation(spriteAnimationDown); player1.y+=2}
|
||||
Key.UP -> {player1.playAnimation(spriteAnimationUp); player1.y-=2}
|
||||
Key.A -> {player2.playAnimation(spriteAnimationLeft); player2.x-=2}
|
||||
Key.D -> {player2.playAnimation(spriteAnimationRight); player2.x+=2}
|
||||
Key.S -> {player2.playAnimation(spriteAnimationDown); player2.y+=2}
|
||||
Key.W -> {player2.playAnimation(spriteAnimationUp); player2.y-=2}
|
||||
Key.L -> {player1.playAnimationLooped(spriteAnimationDown, 100.milliseconds)}
|
||||
Key.T -> {player1.playAnimation(spriteAnimation = spriteAnimationDown, times = 3, spriteDisplayTime = 200.milliseconds)}
|
||||
Key.C -> {player1.playAnimationForDuration(1.seconds, spriteAnimationDown); player1.y-=2}
|
||||
Key.ESCAPE -> {player1.stopAnimation()}
|
||||
else -> {}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.klock.hr.hrMilliseconds
|
||||
import com.soywiz.korev.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korim.bitmap.*
|
||||
import com.soywiz.korim.format.*
|
||||
@@ -20,50 +17,45 @@ suspend fun main() = Korge(width = 1600, height = 1200) {
|
||||
val greenAnimations = animations(greenSpriteMap)
|
||||
val redAnimations = animations(redSpriteMap)
|
||||
|
||||
val greenSprites = Array<Sprite>(numberOfGreen) {
|
||||
Sprite(greenAnimations[it % greenAnimations.size]).xy((10..1590).random(), (10..1190).random()).scale(2.0)
|
||||
val greenSprites = Array(numberOfGreen) {
|
||||
sprite(greenAnimations[it % greenAnimations.size]).xy((10..1590).random(), (10..1190).random()).scale(2.0)
|
||||
}
|
||||
|
||||
val redSprites = Array<Sprite>(numberOfRed) {
|
||||
Sprite(redAnimations[it % redAnimations.size]).xy((10..1590).random(), (10..1190).random()).scale(2.0)
|
||||
val redSprites = Array(numberOfRed) {
|
||||
sprite(redAnimations[it % redAnimations.size]).xy((10..1590).random(), (10..1190).random()).scale(2.0)
|
||||
}
|
||||
|
||||
redSprites.forEach {
|
||||
addChild(it)
|
||||
greenSprites.forEachIndexed { index, sprite ->
|
||||
sprite.playAnimationLooped(greenAnimations[index % greenAnimations.size])
|
||||
}
|
||||
|
||||
greenSprites.forEach {
|
||||
addChild(it)
|
||||
redSprites.forEachIndexed { index, sprite ->
|
||||
sprite.playAnimationLooped(redAnimations[index % redAnimations.size])
|
||||
}
|
||||
|
||||
addHrUpdater {
|
||||
val scale = if (it == 0.hrMilliseconds) 0.0 else (it / 16.666666.hrMilliseconds)
|
||||
|
||||
greenSprites.forEachIndexed { index, sprite ->
|
||||
sprite.playAnimationLooped(greenAnimations[index % greenAnimations.size]).apply { walkdirection(sprite, index % greenAnimations.size, scale) }
|
||||
sprite.walkDirection(index % greenAnimations.size, scale)
|
||||
}
|
||||
|
||||
redSprites.forEachIndexed { index, sprite ->
|
||||
sprite.playAnimationLooped(redAnimations[index % redAnimations.size]).apply { walkdirection(sprite, index % redAnimations.size, scale) }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun animations(spriteMap: Bitmap) = arrayOf(
|
||||
SpriteAnimation(spriteMap,16,32,96,1,4,1), // left
|
||||
SpriteAnimation(spriteMap,16,32,32,1,4,1), // right
|
||||
SpriteAnimation(spriteMap,16,32,64,1,4,1), // up
|
||||
SpriteAnimation(spriteMap,16,32,0,1,4,1)) // down
|
||||
|
||||
fun walkdirection(sprite : Sprite, indexOfAnimation : Int, scale: Double = 1.0) {
|
||||
sprite.apply {
|
||||
val delta = 2 * scale
|
||||
when (indexOfAnimation) {
|
||||
0 -> x-=delta
|
||||
1 -> x+=delta
|
||||
2 -> y-=delta
|
||||
3 -> y+=delta
|
||||
sprite.walkDirection(index % redAnimations.size, scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun animations(spriteMap: Bitmap) = arrayOf(
|
||||
SpriteAnimation(spriteMap, 16, 32, 96, 1, 4, 1), // left
|
||||
SpriteAnimation(spriteMap, 16, 32, 32, 1, 4, 1), // right
|
||||
SpriteAnimation(spriteMap, 16, 32, 64, 1, 4, 1), // up
|
||||
SpriteAnimation(spriteMap, 16, 32, 0, 1, 4, 1)) // down
|
||||
|
||||
fun Sprite.walkDirection(indexOfAnimation: Int, scale: Double = 1.0) {
|
||||
val delta = 2 * scale
|
||||
when (indexOfAnimation) {
|
||||
0 -> x -= delta
|
||||
1 -> x += delta
|
||||
2 -> y -= delta
|
||||
3 -> y += delta
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.soywiz.korma.geom.*
|
||||
enum class Chip { EMPTY, CROSS, CIRCLE }
|
||||
|
||||
class Board(val width: Int = 3, val height: Int = width, val lineSize: Int = width) {
|
||||
class Cell(val x: Int, val y: Int) : Extra by Extra.Mixin() {
|
||||
class Cell(x: Int, y: Int) : Extra by Extra.Mixin() {
|
||||
val pos = PointInt(x, y)
|
||||
var value = Chip.EMPTY
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class Board(val width: Int = 3, val height: Int = width, val lineSize: Int = wid
|
||||
return (0 until size).map { cells[x + dx * it, y + dy * it] }
|
||||
}
|
||||
|
||||
val lines = kotlin.collections.ArrayList<List<Cell>>()
|
||||
val lines = ArrayList<List<Cell>>()
|
||||
|
||||
init {
|
||||
fun addLine(line: List<Cell>?) {
|
||||
@@ -48,15 +48,13 @@ class Board(val width: Int = 3, val height: Int = width, val lineSize: Int = wid
|
||||
|
||||
val winnerLine: List<Cell>?
|
||||
get() {
|
||||
val out = kotlin.collections.ArrayList<Cell>()
|
||||
val out = ArrayList<Cell>()
|
||||
for (line in lines) if (line.chipLine != null) out += line
|
||||
return if (out.isEmpty()) null else out.toSet().toList()
|
||||
}
|
||||
|
||||
val winner: Chip?
|
||||
get() {
|
||||
return winnerLine?.firstOrNull()?.value
|
||||
}
|
||||
get() = winnerLine?.firstOrNull()?.value
|
||||
}
|
||||
|
||||
fun Board(str: String): Board {
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.soywiz.korma.interpolation.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
var Board.Cell.view by Extra.Property<View?> { null }
|
||||
val Board.Cell.vview: View get() = this.view!!
|
||||
val Board.Cell.onPress by Extra.Property { Signal<Unit>() }
|
||||
|
||||
fun Board.Cell.set(type: Chip) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.animate.*
|
||||
import com.soywiz.korge.animate.serialization.*
|
||||
import com.soywiz.korge.ext.swf.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korge.view.*
|
||||
@@ -72,12 +71,10 @@ class TicTacToeMainScene : Scene() {
|
||||
}
|
||||
}
|
||||
sceneView += results
|
||||
results["hit"]?.mouse?.onClick?.waitOne()
|
||||
results["hit"]?.mouse?.click?.waitOne()
|
||||
//sceneView -= results
|
||||
results.removeFromParent()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +131,5 @@ class InteractivePlayer(val board: Board, override val chip: Chip) : Player {
|
||||
}
|
||||
|
||||
override suspend fun move(): PointInt = clicked.waitOne()
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ import com.soywiz.korma.triangle.triangulate.*
|
||||
|
||||
suspend fun main() = Korge(width = 512, height = 512) {
|
||||
val stage = this
|
||||
text("Add Points by clicking with the mouse")
|
||||
text("Add Points by clicking with the mouse", 14.0).position(5.0, 5.0)
|
||||
graphics {
|
||||
val graphics = this
|
||||
graphics.useNativeRendering = false
|
||||
position(100, 100)
|
||||
|
||||
val points = arrayListOf<IPoint>()
|
||||
val points = arrayListOf<Point>()
|
||||
|
||||
var additionalPoint: Point? = null
|
||||
|
||||
@@ -56,7 +56,7 @@ suspend fun main() = Korge(width = 512, height = 512) {
|
||||
for (n in 0 until edges.size - 1) {
|
||||
val e0 = Point(edges[n])
|
||||
val e1 = Point(edges[n + 1])
|
||||
var last = n == edges.size - 2
|
||||
val last = n == edges.size - 2
|
||||
stroke(if (last) Colors.RED else Colors.BLUE, Context2d.StrokeInfo(thickness = 2.0)) {
|
||||
line(e0, e1)
|
||||
}
|
||||
@@ -64,13 +64,13 @@ suspend fun main() = Korge(width = 512, height = 512) {
|
||||
}
|
||||
|
||||
stage.mouse {
|
||||
onClick { e ->
|
||||
onClick {
|
||||
points.add(graphics.localMouseXY(views))
|
||||
repaint(finished = true)
|
||||
//println("CLICK")
|
||||
}
|
||||
|
||||
onMove { e ->
|
||||
onMove {
|
||||
additionalPoint = graphics.localMouseXY(views)
|
||||
repaint(finished = false)
|
||||
}
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
import com.soywiz.klock.*
|
||||
import com.soywiz.korge.*
|
||||
import com.soywiz.korge.font.*
|
||||
import com.soywiz.korge.html.*
|
||||
import com.soywiz.korge.input.*
|
||||
import com.soywiz.korge.ui.*
|
||||
import com.soywiz.korge.render.*
|
||||
import com.soywiz.korge.scene.*
|
||||
import com.soywiz.korge.service.process.*
|
||||
import com.soywiz.korge.tween.*
|
||||
import com.soywiz.korge.ui.*
|
||||
import com.soywiz.korge.view.*
|
||||
import com.soywiz.korgw.*
|
||||
import com.soywiz.korim.bitmap.*
|
||||
import com.soywiz.korim.color.*
|
||||
import com.soywiz.korim.font.*
|
||||
import com.soywiz.korim.format.*
|
||||
import com.soywiz.korio.async.*
|
||||
import com.soywiz.korio.file.*
|
||||
import com.soywiz.korio.file.std.*
|
||||
import com.soywiz.korio.net.*
|
||||
import com.soywiz.korio.util.*
|
||||
import com.soywiz.korma.interpolation.*
|
||||
|
||||
suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "UI") {
|
||||
val nativeProcess = NativeProcess(views)
|
||||
|
||||
//uiSkin(OtherUISkin()) {
|
||||
defaultUISkin = OtherUISkin()
|
||||
defaultUIFont = Html.FontFace.Bitmap(resourcesVfs["uifont.fnt"].readBitmapFontWithMipmaps())
|
||||
|
||||
textButton(256.0, 32.0) {
|
||||
text = "Disabled Button"
|
||||
position(128, 128)
|
||||
@@ -42,6 +38,7 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "UI
|
||||
}
|
||||
enable()
|
||||
}
|
||||
|
||||
uiScrollBar(256.0, 32.0, 0.0, 32.0, 64.0) {
|
||||
position(64, 64)
|
||||
onChange {
|
||||
@@ -66,7 +63,6 @@ suspend fun main() = Korge(quality = GameWindow.Quality.PERFORMANCE, title = "UI
|
||||
uiScrollableArea(config = {
|
||||
position(480, 128)
|
||||
}) {
|
||||
|
||||
for (n in 0 until 16) {
|
||||
textButton(text = "HELLO $n").position(0, n * 64)
|
||||
}
|
||||
@@ -104,19 +100,3 @@ suspend fun OtherUISkin(): UISkin = OtherUISkinOnce {
|
||||
//font = Html.FontFace.Bitmap(resourcesVfs["uifont.fnt"].readBitmapFontWithMipmaps())
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun VfsFile.readBitmapFontWithMipmaps(imageFormat: ImageFormat = RegisteredImageFormats, mipmaps: Boolean = true): BitmapFont =
|
||||
readBitmapFont(imageFormat).also { it.atlas.mipmaps(mipmaps) }
|
||||
|
||||
|
||||
private class NativeProcess(views: Views) : NativeProcessBase(views) {
|
||||
}
|
||||
|
||||
private open class NativeProcessBase(val views: Views) {
|
||||
open suspend fun alert(message: String) = views.gameWindow.alert(message)
|
||||
open suspend fun confirm(message: String): Boolean = views.gameWindow.confirm(message)
|
||||
open suspend fun openFileDialog(filter: String? = null, write: Boolean = false, multi: Boolean = false) = views.gameWindow.openFileDialog(filter, write, multi)
|
||||
open suspend fun browse(url: URL) = views.gameWindow.browse(url)
|
||||
open suspend fun close() = views.gameWindow.close()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user