我目前正在研究Lee Stemkoski的book“使用LibGDX开发Java游戏”中的示例。我想尝试Kotlin,并将第2章中的代码转换为Kotlin。
我在问以下代码是否是最佳实践,因为Kotlin代码似乎比Java代码要麻烦得多(而不是“好”)。
class A(val a: Int, val b: String, val c: Int)
// Handmade companion object for demonstration purpose only.
object A {
def unapply(u: A): Option[(Int, String, Int)] =
Some(u.a, u.b, u.c)
}
// No factory method found, so 'new' keyword is necessary.
val a = new A(1, "hello", 3)
/* With real case class the right side expression
calls the unapply of the Object
otherwise call must be explicitly.
*/
val Some((b, _, c)) = A.unapply(a)
// b: Int = 1
// c: Int = 3
def getId(user: A): Int = user match {
case A(_, _, id) => id
}
getId(a) // 3
首先:Java版本仅用三个词定义了可为空的变量:
package chapter2
import com.badlogic.gdx.Game
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.math.Rectangle
class StarfishCollectorAlpha : Game() {
private lateinit var batch: SpriteBatch
private var turtleTexture: Texture? = null
private var turtleX: Float? = null
private var turtleY: Float? = null
private lateinit var turtleRectangle: Rectangle
private var starfishTexture: Texture? = null
private var starfishX: Float? = null
private var starfishY: Float? = null
private lateinit var starfishRectangle: Rectangle
private var oceanTexture: Texture? = null
private var winMessageTexture: Texture? = null
private var win: Boolean? = null
override fun create() {
batch = SpriteBatch()
turtleTexture = Texture(Gdx.files.internal("assets/turtle-1.png"))
turtleX = 20f
turtleY = 20f
turtleRectangle = Rectangle(
turtleX!!,
turtleY!!,
turtleTexture!!.width.toFloat(),
turtleTexture!!.height.toFloat()
)
starfishTexture = Texture(Gdx.files.internal("assets/starfish.png"))
starfishX = 380f
starfishY = 380f
starfishRectangle = Rectangle(
starfishX!!,
starfishY!!,
starfishTexture!!.width.toFloat(),
starfishTexture!!.height.toFloat()
)
oceanTexture = Texture(Gdx.files.internal("assets/water.jpg"))
winMessageTexture = Texture(Gdx.files.internal("assets/you-win.png"))
win = false
}
override fun render() {
// check user input
if (Gdx.input.isKeyPressed(Input.Keys.LEFT))
turtleX = turtleX!! - 1
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT))
turtleX = turtleX!! + 1
if(Gdx.input.isKeyPressed(Input.Keys.UP))
turtleY = turtleY!! + 1
if(Gdx.input.isKeyPressed(Input.Keys.DOWN))
turtleY = turtleY!! - 1
// update turtle rectangle location
turtleRectangle.setPosition(turtleX!!, turtleY!!)
// checks win condition: Turtle must be overlapping starfish
if (turtleRectangle.overlaps(starfishRectangle))
win = true
// clear screen
Gdx.gl.glClearColor(0f, 0f, 0f, 1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
// draw graphics
batch.begin()
batch.draw(oceanTexture, 0f, 0f)
if (!win!!)
batch.draw(starfishTexture, starfishX!!, starfishY!!)
batch.draw(turtleTexture, turtleX!!, turtleY!!)
if (win!!)
batch.draw(winMessageTexture, 180f, 180f)
batch.end()
}
}
第二:您必须使用Kotlin将int显式转换为浮点数,而Java由Java为您管理。
第三:为了使用可为空的定义变量,您必须使用双感叹号!最后,以及每当您要更改它们时。
我想在游戏开发(LibGDX)中使用Kotlin,但在我看来(也许是由于我有限的知识),Java是更好的语言。
请告诉我我的Kotlin代码是垃圾,还有一种更好的方法来重构我的烂摊子。
答案 0 :(得分:0)
对于libgdx来说,通常的情况是要么所有变量都应该为null,要么所有变量都应初始化,并且两者之间什么也没有。因此,您可以在Game类中使用单个可为空的变量来委派给没有可为空属性的上下文类。
这消除了大多数烦人的null检查。
关于需要在数字类型之间进行显式转换-对我来说,这是一个功能:D。我可以看到它可能如何令人讨厌。我会尝试一下,看看它是否会长在您身上。
这是我刚刚出于个人目的而提出的建议:
class GolGui : ApplicationAdapter() {
companion object {
private val SCREEN_HEIGHT = 480
private val SCREEN_WIDTH = 800
private val SCREEN_CENTER_X = SCREEN_WIDTH / 2
private val SCREEN_CENTER_Y = SCREEN_HEIGHT / 2
}
private class Context : Disposable {
val batch = SpriteBatch();
val img = Texture("badlogic.jpg")
val gameSession = GameSession(GameBoard(12, 12))
val camera = OrthographicCamera(SCREEN_WIDTH.toFloat(), SCREEN_HEIGHT.toFloat())
val shapeRenderer = ShapeRenderer()
init {
shapeRenderer.projectionMatrix = camera.combined
}
fun render() {
Gdx.gl.glClearColor(0.2f, 0f, 0f, 1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
shapeRenderer.apply {
begin(ShapeRenderer.ShapeType.Filled)
rect(200f, 200f, 200f, 200f)
end()
}
}
override fun dispose() {
batch.dispose()
img.dispose()
shapeRenderer.dispose()
}
}
private var context: Context? = null
override fun create() {
context = Context()
}
override fun render() {
context!!.render()
}
override fun dispose() {
context!!.dispose()
}
}