diff --git a/core/assets/assets b/core/assets/assets index 5fc8871..25528af 160000 --- a/core/assets/assets +++ b/core/assets/assets @@ -1 +1 @@ -Subproject commit 5fc88713c70603365506f3cb691a2d80b7d1305a +Subproject commit 25528afcd4614d6ae4bd056f237ed6a55ecb29aa diff --git a/core/src/me/srikavin/fbla/game/FBLAGame.kt b/core/src/me/srikavin/fbla/game/FBLAGame.kt index ddc3bd6..b8120bf 100644 --- a/core/src/me/srikavin/fbla/game/FBLAGame.kt +++ b/core/src/me/srikavin/fbla/game/FBLAGame.kt @@ -16,6 +16,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGeneratorLoader import com.badlogic.gdx.graphics.g2d.freetype.FreetypeFontLoader +import com.badlogic.gdx.maps.MapProperties import com.badlogic.gdx.maps.tiled.TiledMap import com.badlogic.gdx.maps.tiled.TmxMapLoader import com.badlogic.gdx.math.Vector2 @@ -29,8 +30,10 @@ import com.strongjoshua.console.GUIConsole import ktx.assets.disposeSafely import me.srikavin.fbla.game.Scene.PLAYING import me.srikavin.fbla.game.Scene.TITLE +import me.srikavin.fbla.game.ecs.component.MinigameComponent import me.srikavin.fbla.game.ecs.system.* import me.srikavin.fbla.game.map.MapLoader +import me.srikavin.fbla.game.minigame.dropcatch.DropcatchMinigame import me.srikavin.fbla.game.physics.ContactListenerManager import me.srikavin.fbla.game.ui.MainMenu @@ -74,7 +77,7 @@ class FBLAGame : ApplicationAdapter() { val physicsWorld = com.badlogic.gdx.physics.box2d.World(Vector2(0f, -20f), true) - val stage = Stage(ExtendViewport(640f, 480f)) + val stage = Stage(ExtendViewport(1920f, 1080f)) val root = Table(skin) stage.addActor(root) @@ -125,6 +128,19 @@ class FBLAGame : ApplicationAdapter() { mapLoader.loadMap(world, "assets/maps/${name}.tmx") } + fun mainMenu() { + afterLoad() + } + + fun dropcatch(stage: String) { + world.createEntity().edit().add(MinigameComponent().apply { + minigame = DropcatchMinigame().apply { + reset(MapProperties().apply { put("subtype", stage); put("next_level", "level1.tmx") }, world, mapLoader) + } + }) + + } + fun debug(boolean: Boolean) { world.getSystem(PhysicsDebugSystem::class.java).debug = boolean } @@ -135,6 +151,7 @@ class FBLAGame : ApplicationAdapter() { override fun create() { Colors.put("accent", Color.valueOf("#AA3E39")) + Colors.put("green", Color.valueOf("#00FF00")) batch = SpriteBatch() splashImage = Texture(Gdx.files.internal("assets/graphics/titlelogo.png")) @@ -179,6 +196,7 @@ class FBLAGame : ApplicationAdapter() { mainMenuUI.disposeSafely() scene = PLAYING } + mainMenuUI.build() } override fun render() { @@ -189,7 +207,7 @@ class FBLAGame : ApplicationAdapter() { console.draw() } TITLE -> { - Gdx.gl.glClearColor(20f, 20f, 20f, 1f) + Gdx.gl.glClearColor(0f, 0f, 0f, 1f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT) mainMenuUI.render() @@ -205,8 +223,6 @@ class FBLAGame : ApplicationAdapter() { // Continue loading resources if (assetManager.update()) { afterLoad() - mainMenuUI.build() - scene = TITLE } } } diff --git a/core/src/me/srikavin/fbla/game/ecs/system/MinigameRenderSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/MinigameRenderSystem.kt index 7a0cf84..10ddb6a 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/MinigameRenderSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/MinigameRenderSystem.kt @@ -38,13 +38,14 @@ class MinigameRenderSystem : IteratingSystem() { override fun initialize() { super.initialize() - minigameStage = Stage(ExtendViewport(640f, 480f)) + minigameStage = Stage(ExtendViewport(1920f, 1080f)) registerInputHandler(minigameStage) subscription.addSubscriptionListener(object : EntitySubscription.SubscriptionListener { override fun inserted(entities: IntBag) { for (i in 0 until entities.size()) { val e: EntityInt = entities[i] minigameStage.clear() + minigameStage.viewport.update(Gdx.graphics.width, Gdx.graphics.height) minigameMapper[e].minigame?.initialize(skin, minigameStage) ?: info { "Minigame not initialized upon creation: ${minigameMapper[e]}" } @@ -62,6 +63,7 @@ class MinigameRenderSystem : IteratingSystem() { val minigame = minigameComponent.minigame ?: return if (minigame.active) { + minigameStage.viewport.update(Gdx.graphics.width, Gdx.graphics.height, true) if (!minigame.shouldRenderBackground()) { Gdx.gl.glClearColor(0f, 0f, 0f, 1f) Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT) diff --git a/core/src/me/srikavin/fbla/game/map/MapLoader.kt b/core/src/me/srikavin/fbla/game/map/MapLoader.kt index e9763aa..e41a7a0 100644 --- a/core/src/me/srikavin/fbla/game/map/MapLoader.kt +++ b/core/src/me/srikavin/fbla/game/map/MapLoader.kt @@ -127,8 +127,6 @@ class MapLoader { fun loadMap(world: World, path: String, unload: UnloadType = UnloadType.ALL, customTriggerProcessor: TriggerProcessor = defaultTriggerProcessor): EntityInt { - Throwable().printStackTrace() - if (unload == UnloadType.ALL || unload == UnloadType.NonMinigame) { // Unload previously loaded maps val entities = world.aspectSubscriptionManager[Aspect.all()].entities diff --git a/core/src/me/srikavin/fbla/game/minigame/dropcatch/DropcatchMinigame.kt b/core/src/me/srikavin/fbla/game/minigame/dropcatch/DropcatchMinigame.kt index acca388..a927119 100644 --- a/core/src/me/srikavin/fbla/game/minigame/dropcatch/DropcatchMinigame.kt +++ b/core/src/me/srikavin/fbla/game/minigame/dropcatch/DropcatchMinigame.kt @@ -9,13 +9,19 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.maps.MapProperties import com.badlogic.gdx.maps.objects.RectangleMapObject +import com.badlogic.gdx.math.Interpolation import com.badlogic.gdx.math.Vector2 import com.badlogic.gdx.physics.box2d.* import com.badlogic.gdx.scenes.scene2d.Stage +import com.badlogic.gdx.scenes.scene2d.actions.Actions +import com.badlogic.gdx.scenes.scene2d.ui.Image +import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Skin import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.utils.Drawable +import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable import com.badlogic.gdx.utils.ObjectMap -import com.rafaskoberg.gdx.typinglabel.TypingLabel import ktx.log.info import me.srikavin.fbla.game.EntityInt import me.srikavin.fbla.game.GameState @@ -24,6 +30,8 @@ import me.srikavin.fbla.game.ecs.component.PhysicsBody import me.srikavin.fbla.game.ecs.component.Sprite import me.srikavin.fbla.game.ecs.component.SpriteOffset import me.srikavin.fbla.game.ecs.component.Transform +import me.srikavin.fbla.game.ext.sequence +import me.srikavin.fbla.game.ext.table import me.srikavin.fbla.game.graphics.MAP_SCALE_FACTOR import me.srikavin.fbla.game.map.MapLoader import me.srikavin.fbla.game.minigame.Minigame @@ -31,11 +39,24 @@ import me.srikavin.fbla.game.physics.ContactListenerManager class DropcatchMinigame : Minigame() { private val inputs = GdxArray() - private lateinit var itemsLeft: TypingLabel - private lateinit var timeLeft: TypingLabel + private lateinit var itemsLeft: Label + private lateinit var timeLeft: Label + private lateinit var gameState: GameState + private lateinit var table: Table + private lateinit var infoPanel: Table + private lateinit var container: Table + + private var firstRender = true + private var haveShownScoreboard = false private var goodItemsLeft = 0 private var timeLeftVal = 60f - private lateinit var gameState: GameState + + private val goodItems = ArrayList() + private val badItems = ArrayList() + + private var goodCollected = 0 + private var badCollected = 0 + init { inputs.add(Input.Keys.NUM_1) @@ -46,20 +67,37 @@ class DropcatchMinigame : Minigame() { } override fun resetMinigame(properties: MapProperties) { + goodItems.clear() + badItems.clear() timeLeftVal = 60f + goodCollected = 0 + badCollected = 0 + firstRender = true } override fun initializeMinigame(skin: Skin, stage: Stage) { - val table = Table(skin).center().bottom() - table.setFillParent(true) + container = Table(skin) + container.setSize(1920f, 1080f) + container.setFillParent(true) + + stage.addActor(container) + + table = Table(skin).center().bottom() + table.setSize(170f, 50f) + table.background(NinePatchDrawable(skin.getPatch("menu-button-bg"))) + + container.addActor(table) + + itemsLeft = Label("Items Left: ?", skin) + timeLeft = Label("Time Left: ?", skin) + + - stage.addActor(table) - itemsLeft = TypingLabel("Items Left: ?", skin) - timeLeft = TypingLabel("Time Left: ?", skin) table.add(itemsLeft) table.row() table.add(timeLeft) + gameState = world.getRegistered(GameState::class.java) val mapper = world.getMapper(DropcatchItemComponent::class.java) @@ -117,7 +155,14 @@ class DropcatchMinigame : Minigame() { val triggerProperties = MapTriggerProperties(mapObject.properties) if (!cache.containsKey(triggerProperties.subtype)) { - cache.put(triggerProperties.subtype, TextureRegion(Texture(Gdx.files.internal(triggerProperties.subtype)))) + val texture = TextureRegion(Texture(Gdx.files.internal(triggerProperties.subtype))) + cache.put(triggerProperties.subtype, texture) + + if (type == "gooditem") { + goodItems.add(TextureRegionDrawable(texture)) + } else if (type == "baditem") { + badItems.add(TextureRegionDrawable(texture)) + } } val sprite = cache.get(triggerProperties.subtype) @@ -137,10 +182,12 @@ class DropcatchMinigame : Minigame() { when (type) { "gooditem" -> { editor.add(DropcatchItemComponent().apply { this.type = DropcatchItemType.GOOD }) - goodItemsLeft += 1 + goodItemsLeft++ + goodCollected++ } "baditem" -> { editor.add(DropcatchItemComponent().apply { this.type = DropcatchItemType.BAD }) + badCollected++ } else -> { error("Unknown dropcatch minigame type: $type") @@ -150,8 +197,59 @@ class DropcatchMinigame : Minigame() { } override fun render(camera: OrthographicCamera, batch: SpriteBatch, stage: Stage) { + if (firstRender) { + table.isTransform = true + container.isTransform = true + table.sequence( + Actions.moveTo(1920 / 2f - 150f, 1080 / 3f), + Actions.scaleTo(3f, 3f), + Actions.parallel( + Actions.moveTo(1920 / 2f, table.y, 2.5f, Interpolation.pow2In), + Actions.scaleTo(1f, 1f, 2.5f, Interpolation.pow2In) + ) + ) + infoPanel = container.table(NinePatchDrawable(table.skin.getPatch("menu-button-bg"))) { + it.add("Collect the items as fast as possible, while avoiding unwanted objects!") + it.row() + it.add().height(15f) + it.row() + it.table { t -> + t.table { inner -> + inner.add("[green]Collect:[]").actor.setScale(3f) + + for (item in goodItems) { + info { "$goodItems" } + inner.row() + inner.add(Image(item)).height(50f).width(50f * item.minWidth / item.minHeight) + } + } + + t.add().width(40f) + + t.table { inner -> + inner.add("[accent]Avoid:[]").actor.setScale(3f) + + for (item in badItems) { + info { "$badItems" } + inner.row() + inner.add(Image(item)).height(50f).width(50f * item.minWidth / item.minHeight) + } + } + }.center().bottom() + }.width(880f).height(150f).fill().actor + + infoPanel.sequence( + Actions.fadeIn(7f), + Actions.fadeOut(3f), + Actions.hide() + ) + + + firstRender = false + } + itemsLeft.setText("Items Left: $goodItemsLeft") - timeLeft.setText("Time Left: ${"%.1f".format(timeLeftVal)}") + timeLeft.setText("Time Left: ${timeLeftVal.toInt()}") } override fun shouldRenderBackground(): Boolean { @@ -159,16 +257,42 @@ class DropcatchMinigame : Minigame() { } override fun allowPlayerMovement(): Boolean { - return true + return !(timeLeftVal <= 0 || goodItemsLeft == 0) } override fun process(delta: Float) { - timeLeftVal -= delta - if (timeLeftVal <= 0 || goodItemsLeft == 0) { - Gdx.app.postRunnable { - this.endMinigame() + if (!haveShownScoreboard) { + infoPanel.clear() + + infoPanel.let { + val response = when { + goodItemsLeft == 0 -> "Perfect! You got all of the items!" + goodItemsLeft < 5 -> "You nearly got all of them!" + goodItemsLeft < 10 -> "You could've gotten more." + else -> "Good effort! Better luck next time." + } + it.add(response) + it.row() + it.add("You collected [green]$goodCollected items[], but also [accent]$badCollected unwanted objects[]!") + it.row() + it.add("Score: [green]${goodCollected + timeLeftVal.toInt() - badCollected}[]") + } + + infoPanel.sequence( + Actions.fadeIn(7f), + Actions.fadeOut(3f), + Actions.hide(), + Actions.run { + Gdx.app.postRunnable { + this.endMinigame() + } + } + ) + haveShownScoreboard = true } + } else { + timeLeftVal -= delta } } diff --git a/core/src/me/srikavin/fbla/game/ui/MainMenu.kt b/core/src/me/srikavin/fbla/game/ui/MainMenu.kt index 7b0c51d..8b244dc 100644 --- a/core/src/me/srikavin/fbla/game/ui/MainMenu.kt +++ b/core/src/me/srikavin/fbla/game/ui/MainMenu.kt @@ -12,6 +12,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable import com.badlogic.gdx.utils.Align import com.badlogic.gdx.utils.Disposable +import com.badlogic.gdx.utils.Scaling import com.badlogic.gdx.utils.viewport.ExtendViewport import ktx.actors.alpha import me.srikavin.fbla.game.GdxArray @@ -22,8 +23,13 @@ import me.srikavin.fbla.game.registerInputHandler import me.srikavin.fbla.game.unregisterInputHandler class MainMenu(private val skin: Skin, private val playRunnable: () -> Unit) : Disposable { - private val stage = Stage(ExtendViewport(1920f, 1080f)) + private val stage = Stage(ExtendViewport(1920f, 1080f, 1920f, 1080f)) private val container = Table(skin) + private val cloudContainer = Table(skin) + private val bgStack = Stack() + private val filterStack = Stack() + + private lateinit var submenu: Table private lateinit var infoPanel: Table @@ -33,17 +39,27 @@ class MainMenu(private val skin: Skin, private val playRunnable: () -> Unit) : D private val curButtons: GdxArray