All Projects → TobseF → HitKlack_LibGDX

TobseF / HitKlack_LibGDX

Licence: other
🎮 Retro console game remake of Mephisto Hit Klack

Programming Languages

kotlin
9241 projects
java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to HitKlack LibGDX

Koru
A 2D multiplayer sandbox game.
Stars: ✭ 78 (+239.13%)
Mutual labels:  libgdx
WurfelEngineSDK
Isometric game engine. Open world, block/voxel based and sprite rendering.
Stars: ✭ 96 (+317.39%)
Mutual labels:  libgdx
myxy
用libGDX开发的梦幻西游
Stars: ✭ 24 (+4.35%)
Mutual labels:  libgdx
kickoff
Open Kick-Off is a fun rewriting attempt of the cult football game Kick Off 2 designed by Dino Dini and released in 1990 by Anco for the Atari ST and the Commodore Amiga. It is written in Java with the help of libGDX.
Stars: ✭ 32 (+39.13%)
Mutual labels:  libgdx
bialjam17
💫 The game that won the BialJam'17 event
Stars: ✭ 55 (+139.13%)
Mutual labels:  libgdx
omo
Kotlin port with changes and improvements for omo originally by ForeignGuyMike
Stars: ✭ 22 (-4.35%)
Mutual labels:  libgdx
libgdx-transitions
libgdx screen transitions/fading
Stars: ✭ 43 (+86.96%)
Mutual labels:  libgdx
gdx-backend-bytecoder
Libgdx Kotlin app with Bytecoder
Stars: ✭ 24 (+4.35%)
Mutual labels:  libgdx
gdx-sqlite
A cross-platform extension for database handling in Libgdx
Stars: ✭ 61 (+165.22%)
Mutual labels:  libgdx
libgdx-screenmanager
A screen manager for libgdx supporting transitions
Stars: ✭ 69 (+200%)
Mutual labels:  libgdx
pixelwheels
A top-down retro racing game for PC (Linux, macOS, Windows) and Android.
Stars: ✭ 315 (+1269.57%)
Mutual labels:  libgdx
GDX-lazy-font
auto self-generate BitmapFont for libgdx 1.5.0 +
Stars: ✭ 26 (+13.04%)
Mutual labels:  libgdx
gdx-freetype-gwt
Freetype for gwt
Stars: ✭ 41 (+78.26%)
Mutual labels:  libgdx
tripeaks-gdx
A simple tri peaks solitaire game using libGDX.
Stars: ✭ 45 (+95.65%)
Mutual labels:  libgdx
gdx-gltf
GLTF 2.0 3D format support and PBR shader implementation for LibGDX
Stars: ✭ 156 (+578.26%)
Mutual labels:  libgdx
ForgE
Simple clone of RPG maker using LibGdx
Stars: ✭ 17 (-26.09%)
Mutual labels:  libgdx
pathfinding
Java pathfinding framework.
Stars: ✭ 94 (+308.7%)
Mutual labels:  libgdx
ZapTap
Cross Platform Game made in libGDX. Live on Google Play: https://play.google.com/store/apps/details?id=com.betterclever.zaptap
Stars: ✭ 49 (+113.04%)
Mutual labels:  libgdx
odb-arktrail
Artemis-ODB + LibGDX game
Stars: ✭ 16 (-30.43%)
Mutual labels:  libgdx
gdx-deploy-sample
Sample Gradle configurations for LibGDX for preparing and deploying release builds
Stars: ✭ 28 (+21.74%)
Mutual labels:  libgdx

Hit Klack - LibGDX

Retro console game remake of Mephisto Hit Klack

📢 Check out the NEW HitKlack Repo based on Korge framework.

This is a just for fun work in progress game remake. It's based on a German console, the Hit Klack from Mephisto. It runs on multiple platforms: Android, Windows, Linux, and Mac. For me it's a way to test the latest features of Kotlin, a programming language by Jetbrains. It uses the LibGDX Java game development framework.

🌍 Website and Downloads ...

Kotlin Coding Hitlist

Here is a list of nice noticeable Kotlin features which are already in use for HitKlack. Some of them are only available in the newest EAP of Kotlin 1.1. For a better understanding it may be help to follow direct into the sources.

Model cheatsheet: GameField consist out of ten Rings. A Ring contains four Blocks which each can hold one Stone.

Extension Function + When Expression

fun Orientation.toControl(): Controller.Control =
  when (this) {
      Orientation.Left -> Controller.Control.Left
      Orientation.Right -> Controller.Control.Right
      Orientation.Up -> Controller.Control.Top
      Orientation.Down -> Controller.Control.Bottom
  }

