diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 8fd8070..1057326 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly + plugins { kotlin("jvm") version "1.8.0" application @@ -6,7 +8,7 @@ plugins { group = "dev.jombi" version = "1.0-DEV" val lwjglVersion = "3.3.1" -val lwjglNatives = "natives-macos-arm64" +val natives = arrayOf("natives-windows", "natives-macos-arm64") repositories { mavenCentral() @@ -21,12 +23,33 @@ dependencies { implementation("org.lwjgl", "lwjgl-openal") implementation("org.lwjgl", "lwjgl-opengl") implementation("org.lwjgl", "lwjgl-stb") - runtimeOnly("org.lwjgl", "lwjgl", classifier = lwjglNatives) - runtimeOnly("org.lwjgl", "lwjgl-assimp", classifier = lwjglNatives) - runtimeOnly("org.lwjgl", "lwjgl-glfw", classifier = lwjglNatives) - runtimeOnly("org.lwjgl", "lwjgl-openal", classifier = lwjglNatives) - runtimeOnly("org.lwjgl", "lwjgl-opengl", classifier = lwjglNatives) - runtimeOnly("org.lwjgl", "lwjgl-stb", classifier = lwjglNatives) + + natives.forEach { + runtimeOnly("org.lwjgl", "lwjgl", classifier = it) + runtimeOnly("org.lwjgl", "lwjgl-assimp", classifier = it) + runtimeOnly("org.lwjgl", "lwjgl-glfw", classifier = it) + runtimeOnly("org.lwjgl", "lwjgl-openal", classifier = it) + runtimeOnly("org.lwjgl", "lwjgl-opengl", classifier = it) + runtimeOnly("org.lwjgl", "lwjgl-stb", classifier = it) + } +} + +val fatJar = task("fatJar", type = Jar::class) { + archiveFileName.set("${project.name.toLowerCaseAsciiOnly()}.jar") + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + manifest { + attributes["Implementation-Title"] = "Gradle Jar File Example" + attributes["Implementation-Version"] = archiveVersion.get() + attributes["Main-Class"] = "dev.jombi.tetris.MainKt" + } + from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) + with(tasks.jar.get() as CopySpec) +} + +tasks { + "build" { + dependsOn(fatJar) + } } tasks.test { @@ -38,5 +61,5 @@ kotlin { } application { - mainClass.set("MainKt") + mainClass.set("dev.jombi.tetris.MainKt") } \ No newline at end of file diff --git a/src/main/kotlin/dev/jombi/tetris/Field.kt b/src/main/kotlin/dev/jombi/tetris/Field.kt index 0b35c9c..4312d55 100644 --- a/src/main/kotlin/dev/jombi/tetris/Field.kt +++ b/src/main/kotlin/dev/jombi/tetris/Field.kt @@ -110,6 +110,7 @@ class Field { var currentMino: Tetrimino? = null var minoPosY = 0 set(value) { + if (currentMino == null) return if (field == value) return if (value in -2 until blockY && !checkFloor(currentMino!!, minoSpin, value)) { field = value @@ -237,8 +238,8 @@ class Field { currentMino = null } } catch (e: ArrayIndexOutOfBoundsException) { - GLTetrisGame.instance().displayScreen(GuiGameOver()) - GLTetrisGame.instance().finalizeGame() + GLTetrisGame.getInstance().displayScreen(GuiGameOver()) + GLTetrisGame.getInstance().finalizeGame() System.gc() } } diff --git a/src/main/kotlin/dev/jombi/tetris/GLTetrisGame.kt b/src/main/kotlin/dev/jombi/tetris/GLTetrisGame.kt index c723a8c..afa6aaf 100644 --- a/src/main/kotlin/dev/jombi/tetris/GLTetrisGame.kt +++ b/src/main/kotlin/dev/jombi/tetris/GLTetrisGame.kt @@ -10,17 +10,17 @@ import org.lwjgl.glfw.GLFWErrorCallback import org.lwjgl.opengl.GL import org.lwjgl.opengl.GL11.* import org.lwjgl.system.MemoryUtil.NULL -import kotlin.properties.Delegates class GLTetrisGame { companion object { private val instance = GLTetrisGame() - fun instance() = instance + @JvmStatic + fun getInstance() = instance } private val gameTimer = Timer(20.0f, 0L) private val keyTimer = Timer(40.0f, 0) - private var window by Delegates.notNull() + private var window = 0L private var field: Field? = null val WIDTH = 400 val HEIGHT = 490 @@ -170,9 +170,10 @@ class GLTetrisGame { } fun clear() { - glfwFreeCallbacks(window) - glfwDestroyWindow(window) - + if (window != 0L) { + glfwFreeCallbacks(window) + glfwDestroyWindow(window) + } glfwTerminate() glfwSetErrorCallback(null)?.free() } diff --git a/src/main/kotlin/dev/jombi/tetris/Main.kt b/src/main/kotlin/dev/jombi/tetris/Main.kt index b70e7ce..b546cfd 100644 --- a/src/main/kotlin/dev/jombi/tetris/Main.kt +++ b/src/main/kotlin/dev/jombi/tetris/Main.kt @@ -1,10 +1,15 @@ package dev.jombi.tetris +import java.lang.Exception + fun main() { - val tetrKt = GLTetrisGame.instance() + val tetrKt = GLTetrisGame.getInstance() try { tetrKt.init() tetrKt.loop() + } catch (e: Exception) { + e.printStackTrace() + println("Error while loop.") } finally { tetrKt.clear() } diff --git a/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiGameOver.kt b/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiGameOver.kt index 874e227..51fb71a 100644 --- a/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiGameOver.kt +++ b/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiGameOver.kt @@ -6,15 +6,15 @@ import dev.jombi.tetris.screen.overlay.Button class GuiGameOver : GuiScreen() { override fun initGui() { - val halfWidth = GLTetrisGame.instance().WIDTH / 2.0 - val halfHeight = GLTetrisGame.instance().HEIGHT / 2.0 + val halfWidth = GLTetrisGame.getInstance().WIDTH / 2.0 + val halfHeight = GLTetrisGame.getInstance().HEIGHT / 2.0 buttons.add(Button("Retry", halfWidth, halfHeight) { - GLTetrisGame.instance().initGame() - GLTetrisGame.instance().displayScreen(null) + GLTetrisGame.getInstance().initGame() + GLTetrisGame.getInstance().displayScreen(null) }) buttons.add(Button("Main menu", halfWidth, halfHeight + 40.0) { - GLTetrisGame.instance().displayScreen(GuiMainMenu.getInstance()) + GLTetrisGame.getInstance().displayScreen(GuiMainMenu.getInstance()) }) } diff --git a/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiMainMenu.kt b/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiMainMenu.kt index 065b0aa..8620258 100644 --- a/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiMainMenu.kt +++ b/src/main/kotlin/dev/jombi/tetris/screen/impl/GuiMainMenu.kt @@ -17,14 +17,14 @@ class GuiMainMenu private constructor() : GuiScreen() { fun getInstance() = instance } override fun initGui() { - val halfWidth = GLTetrisGame.instance().WIDTH / 2.0 - val halfHeight = GLTetrisGame.instance().HEIGHT / 2.0 + val halfWidth = GLTetrisGame.getInstance().WIDTH / 2.0 + val halfHeight = GLTetrisGame.getInstance().HEIGHT / 2.0 buttons.add(Button("Start", halfWidth, halfHeight) { - GLTetrisGame.instance().initGame() - GLTetrisGame.instance().displayScreen(null) + GLTetrisGame.getInstance().initGame() + GLTetrisGame.getInstance().displayScreen(null) }) buttons.add(Button("Exit", halfWidth, halfHeight + 40.0) { - GLTetrisGame.instance().exitGame() + GLTetrisGame.getInstance().exitGame() }) } @@ -34,7 +34,7 @@ class GuiMainMenu private constructor() : GuiScreen() { override fun drawScreen(mouseX: Double, mouseY: Double) { super.drawScreen(mouseX, mouseY) - val halfWidth = GLTetrisGame.instance().WIDTH / 2.0 + val halfWidth = GLTetrisGame.getInstance().WIDTH / 2.0 val TARGET_FONT = FontFactory.getFont(FontType.ARIAL, 48) val (fWidth, fHeight) = TARGET_FONT.getStringBound("TetrKt")