Finish the Simple Game Extended section

This commit is contained in:
2026-02-07 00:11:05 +00:00
parent cfebae281d
commit 5c89bd0d94
5 changed files with 156 additions and 183 deletions

View File

@@ -1,16 +1,16 @@
package com.badlogic.drop.android package com.badlogic.drop.android
import android.os.Bundle import android.os.Bundle
import com.badlogic.drop.Drop
import com.badlogic.gdx.backends.android.AndroidApplication import com.badlogic.gdx.backends.android.AndroidApplication
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration
import com.badlogic.drop.Main
/** Launches the Android application. */ /** Launches the Android application. */
class AndroidLauncher : AndroidApplication() { class AndroidLauncher : AndroidApplication() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
initialize(Main(), AndroidApplicationConfiguration().apply { initialize(Drop(), AndroidApplicationConfiguration().apply {
// Configure your application here. // Configure your application here.
useImmersiveMode = true // Recommended, but not required. useImmersiveMode = true // Recommended, but not required.
}) })

View File

@@ -7,14 +7,19 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.utils.viewport.FitViewport import com.badlogic.gdx.utils.viewport.FitViewport
class Drop : Game() { class Drop : Game() {
val batch: SpriteBatch = SpriteBatch() lateinit var batch: SpriteBatch
val viewport: FitViewport = FitViewport(8f, 5f) // We put viewport above font for the .appy scope function lateinit var font: BitmapFont
val font: BitmapFont = BitmapFont().apply { //lateinit var viewport: FitViewport // Use camera instead of viewport
setUseIntegerPositions(false)
data.scale(viewport.worldHeight / Gdx.graphics.height)
}
override fun create(): Unit { override fun create(): Unit {
batch = SpriteBatch()
//viewport = FitViewport(8f, 5f)
/*font = BitmapFont().apply {
setUseIntegerPositions(false)
data.scale(viewport.worldHeight / Gdx.graphics.height)
}*/
font = BitmapFont()
this.screen = MainMenuScreen(this) this.screen = MainMenuScreen(this)
} }

View File

@@ -1,34 +1,146 @@
package com.badlogic.drop package com.badlogic.drop
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Screen import com.badlogic.gdx.Screen
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.Gdx.audio
import com.badlogic.gdx.Input
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.Sprite
import com.badlogic.gdx.math.MathUtils
import com.badlogic.gdx.math.Rectangle
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.math.Vector3
import com.badlogic.gdx.utils.ScreenUtils
import ktx.assets.toInternalFile
class GameScreen(val game: Drop) : Screen {
val camera = OrthographicCamera().apply { setToOrtho(false, 800f, 480f) }
val backgroundTexture = Texture("background.png")
val bucketTexture = Texture("bucket.png")
val dropTexture = Texture("drop.png")
val dropSound = audio.newSound("drop.mp3".toInternalFile())
val music = audio.newMusic("music.mp3".toInternalFile()).apply {
isLooping = true
volume = 0.5f
}
val bucketSprite = Sprite(bucketTexture).apply { setSize(64f, 64f) }
val touchPos = Vector3()
val dropSprites = mutableListOf<Sprite>()
val dropSpeed = -128f
var dropTimer = 0f
val bucketRectangle = Rectangle()
val dropRectangle = Rectangle()
var dropsGathered = 0
class GameScreen(val newGame: Drop) : Screen {
override fun show() { override fun show() {
TODO("Not yet implemented") music.play()
} }
override fun render(delta: Float) { override fun render(delta: Float) {
TODO("Not yet implemented") input()
logic()
draw()
} }
override fun resize(width: Int, height: Int) { private fun input() {
TODO("Not yet implemented") val speed = 4f
val delta: Float = Gdx.graphics.deltaTime
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
bucketSprite.translateX(speed * delta)
}
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
bucketSprite.translateX(-speed * delta)
} }
override fun pause() { if (Gdx.input.isTouched) {
TODO("Not yet implemented") touchPos.set(Gdx.input.x.toFloat(), Gdx.input.y.toFloat(), 0f)
camera.unproject(touchPos)
bucketSprite.setCenterX(touchPos.x)
}
} }
override fun resume() { private fun logic() {
TODO("Not yet implemented") val worldWidth: Float = camera.viewportWidth
val worldHeight: Float = camera.viewportHeight
val bucketWidth: Float = bucketSprite.width
val bucketHeight: Float = bucketSprite.height
val delta: Float = Gdx.graphics.deltaTime
bucketSprite.x = MathUtils.clamp(bucketSprite.x, 0f, worldWidth - bucketWidth)
bucketRectangle.set(bucketSprite.x, bucketSprite.y, bucketWidth, bucketHeight)
for (dropSprite in dropSprites.reversed()) {
val dropWidth: Float = dropSprite.width
val dropHeight: Float = dropSprite.height
dropSprite.translateY(dropSpeed * delta * (MathUtils.clamp((dropsGathered.toFloat() + 1f) / 5f, 1f, Float.MAX_VALUE)))
dropRectangle.set(dropSprite.x, dropSprite.y, dropWidth, dropHeight)
if (dropSprite.y < -dropHeight) dropSprites.remove(dropSprite)
else if (bucketRectangle.overlaps(dropRectangle)) {
dropsGathered++
dropSprites.remove(dropSprite)
dropSound.play()
}
} }
override fun hide() { dropTimer += delta
TODO("Not yet implemented") if (dropTimer > 1f) {
dropTimer = 0f
createDroplet()
} }
}
private fun draw() {
ScreenUtils.clear(Color.BLACK)
camera.update()
game.batch.projectionMatrix = camera.combined
game.batch.begin()
val worldWidth: Float = camera.viewportWidth
val worldHeight: Float = camera.viewportHeight
game.batch.draw(backgroundTexture, 0f, 0f, worldWidth, worldHeight)
bucketSprite.draw(game.batch)
game.font.draw(game.batch, "Drops collected: $dropsGathered", 0f, worldHeight)
for (dropSprite in dropSprites) dropSprite.draw(game.batch)
game.batch.end()
}
private fun createDroplet() {
val dropWidth = 64f
val dropHeight = 64f
val worldWidth: Float = camera.viewportWidth
val worldHeight: Float = camera.viewportHeight
val dropSprite = Sprite(dropTexture).apply {
setSize(dropWidth, dropHeight)
x = MathUtils.random(0f, worldWidth - dropWidth)
y = worldHeight
}
dropSprites.add(dropSprite)
}
override fun resize(width: Int, height: Int) = Unit
override fun pause() = Unit
override fun resume() = Unit
override fun hide() = Unit
override fun dispose() { override fun dispose() {
TODO("Not yet implemented") backgroundTexture.dispose()
dropSound.dispose()
music.dispose()
dropTexture.dispose()
bucketTexture.dispose()
} }
} }

View File

@@ -1,138 +0,0 @@
package com.badlogic.drop
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Gdx.audio
import com.badlogic.gdx.audio.Music
import com.badlogic.gdx.audio.Sound
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.Texture.TextureFilter.Linear
import com.badlogic.gdx.graphics.g2d.Sprite
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.math.MathUtils
import com.badlogic.gdx.math.Rectangle
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.utils.ScreenUtils
import com.badlogic.gdx.utils.viewport.FitViewport
import ktx.app.KtxGame
import ktx.app.KtxScreen
import ktx.assets.disposeSafely
import ktx.assets.toInternalFile
import ktx.async.KtxAsync
import ktx.graphics.use
class Main : KtxGame<KtxScreen>() {
override fun create() {
KtxAsync.initiate()
addScreen(FirstScreen())
setScreen<FirstScreen>()
}
class FirstScreen : KtxScreen {
private val backgroundTexture: Texture = Texture("background.png".toInternalFile(), true).apply { setFilter(Linear, Linear) }
private val bucketTexture: Texture = Texture("bucket.png".toInternalFile(), true).apply { setFilter(Linear, Linear) }
private val dropTexture: Texture = Texture("drop.png".toInternalFile(), true).apply { setFilter(Linear, Linear) }
private val dropSound: Sound = audio.newSound("drop.mp3".toInternalFile())
private val music: Music = audio.newMusic("music.mp3".toInternalFile()).apply {
isLooping = true
volume = 0.5f
play()
}
private val bucketSprite: Sprite = Sprite(bucketTexture).apply { setSize(1f, 1f) }
private val image = Texture("logo.png".toInternalFile(), true).apply { setFilter(Linear, Linear) }
private val batch = SpriteBatch()
private val viewport = FitViewport(8f, 5f)
private var touchPos: Vector2 = Vector2()
private var dropletSpriteList: MutableList<Sprite> = mutableListOf()
private var dropTimer: Float = 0f
private val bucketRectangle: Rectangle = Rectangle()
private val dropletRectangle: Rectangle = Rectangle()
override fun resize(width: Int, height: Int) {
viewport.update(width, height, true)
}
override fun render(delta: Float) {
input()
logic()
draw()
}
override fun dispose() {
image.disposeSafely()
batch.disposeSafely()
}
private fun input() {
if (Gdx.input.isTouched) {
touchPos.set(Gdx.input.x.toFloat(), Gdx.input.y.toFloat())
viewport.unproject(touchPos)
bucketSprite.setCenterX(touchPos.x)
}
}
private fun logic() {
val worldWidth: Float = viewport.worldWidth
bucketSprite.x = MathUtils.clamp(bucketSprite.x, 0f, worldWidth - bucketSprite.width)
val delta: Float = Gdx.graphics.deltaTime
bucketRectangle.set(bucketSprite.x, bucketSprite.y, bucketSprite.width, bucketSprite.height)
for (sprite in dropletSpriteList.reversed()) {
sprite.translateY(-2f * delta)
dropletRectangle.set(sprite.x, sprite.y, sprite.width, sprite.height)
if (sprite.y < -sprite.height) dropletSpriteList.remove(sprite)
else if (bucketRectangle.overlaps(dropletRectangle)) {
dropletSpriteList.remove(sprite)
dropSound.play()
}
}
dropTimer += delta
if (dropTimer >= 1f)
{
dropTimer = 0f
dropletSpriteList.add(createDroplet())
}
//Gdx.app.log("Droplets", dropletSpriteList.size.toString() + " in List")
}
private fun draw() {
ScreenUtils.clear(Color.BLACK)
viewport.apply()
batch.setProjectionMatrix(viewport.camera.combined)
batch.use {
it.draw(backgroundTexture, 0f, 0f, viewport.worldWidth, viewport.worldHeight)
for (s in dropletSpriteList) {
s.draw(it)
}
bucketSprite.draw(it)
}
}
private fun createDroplet(): Sprite {
val dropWidth: Float = 1f
val dropHeight: Float = 1f
val worldWidth: Float = viewport.worldWidth
val worldHeight: Float = viewport.worldHeight
val dropSprite: Sprite = Sprite(dropTexture).apply {
setSize(dropWidth, dropHeight)
x = MathUtils.random(0f, worldWidth - dropWidth)
y = worldHeight //- dropHeight // Spawn droplet above world for cleaner transition in?
} // We don't add the object to the set here because apply is really meant for doing stuff with members
return dropSprite
}
}
}

View File

@@ -3,26 +3,30 @@ package com.badlogic.drop
import com.badlogic.gdx.Screen import com.badlogic.gdx.Screen
import com.badlogic.gdx.Gdx import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.OrthographicCamera
import com.badlogic.gdx.utils.ScreenUtils import com.badlogic.gdx.utils.ScreenUtils
class MainMenuScreen(val newGame: Drop) : Screen { class MainMenuScreen(val game: Drop) : Screen {
private val camera = OrthographicCamera()
val game: Drop = newGame init {
camera.setToOrtho(false, 800f, 480f)
override fun show() {
TODO("Not yet implemented")
} }
override fun show() = Unit
override fun render(delta: Float) { override fun render(delta: Float) {
ScreenUtils.clear(Color.BLACK) ScreenUtils.clear(Color.BLACK)
game.viewport.apply() //game.viewport.apply()
game.batch.projectionMatrix = game.viewport.camera.combined //game.batch.projectionMatrix = game.viewport.camera.combined
camera.update()
game.batch.projectionMatrix = camera.combined
game.batch.begin() game.batch.begin()
game.font.draw(game.batch, "Wekcine to Drop!!!", 1f, 1.5f) game.font.draw(game.batch, "Welcome to Drop!!!", 100f, 150f)
game.font.draw(game.batch, "Tap anywhere to begin!", 1f, 1f) game.font.draw(game.batch, "Tap anywhere to begin!", 100f, 100f)
game.batch.end() game.batch.end()
@@ -32,23 +36,13 @@ class MainMenuScreen(val newGame: Drop) : Screen {
} }
override fun resize(width: Int, height: Int) { override fun resize(width: Int, height: Int) = Unit
TODO("Not yet implemented")
}
override fun pause() { override fun pause() = Unit
TODO("Not yet implemented")
}
override fun resume() { override fun resume() = Unit
TODO("Not yet implemented")
}
override fun hide() { override fun hide() = Unit
TODO("Not yet implemented")
}
override fun dispose() { override fun dispose() = Unit
TODO("Not yet implemented")
}
} }