Skip to content

Commit

Permalink
Merge pull request #15 from ImXico/0.3.1
Browse files Browse the repository at this point in the history
Changelog:
- Moved `StateManager` FBO-related code to a new file, `TransitionFBO.kt`.
- Add AssetManager notes for `audio` and `image` modules.
- Minor code changes (code style, type inference...).
  • Loading branch information
ImXico authored Dec 28, 2018
2 parents d2a1a61 + 4309564 commit e791d71
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 114 deletions.
7 changes: 6 additions & 1 deletion audio/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
**Note**

> LibGDX provides [AssetManager](https://github.com/libgdx/libgdx/wiki/Managing-your-assets), which has a fully-fledged API for loading, storing and fetching assets (sounds, music, textures, fonts...). Using `AssetManager` (with maybe some DI framework) might be a more scalable and testable solution as projects grow in complexity. The manager modules (`ImageManager`, `SoundManger`, `MusicManager`...) may eventually become wrappers around `AssetManager`. Until then, they'll remain as singleton-based managers whose simplicity might come in handy for game jams or PoCs.
The audio package for Cyberpunk is split into two different utilities: [`SoundManager`](#soundmanager) and [`MusicManager`](#musicmanager).

### SoundManager
Expand All @@ -23,12 +27,13 @@ SoundManager.pause("mysound")
SoundManager.resume("mysound")
```

Diposose it when you don't need to use it anymore - hey, leave a good footprint!
Dispose it when you don't need to use it anymore - hey, leave a good footprint!
```kotlin
SoundManager.dispose("mysound")
```

### MusicManager

The [`MusicManager`](https://github.com/ImXico/Cyberpunk/blob/master/audio/src/main/kotlin/cyberpunk/audio/MusicManager.kt) will hold [`Music`](https://github.com/libgdx/libgdx/wiki/Streaming-music) instances. As stated in the official libGDX [wiki](https://github.com/libgdx/libgdx/wiki/Streaming-music):
> For any sound that's longer than a few seconds, it is preferable to stream it from disk instead of fully loading it into RAM. Libgdx provides a Music interface that lets you do that.
Expand Down
1 change: 1 addition & 0 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Start out by initializing the `StateManager`:
private lateinit var stateManager: StateManager

override fun create() {

// Have a Camera
val camera = OrthographicCamera(WORLD_WIDTH.toFloat(), WORLD_HEIGHT.toFloat())
camera.position.set(viewportWidth / 2f, viewportHeight / 2f, 0f)
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/kotlin/cyberpunk/core/WorldConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

package cyberpunk.core

@JvmField val WORLD_WIDTH = 700
@JvmField val WORLD_HEIGHT = 300
const val WORLD_WIDTH = 700
const val WORLD_HEIGHT = 300
6 changes: 3 additions & 3 deletions core/src/main/kotlin/cyberpunk/core/state/StateAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ abstract class StateAdapter(protected val stateManager: StateManager) : State {
/**
* State methods that absolutely must be overridden.
*/
override abstract fun update(delta: Float)
override abstract fun render(batch: Batch)
override abstract fun dispose()
abstract override fun update(delta: Float)
abstract override fun render(batch: Batch)
abstract override fun dispose()

/**
* State methods that may or may not be overridden (no-op implementation).
Expand Down
67 changes: 14 additions & 53 deletions core/src/main/kotlin/cyberpunk/core/state/StateManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package cyberpunk.core.state

import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Camera
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.g2d.Batch
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import com.badlogic.gdx.utils.viewport.Viewport
import cyberpunk.core.transition.Transition
import cyberpunk.core.transition.TransitionFBO

/**
* Initializes the [StateManager] with it a [Camera] and [Viewport].
Expand All @@ -33,22 +32,15 @@ class StateManager(val camera: Camera, val viewport: Viewport) {
private var transition: Transition? = null

/**
* [FrameBuffer] objects and [TextureRegion]s for the transitions.
* Initialized at the init block, under [setupFBOs].
* Holds the frame buffer objects (FBOs) and flipped regions
* that are used during transitions.
*/
lateinit private var currentFBO: FrameBuffer
lateinit private var nextFBO: FrameBuffer
lateinit private var currentFlippedRegion: TextureRegion
lateinit private var nextFlippedRegion: TextureRegion
private val transitionFBO = TransitionFBO()

/**
* [Batch] used to render everything.
*/
private val batch: Batch = SpriteBatch()

init {
setupFBOs()
}
private val batch = SpriteBatch()

/**
* Sets a [State] to be the currently running one. Optionally, pass
Expand Down Expand Up @@ -77,7 +69,9 @@ class StateManager(val camera: Camera, val viewport: Viewport) {
*/
fun update(delta: Float) {
currentState?.update(delta)
transition?.let { if (it.running()) it.update(delta) }
transition?.let {
if (it.running()) it.update(delta)
}
}

/**
Expand All @@ -98,11 +92,10 @@ class StateManager(val camera: Camera, val viewport: Viewport) {
currentState?.render(batch)
Gdx.input.inputProcessor = currentState
} else {
currentFBO.wrap { currentState?.render(batch) }
nextFBO.wrap { nextState?.render(batch) }
currentFlippedRegion.texture = currentFBO.colorBufferTexture
nextFlippedRegion.texture = nextFBO.colorBufferTexture
transition?.render(batch, currentFlippedRegion, nextFlippedRegion)
transitionFBO.wrapCurrent { currentState?.render(batch) }
transitionFBO.wrapNext { nextState?.render(batch) }
val (currentRegion, nextRegion) = transitionFBO.getFlippedRegions()
transition?.render(batch, currentRegion, nextRegion)
}
}
}
Expand Down Expand Up @@ -144,45 +137,13 @@ class StateManager(val camera: Camera, val viewport: Viewport) {
fun dispose() {
currentState?.dispose()
nextState?.dispose()
currentFBO.dispose()
nextFBO.dispose()
}

/**
* Utility extension function to wrap any [block] inside the
* [FrameBuffer.begin] and [FrameBuffer.end] calls, for shortness.
* @param block a [Unit] returning function.
*/
private inline fun FrameBuffer.wrap(block: () -> Unit) {
this.begin()
block()
this.end()
}

/**
* Initializes the [FrameBuffer] objects and the [TextureRegion]s that will
* serve any running [Transition].
*/
private fun setupFBOs() {
val screenWidth = Gdx.graphics.width
val screenHeight = Gdx.graphics.height
currentFBO = FrameBuffer(Pixmap.Format.RGBA8888, screenWidth, screenHeight, false)
nextFBO = FrameBuffer(Pixmap.Format.RGBA8888, screenWidth, screenHeight, false)
currentFlippedRegion = TextureRegion(currentFBO.colorBufferTexture)
currentFlippedRegion.flip(false, true)
nextFlippedRegion = TextureRegion(nextFBO.colorBufferTexture)
nextFlippedRegion.flip(false, true)
transitionFBO.dispose()
}

/**
* Resizes the [FrameBuffer] objects in every [StateManager.resize] call.
* @param width new screen width.
* @param height new screen height.
*/
private fun resizeFBOs(width: Int, height: Int) {
currentFBO.dispose()
nextFBO.dispose()
currentFBO = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
nextFBO = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
}
private fun resizeFBOs(width: Int, height: Int) = transitionFBO.resize(width, height)
}
4 changes: 2 additions & 2 deletions core/src/main/kotlin/cyberpunk/core/transition/Transition.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ interface Transition {
* Checks whether or not this [Transition] is running.
* @return true if it is running, false otherwise.
*/
fun running(): Boolean = running
fun running() = running

/**
* Checks whether or not this [Transition] is completed.
* @return true if it is completed, false otherwise.
*/
fun completed(): Boolean = !running
fun completed() = !running

/**
* Updates the [Transition].
Expand Down
91 changes: 91 additions & 0 deletions core/src/main/kotlin/cyberpunk/core/transition/TransitionFBO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package cyberpunk.core.transition

import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.graphics.glutils.FrameBuffer

/**
* Holds the frame buffer objects (FBOs) and flipped regions
* that are used during state transitions.
*/
internal class TransitionFBO {

/**
* [FrameBuffer] objects that are used to wrap render calls during state transitions.
*/
private var currentFBO: FrameBuffer
private var nextFBO: FrameBuffer

/**
* [TextureRegion] objects that represent frames before and after a transition.
*/
private var currentFlippedRegion: TextureRegion
private var nextFlippedRegion: TextureRegion

init {
val screenWidth = Gdx.graphics.width
val screenHeight = Gdx.graphics.height
currentFBO = FrameBuffer(Pixmap.Format.RGBA8888, screenWidth, screenHeight, false)
nextFBO = FrameBuffer(Pixmap.Format.RGBA8888, screenWidth, screenHeight, false)
currentFlippedRegion = TextureRegion(currentFBO.colorBufferTexture)
currentFlippedRegion.flip(false, true)
nextFlippedRegion = TextureRegion(nextFBO.colorBufferTexture)
nextFlippedRegion.flip(false, true)
}

/**
* Dispose the current and next FBOs.
*/
internal fun dispose() {
currentFBO.dispose()
nextFBO.dispose()
}

/**
* Resizes the [FrameBuffer] objects.
* The [FrameBuffer] objects are disposed manually and re-defined.
* @param width new screen width.
* @param height new screen height.
*/
internal fun resize(width: Int, height: Int) {
this.dispose()
currentFBO = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
nextFBO = FrameBuffer(Pixmap.Format.RGBA8888, width, height, false)
}

/**
* Render an arbitrary block onto the currentFBO.
* @param block a [Unit] returning function.
*/
internal fun wrapCurrent(block: () -> Unit) {
currentFBO.wrap { block() }
currentFlippedRegion.texture = currentFBO.colorBufferTexture
}

/**
* Render an arbitrary block onto the nextFBO.
* @param block a [Unit] returning function.
*/
internal fun wrapNext(block: () -> Unit) {
nextFBO.wrap { block() }
nextFlippedRegion.texture = nextFBO.colorBufferTexture
}

/**
* Return the current and next flipped regions in an easy-to-destruct way.
* @return a [Pair] holding both flipped regions.
*/
internal fun getFlippedRegions() = Pair(currentFlippedRegion, nextFlippedRegion)

/**
* Utility extension function to wrap any [block] inside the
* [FrameBuffer.begin] and [FrameBuffer.end] calls, for shortness.
* @param block a [Unit] returning function.
*/
private inline fun FrameBuffer.wrap(block: () -> Unit) {
this.begin()
block()
this.end()
}
}
17 changes: 7 additions & 10 deletions core/src/main/kotlin/cyberpunk/core/transition/types/Fade.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,31 @@ import cyberpunk.core.WORLD_HEIGHT
import cyberpunk.core.WORLD_WIDTH
import cyberpunk.core.transition.Transition

@JvmField val DEFAULT_SPEED: Float = 1.5f
const val DEFAULT_SPEED = 1.5f

class Fade
@JvmOverloads
constructor(private var speed: Float = DEFAULT_SPEED) : Transition {

@JvmField val MAX_ALPHA: Float = 1f
@JvmField val DEFAULT_ALPHA_INC: Float = 0.05f
@JvmField val MAX_ALPHA = 1f
@JvmField val DEFAULT_ALPHA_INC = 0.05f

/**
* Overrides the property defined at the [Transition] interface.
*
* @property [Transition.running]
*/
override var running: Boolean = false
override var running = false

/**
* Current alpha, ranging from 0 to [MAX_ALPHA].
*
* @see MAX_ALPHA
*/
private var alpha: Float = 0f
private var alpha = 0f

/**
* Alpha increment to be used at each frame
*/
private val alphaInc: Float = calculateAlphaInc()
private val alphaInc = calculateAlphaInc()

/**
* @see [Transition.update]
Expand Down Expand Up @@ -60,8 +58,7 @@ class Fade

/**
* Calculates the alpha increment to be used at each frame based on the [speed] property.
*
* @return alpha increment.
*/
private fun calculateAlphaInc(): Float = this.speed * DEFAULT_ALPHA_INC / DEFAULT_SPEED
private fun calculateAlphaInc() = this.speed * DEFAULT_ALPHA_INC / DEFAULT_SPEED
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ enum class Motion (
LEFT_TO_RIGHT(Vector2(), Vector2(-WORLD_WIDTH.toFloat(), 0f), Vector2(WORLD_WIDTH.toFloat(), 0f), Vector2())
}

@JvmField val DEFAULT_LERP = 0.2f
const val DEFAULT_LERP = 0.2f

class HorizontalSlide
@JvmOverloads
Expand All @@ -35,17 +35,17 @@ class HorizontalSlide
* Overrides the property defined at the [Transition] interface.
* @property [Transition.running]
*/
override var running: Boolean = false
override var running = false

/**
* Current position, in the form of a [Vector2], of the current state.
*/
private val currentStateCurrentPos: Vector2 = motion.currentInitial
private val currentStateCurrentPos = motion.currentInitial

/**
* Current position, in the form of a [Vector2], of the next state.
*/
private val nextStateCurrentPos: Vector2 = motion.nextInitial
private val nextStateCurrentPos = motion.nextInitial

/**
* Overrides the default [Transition.completed] function, declared
Expand Down
6 changes: 5 additions & 1 deletion image/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
Likewise the [`audio`](https://github.com/ImXico/Cyberpunk/tree/master/audio) module, the [`image`]() extension is also split in two classes: [`ImageManager`](https://github.com/ImXico/Cyberpunk/blob/master/image/src/main/kotlin/cyberpunk/image/ImageManager.kt) and [`ImageHelper`](https://github.com/ImXico/Cyberpunk/blob/master/image/src/main/kotlin/cyberpunk/image/ImageHelper.kt).
**Note**

> LibGDX provides [AssetManager](https://github.com/libgdx/libgdx/wiki/Managing-your-assets), which has a fully-fledged API for loading, storing and fetching assets (sounds, music, textures, fonts...). Using `AssetManager` (with maybe some DI framework) might be a more scalable and testable solution as projects grow in complexity. The manager modules (`ImageManager`, `SoundManger`, `MusicManager`...) may eventually become wrappers around `AssetManager`. Until then, they'll remain as singleton-based managers whose simplicity might come in handy for game jams or PoCs.
The [`image`]() extension is split in two classes: [`ImageManager`](https://github.com/ImXico/Cyberpunk/blob/master/image/src/main/kotlin/cyberpunk/image/ImageManager.kt) and [`ImageHelper`](https://github.com/ImXico/Cyberpunk/blob/master/image/src/main/kotlin/cyberpunk/image/ImageHelper.kt).

### ImageManager
This is made to be used with [`TextureAtlas`](https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/TextureAtlas.html). Information on how to use the TexturePacker to pack many smaller images onto larger images can be found [here](https://github.com/libgdx/libgdx/wiki/Texture-packer).
Expand Down
2 changes: 1 addition & 1 deletion image/src/main/kotlin/cyberpunk/image/ImageManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object ImageManager {
@JvmOverloads
fun load(key: String, path: String, setAsDefault: Boolean = false) {
val atlas = TextureAtlas(Gdx.files.internal(path))
atlases.put(key, atlas)
atlases[key] = atlas
if (setAsDefault) {
DEFAULT_ATLAS_KEY = key
}
Expand Down
2 changes: 1 addition & 1 deletion physics/src/main/kotlin/cyberpunk/physics/PhysicsWorld.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class PhysicsWorld
/**
* The [World] instance of this [PhysicsWorld].
*/
val world: World = World(config.gravity, true)
val world = World(config.gravity, true)

/**
* The [PhysicsDebugger] that will render this [PhysicsWorld].
Expand Down
Loading

0 comments on commit e791d71

Please sign in to comment.