diff --git a/core/assets/assets b/core/assets/assets index 4084863..40cb189 160000 --- a/core/assets/assets +++ b/core/assets/assets @@ -1 +1 @@ -Subproject commit 4084863016fedbf0766bba783a780a6ac38f1485 +Subproject commit 40cb189bcfc1e00537382569def5ca220fe67374 diff --git a/core/src/me/srikavin/fbla/game/FBLAGame.kt b/core/src/me/srikavin/fbla/game/FBLAGame.kt index 6194301..0770cf6 100644 --- a/core/src/me/srikavin/fbla/game/FBLAGame.kt +++ b/core/src/me/srikavin/fbla/game/FBLAGame.kt @@ -30,12 +30,15 @@ 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.award.Awards 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.state.GameState import me.srikavin.fbla.game.ui.MainMenu +import me.srikavin.fbla.game.util.GameFonts const val cameraScale = 45f @@ -138,7 +141,14 @@ class FBLAGame : ApplicationAdapter() { reset(MapProperties().apply { put("subtype", stage); put("next_level", "level1.tmx") }, world, mapLoader) } }) + } + + fun addAward(name: String) { + gameState.addAward(name) + } + fun removeAward(name: String) { + gameState.removeAward(name) } fun debug(boolean: Boolean) { @@ -162,6 +172,8 @@ class FBLAGame : ApplicationAdapter() { assetManager.setLoader(FreeTypeFontGenerator::class.java, FreeTypeFontGeneratorLoader(resolver)) assetManager.setLoader(BitmapFont::class.java, ".ttf", FreetypeFontLoader(resolver)) + GameFonts.loadFonts(assetManager, "assets/fonts/font.ttf") + Awards.init(assetManager) fun newCursor(name: String): Cursor { val p = Pixmap(Gdx.files.internal("assets/cursors/$name.png")) @@ -170,21 +182,9 @@ class FBLAGame : ApplicationAdapter() { Gdx.graphics.setCursor(newCursor("cursor")) - val parameter = FreetypeFontLoader.FreeTypeFontLoaderParameter().apply { - fontParameters.apply { - size = 22 - fontFileName = "assets/fonts/font.ttf" - gamma = .8f - } - } - assetManager.load("defaultFont.ttf", BitmapFont::class.java, parameter) - val font = assetManager.finishLoadingAsset("defaultFont.ttf") - font.data.apply { - markupEnabled = true - } - val fontMap = ObjectMap() - fontMap.put("defaultFont", font) + fontMap.put("defaultFont", GameFonts.DEFAULT) + fontMap.put("menuFont", GameFonts.MENU) assetManager.load("assets/skin/skin.json", Skin::class.java, SkinLoader.SkinParameter(fontMap)) } @@ -198,6 +198,8 @@ class FBLAGame : ApplicationAdapter() { } mainMenuUI.build() scene = TITLE + startGame() + scene = PLAYING } override fun render() { diff --git a/core/src/me/srikavin/fbla/game/GameState.kt b/core/src/me/srikavin/fbla/game/GameState.kt deleted file mode 100644 index d9f2fc9..0000000 --- a/core/src/me/srikavin/fbla/game/GameState.kt +++ /dev/null @@ -1,3 +0,0 @@ -package me.srikavin.fbla.game - -data class GameState(var score: Int = 0, var lives: Int = 3) \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/award/America.kt b/core/src/me/srikavin/fbla/game/award/America.kt new file mode 100644 index 0000000..22f67b1 --- /dev/null +++ b/core/src/me/srikavin/fbla/game/award/America.kt @@ -0,0 +1,13 @@ +package me.srikavin.fbla.game.award + +import me.srikavin.fbla.game.state.GameRules + +class America : Award() { + override fun apply(gameRules: GameRules) { + gameRules.enemiesToGold = true + } + + override fun getName(): String { + return "america" + } +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/award/Award.kt b/core/src/me/srikavin/fbla/game/award/Award.kt new file mode 100644 index 0000000..b904b34 --- /dev/null +++ b/core/src/me/srikavin/fbla/game/award/Award.kt @@ -0,0 +1,30 @@ +package me.srikavin.fbla.game.award + +import com.badlogic.gdx.assets.AssetManager +import com.badlogic.gdx.graphics.Texture +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable +import me.srikavin.fbla.game.state.GameRules + +abstract class Award { + private lateinit var texture: Texture + private lateinit var drawable: TextureRegionDrawable + + abstract fun apply(gameRules: GameRules) + + protected abstract fun getName(): String + + fun loadDrawable(assetManager: AssetManager) { + val path = "assets/graphics/awards/${getName()}.png" + assetManager.load(path, Texture::class.java) + texture = assetManager.finishLoadingAsset(path) + drawable = TextureRegionDrawable(texture) + } + + fun getTexture(): Texture { + return texture + } + + fun getDrawable(): TextureRegionDrawable { + return drawable + } +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/award/Awards.kt b/core/src/me/srikavin/fbla/game/award/Awards.kt new file mode 100644 index 0000000..b067d32 --- /dev/null +++ b/core/src/me/srikavin/fbla/game/award/Awards.kt @@ -0,0 +1,28 @@ +package me.srikavin.fbla.game.award + +import com.badlogic.gdx.assets.AssetManager + +object Awards { + val future: Future = Future() + val business: Business = Business() + val leader: Leader = Leader() + val america: America = America() + + private val nameMap = mapOf( + "future" to future, + "business" to business, + "leader" to leader, + "america" to america + ) + + fun init(assetManager: AssetManager) { + future.loadDrawable(assetManager) + business.loadDrawable(assetManager) + leader.loadDrawable(assetManager) + america.loadDrawable(assetManager) + } + + fun getAward(name: String): Award { + return nameMap.getValue(name) + } +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/award/Business.kt b/core/src/me/srikavin/fbla/game/award/Business.kt new file mode 100644 index 0000000..8d1d6b0 --- /dev/null +++ b/core/src/me/srikavin/fbla/game/award/Business.kt @@ -0,0 +1,13 @@ +package me.srikavin.fbla.game.award + +import me.srikavin.fbla.game.state.GameRules + +class Business : Award() { + override fun apply(gameRules: GameRules) { + gameRules.coinMultiplier = 2 + } + + override fun getName(): String { + return "business" + } +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/award/Future.kt b/core/src/me/srikavin/fbla/game/award/Future.kt new file mode 100644 index 0000000..90427e7 --- /dev/null +++ b/core/src/me/srikavin/fbla/game/award/Future.kt @@ -0,0 +1,13 @@ +package me.srikavin.fbla.game.award + +import me.srikavin.fbla.game.state.GameRules + +class Future : Award() { + override fun apply(gameRules: GameRules) { + gameRules.livesGainedPerLevel = 1 + } + + override fun getName(): String { + return "future" + } +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/award/Leader.kt b/core/src/me/srikavin/fbla/game/award/Leader.kt new file mode 100644 index 0000000..539f5a4 --- /dev/null +++ b/core/src/me/srikavin/fbla/game/award/Leader.kt @@ -0,0 +1,13 @@ +package me.srikavin.fbla.game.award + +import me.srikavin.fbla.game.state.GameRules + +class Leader : Award() { + override fun apply(gameRules: GameRules) { + gameRules.enemiesToGold = true + } + + override fun getName(): String { + return "leader" + } +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/dialogue/DialogueManager.kt b/core/src/me/srikavin/fbla/game/dialogue/DialogueManager.kt index 5f6dd8c..f85375a 100644 --- a/core/src/me/srikavin/fbla/game/dialogue/DialogueManager.kt +++ b/core/src/me/srikavin/fbla/game/dialogue/DialogueManager.kt @@ -32,7 +32,7 @@ class DialogueManager(private val stage: Stage, skin: Skin) { private val dialogues = mapOf( "meeting" to DialogueMeeting(), - "make_chapter" to DialogueMakeChapter(), + "recruit" to DialogueMakeChapter(), "job_interview" to DialogueJobInterview(), "office" to DialogueSpeech(), "letter_rec" to DialogueLetterRec(), diff --git a/core/src/me/srikavin/fbla/game/ecs/component/CreatedFromMap.kt b/core/src/me/srikavin/fbla/game/ecs/component/CreatedFromMap.kt index b16091d..c5d8a61 100644 --- a/core/src/me/srikavin/fbla/game/ecs/component/CreatedFromMap.kt +++ b/core/src/me/srikavin/fbla/game/ecs/component/CreatedFromMap.kt @@ -2,7 +2,7 @@ package me.srikavin.fbla.game.ecs.component import com.artemis.Component import com.artemis.annotations.EntityId -import me.srikavin.fbla.game.EntityInt +import me.srikavin.fbla.game.util.EntityInt /** * Component indicating that an entity was the result of loading a map diff --git a/core/src/me/srikavin/fbla/game/ecs/component/Dead.kt b/core/src/me/srikavin/fbla/game/ecs/component/Dead.kt new file mode 100644 index 0000000..4e7e39c --- /dev/null +++ b/core/src/me/srikavin/fbla/game/ecs/component/Dead.kt @@ -0,0 +1,7 @@ +package me.srikavin.fbla.game.ecs.component + +import com.artemis.Component + +class Dead : Component() { + var respawnRunnable: () -> Unit = {} +} \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/ecs/component/PhysicsBody.kt b/core/src/me/srikavin/fbla/game/ecs/component/PhysicsBody.kt index a6a1a45..87008ab 100644 --- a/core/src/me/srikavin/fbla/game/ecs/component/PhysicsBody.kt +++ b/core/src/me/srikavin/fbla/game/ecs/component/PhysicsBody.kt @@ -2,7 +2,7 @@ package me.srikavin.fbla.game.ecs.component import com.artemis.Component import com.badlogic.gdx.physics.box2d.* -import me.srikavin.fbla.game.GdxArray +import me.srikavin.fbla.game.util.GdxArray /** * A component containing the necessary properties to represent an entity as a physics object diff --git a/core/src/me/srikavin/fbla/game/ecs/component/SwitchableAnimation.kt b/core/src/me/srikavin/fbla/game/ecs/component/SwitchableAnimation.kt index de14d09..d29e1d0 100644 --- a/core/src/me/srikavin/fbla/game/ecs/component/SwitchableAnimation.kt +++ b/core/src/me/srikavin/fbla/game/ecs/component/SwitchableAnimation.kt @@ -10,7 +10,31 @@ import ktx.collections.GdxMap */ class SwitchableAnimation : Component() { lateinit var animations: GdxMap> - lateinit var currentState: String + private lateinit var _currentState: String + var currentState: String + get() = _currentState + set(value) { + if (locked <= 0) { + _currentState = value + } + } var mirror: Boolean = false var looping: Boolean = false + private var locked: Float = 0f + + /** + * Lock this animation component to the given animation. Multiple calls to [lock] will override the previous ones. + * + * @param animationName The name of the animation to lock to. + */ + fun lock(animationName: String) { + locked = animations[animationName].animationDuration + _currentState = animationName + } + + fun getCurrentAndUpdate(delta: Float): Animation { + locked -= delta + return animations[currentState] + } + } \ No newline at end of file diff --git a/core/src/me/srikavin/fbla/game/ecs/system/CameraFollowSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/CameraFollowSystem.kt index deac57d..23b2a72 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/CameraFollowSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/CameraFollowSystem.kt @@ -5,6 +5,7 @@ import com.artemis.ComponentMapper import com.artemis.annotations.Wire import com.artemis.managers.TagManager import com.badlogic.gdx.graphics.OrthographicCamera +import me.srikavin.fbla.game.ecs.component.Dead import me.srikavin.fbla.game.ecs.component.Transform /** @@ -16,12 +17,18 @@ import me.srikavin.fbla.game.ecs.component.Transform class CameraFollowSystem(var followVertical: Boolean = true, var followHorizontal: Boolean = true) : BaseSystem() { @Wire private lateinit var transformMapper: ComponentMapper + private lateinit var deadMapper: ComponentMapper + @Wire internal lateinit var camera: OrthographicCamera override fun processSystem() { val player = world.getSystem(TagManager::class.java).getEntityId("PLAYER") + if (deadMapper.has(player)) { + return + } + if (player != -1 && transformMapper.has(player)) { val pos = transformMapper[player].position if (followHorizontal) { diff --git a/core/src/me/srikavin/fbla/game/ecs/system/EntityRenderSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/EntityRenderSystem.kt index 0c011aa..053360f 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/EntityRenderSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/EntityRenderSystem.kt @@ -55,7 +55,7 @@ class EntityRenderSystem : IteratingSystem() { switchableAnimationMapper.has(entityId) -> { val animated = switchableAnimationMapper[entityId] mirrored = animated.mirror - animated.animations[animated.currentState].getKeyFrame(stateTime, animated.looping) + animated.getCurrentAndUpdate(world.delta).getKeyFrame(stateTime, animated.looping) } animatedMapper.has(entityId) -> { val animated = animatedMapper[entityId] diff --git a/core/src/me/srikavin/fbla/game/ecs/system/InputSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/InputSystem.kt index a128240..e292fd0 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/InputSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/InputSystem.kt @@ -12,10 +12,7 @@ import com.badlogic.gdx.physics.box2d.ContactImpulse import com.badlogic.gdx.physics.box2d.ContactListener import com.badlogic.gdx.physics.box2d.Manifold import me.srikavin.fbla.game.GameActions -import me.srikavin.fbla.game.ecs.component.DisableInput -import me.srikavin.fbla.game.ecs.component.PhysicsBody -import me.srikavin.fbla.game.ecs.component.PlayerControlled -import me.srikavin.fbla.game.ecs.component.Transform +import me.srikavin.fbla.game.ecs.component.* import me.srikavin.fbla.game.graphics.player_foot_fixture_id import me.srikavin.fbla.game.physics.ContactListenerManager @@ -37,6 +34,9 @@ class InputSystem(private val listenerManager: ContactListenerManager) : Iterati @Wire private lateinit var physicsBodyMapper: ComponentMapper + @Wire + private lateinit var deadMapper: ComponentMapper + private var allowJump: Int = 0 inner class FootContactListener : ContactListener { @@ -71,6 +71,10 @@ class InputSystem(private val listenerManager: ContactListenerManager) : Iterati override fun process(entityId: Int) { + if (deadMapper.has(entityId)) { + return + } + val body = physicsBodyMapper[entityId].body if (allowJump == 0 && body.linearVelocity.y < -1f && body.linearVelocity.y > -15f) { 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 10ddb6a..b1e63c0 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/MinigameRenderSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/MinigameRenderSystem.kt @@ -14,9 +14,9 @@ import com.badlogic.gdx.scenes.scene2d.Stage import com.badlogic.gdx.scenes.scene2d.ui.Skin import com.badlogic.gdx.utils.viewport.ExtendViewport import ktx.log.info -import me.srikavin.fbla.game.EntityInt import me.srikavin.fbla.game.ecs.component.MinigameComponent -import me.srikavin.fbla.game.registerInputHandler +import me.srikavin.fbla.game.util.EntityInt +import me.srikavin.fbla.game.util.registerInputHandler /** * Handles rendering active minigames diff --git a/core/src/me/srikavin/fbla/game/ecs/system/PhysicsSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/PhysicsSystem.kt index e62b29e..d2652d6 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/PhysicsSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/PhysicsSystem.kt @@ -91,8 +91,26 @@ class PhysicsSystem(var physicsWorld: World, private val contactManager: Contact } } + val filter = Filter() + filter.groupIndex = -1 + fixtures.forEach { + it.filterData = filter + } + if (e == world.getSystem(TagManager::class.java).getEntityId("PLAYER")) { + // Increased friction when touching ground without affecting wall sliding + val feet = FixtureDef().apply { + // this.isSensor = true + this.shape = PolygonShape().apply { + setAsBox(0.6f, 0.05f, Vector2(0f, -1f), 0f) + } + friction = .9f + } + + fixtures.add(physics.body.createFixture(feet)) + + // Used to detect when the player is on the ground val footBox = FixtureDef().apply { // this.isSensor = true this.shape = PolygonShape().apply { @@ -103,9 +121,18 @@ class PhysicsSystem(var physicsWorld: World, private val contactManager: Contact val fixture = physics.body.createFixture(footBox) fixture.userData = player_foot_fixture_id + fixture.isSensor = true fixtures.add(fixture) + + + // Apply a filter to allow for the death animation + filter.groupIndex = 1 + fixtures.forEach { + it.filterData = filter + } } + physics.fixtures = fixtures } } diff --git a/core/src/me/srikavin/fbla/game/ecs/system/TriggerSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/TriggerSystem.kt index 7227caf..4587fea 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/TriggerSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/TriggerSystem.kt @@ -5,11 +5,11 @@ import com.artemis.ComponentMapper import com.artemis.annotations.All import com.artemis.managers.TagManager import com.badlogic.gdx.physics.box2d.* -import me.srikavin.fbla.game.EntityInt import me.srikavin.fbla.game.ecs.component.MapTrigger import me.srikavin.fbla.game.ecs.component.PhysicsBody import me.srikavin.fbla.game.physics.ContactListenerManager import me.srikavin.fbla.game.trigger.TriggerManager +import me.srikavin.fbla.game.util.EntityInt /** * Responsible for handling trigger @@ -84,6 +84,7 @@ class TriggerSystem(private val listenerManager: ContactListenerManager) : BaseE } override fun processSystem() { + triggerManager.tick(world) collisions.forEach { if (triggerMapper.has(it.other)) { triggerManager.handle(world, it.player, it.other, triggerMapper[it.other]) diff --git a/core/src/me/srikavin/fbla/game/ecs/system/TutorialSystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/TutorialSystem.kt index aefd2c0..7c99cbc 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/TutorialSystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/TutorialSystem.kt @@ -5,10 +5,10 @@ import com.artemis.annotations.All import com.artemis.annotations.Wire import com.artemis.systems.EntityProcessingSystem import com.badlogic.gdx.scenes.scene2d.Stage -import me.srikavin.fbla.game.EntityInt import me.srikavin.fbla.game.ecs.component.MapTrigger import me.srikavin.fbla.game.ecs.component.PhysicsBody import me.srikavin.fbla.game.physics.ContactListenerManager +import me.srikavin.fbla.game.util.EntityInt /** * Responsible for handling tutorial components diff --git a/core/src/me/srikavin/fbla/game/ecs/system/UISystem.kt b/core/src/me/srikavin/fbla/game/ecs/system/UISystem.kt index a46d854..52f200d 100644 --- a/core/src/me/srikavin/fbla/game/ecs/system/UISystem.kt +++ b/core/src/me/srikavin/fbla/game/ecs/system/UISystem.kt @@ -1,54 +1,60 @@ package me.srikavin.fbla.game.ecs.system import com.artemis.BaseSystem +import com.artemis.ComponentMapper import com.artemis.annotations.Wire -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.scenes.scene2d.Stage -import com.badlogic.gdx.scenes.scene2d.ui.Cell -import com.badlogic.gdx.scenes.scene2d.ui.Label -import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.artemis.managers.TagManager +import com.badlogic.gdx.scenes.scene2d.ui.Skin import com.rafaskoberg.gdx.typinglabel.TypingConfig -import me.srikavin.fbla.game.GameState -import me.srikavin.fbla.game.registerInputHandler +import me.srikavin.fbla.game.ecs.component.Dead +import me.srikavin.fbla.game.state.GameState +import me.srikavin.fbla.game.ui.DeadUI +import me.srikavin.fbla.game.ui.GameHudUI /** * Responsible for drawing and updating UI elements */ class UISystem : BaseSystem() { - @Wire - private lateinit var stage: Stage - @Wire - private lateinit var root: Table - @Wire - private lateinit var gameState: GameState + private lateinit var gameHudUI: GameHudUI + private lateinit var deadUI: DeadUI - private lateinit var scoreCell: Cell