This adds the toControl() function to the Orientation class as extension. It maps an Orientation enum (Left,Right,Up,Down) to the Orientation enum (Left,Right,Top,Bottom). So we can write val control = block.orientation.toControl().

Lamdas and Method References

private fun firstFull() = gameField.find(Ring::isFull)

private fun renderField() {
	game.getStones().forEach(renderer::renderStone)
}

private fun getTouchPointers() = (0..6).filter(input::isTouched)
	.map { viewport.unproject(TouchPoint(it)) }
	.filter { !it.isZero }

This demonstrates two different types of method references. The Ring::isFull points to the isFullof the Iterable<Ring>. Hopefuly Ring can be omitted due a smart compiler. In the second example the renderer::renderStone points a function of the renderer. That’s called a bound reference which points to it’s reviever. The last example, the getTouchPointers(), shows the combination of ranges, lamdas, Kotlins stream API and method references. It returns a list of all unprojected touchpoints which are not zero (0, 0).

Delegation

class Controller(point: Point, val viewport: Viewport) : InputProcessor by InputAdapter(), Point by point {
    //..
}

This class implements the InputProcessor and the Point interface. Callers will be delegated to the implementation declared with the by statement. In pure Java I had to determine one parent because only a simple 1:1 inheritance is possible. And tying to implement both would result in a bunch of boilerplate code. With the power of delegations this predicament can be solved with a minimum and clear syntax.

Data classes

data class Resolution(var width: Float, var height: Float) {
	fun getCenter() = Point2D(width / 2, height / 2)
}

Kotlin automatically generates the equals(), hashCode(), toString() and even a copy() for our data class. How kindly, isn’t it? GitHub will miss hundreds of hand written boilerplate code in Kotlin project.

Type Aliases

typealias TexturePair = Pair<TextureRegion, TextureRegion>

private val red: TexturePair
private val blue: TexturePair
private val yellow: TexturePair
private val green: TexturePair

init {
  green = Pair(buttons[0], buttons[1])
  blue = Pair(buttons[2], buttons[3])
  yellow = Pair(buttons[4], buttons[5])
  red = Pair(buttons[6], buttons[7])
}

The Pair is used as alias of Pair<TextureRegion, TextureRegion>. So it’s possible to define a scope where a succinct type name can be used. This reduces boilerplate and can enhance the readability.

Inline Functions

fun render(controller: Controller) {
  val radius = width / 2F
  fun draw(textureRegion: TextureRegion, touchArea: Controller.TouchArea) {
  	val pos = touchArea.rect.getCenter(Vector2()).sub(radius, radius)
  	batch.draw(textureRegion, pos.x, pos.y)
  }

  fun button(button: TexturePair, control: Control): TextureRegion {
  	return if (controller.isPressed(control)) button.second else button.first
  }

  draw(button(red, Control.Left), controller.touchAreas[0])
  draw(button(blue, Control.Right), controller.touchAreas[1])
  draw(button(yellow, Control.Bottom), controller.touchAreas[3])
  draw(button(green, Control.Top), controller.touchAreas[2])
}

Inline functions give us the freedom to place functions in the scope where they're really needed: Often inside another function. This offers a better way for a meaningful encapsulation.

String Templates

override fun toString() =  "Block [$row ${orientation.char()} $stone]"

Get rid of the awful and illegible String concatenation and use it’s template feature. Besides that you can see that’s possible to write short funtions into one line without any brackets.

Operator Overloading

val next = geameField[block.row - 1][block.orientation]

It looks like an elagant array acces. field[block.row - 1] returns a Ring and the [block.orientation] retunrs the Array<Block>. Possible doe the two methods:

operator fun get(orientation: Orientation) = //[...]
operator fun get(index: Int) = //[...]

Null Safety and Elvis Operator

private var activeRing: Ring? = null

private fun resetRing() {
	activeRing?.reset()
}

private fun randomFreeOrientation(): Orientation = activeRing?.randomFreeSide() ?: Orientation.random()

With the ? we can safly call reset(). Trying to acces without this check is even forbitten by the compiler: Only safe (?.) or non-null asserted (!!.) calls are allowed on nullable reciever of type Ring?

The second method randomFreeOrientation() demonstrates the use case for the Elvis Operator (?:). The right side will be only elevated and returned, if the left side was null.

With this null safety, it’s clear if a Kotlin type can be nullable. And the compiler does its best to block us from doing unsafe operations. So welcome to world in peace without nullpointer exceptions. NPE RIP

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].