LibGDX:Kotlin与Java

时间:2018-12-02 15:52:27

标签: java kotlin libgdx

我目前正在研究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代码是垃圾,还有一种更好的方法来重构我的烂摊子。

1 个答案:

答案 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()
  }
}