diff --git a/core/src/main/kotlin/com/quillraven/github/quillyjumper/ai/AiEntity.kt b/core/src/main/kotlin/com/quillraven/github/quillyjumper/ai/AiEntity.kt index 0961e7e..35222d6 100644 --- a/core/src/main/kotlin/com/quillraven/github/quillyjumper/ai/AiEntity.kt +++ b/core/src/main/kotlin/com/quillraven/github/quillyjumper/ai/AiEntity.kt @@ -43,7 +43,7 @@ data class AiEntity( } fun notInRange(location: Vector2, tolerance: Float): Boolean = with(world) { - val (_, center) = entity[Graphic] + val center = entity[Graphic].center val diffX = location.x - center.x val diffY = location.y - center.y @@ -51,7 +51,7 @@ data class AiEntity( } fun inRange(location: Vector2, tolerance: Float): Boolean = with(world) { - val (_, center) = entity[Graphic] + val center = entity[Graphic].center val diffX = location.x - center.x val diffY = location.y - center.y @@ -63,8 +63,8 @@ data class AiEntity( } fun angleTo(target: Entity): Float = with(world) { - val (_, center) = entity[Graphic] - val (_, targetCenter) = target[Graphic] + val center = entity[Graphic].center + val targetCenter = target[Graphic].center return atan2(targetCenter.y - center.y, targetCenter.x - center.x) } diff --git a/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/EntityTag.kt b/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/EntityTag.kt index ef6f722..b6ee056 100644 --- a/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/EntityTag.kt +++ b/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/EntityTag.kt @@ -4,5 +4,5 @@ import com.github.quillraven.fleks.EntityTags import com.github.quillraven.fleks.entityTagOf enum class EntityTag : EntityTags by entityTagOf() { - PLAYER, CAMERA_FOCUS, BACKGROUND, FOREGROUND, COLLECTABLE + PLAYER, CAMERA_FOCUS, COLLECTABLE } diff --git a/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/Graphic.kt b/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/Graphic.kt index e54bfb4..44ec66c 100644 --- a/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/Graphic.kt +++ b/core/src/main/kotlin/com/quillraven/github/quillyjumper/component/Graphic.kt @@ -5,7 +5,7 @@ import com.github.quillraven.fleks.Component import com.github.quillraven.fleks.ComponentType import ktx.math.vec2 -data class Graphic(val sprite: Sprite) : Component, Comparable { +data class Graphic(val sprite: Sprite, val z: Int) : Component, Comparable { val center = vec2() get() { field.x = sprite.x + sprite.width * 0.5f @@ -16,6 +16,8 @@ data class Graphic(val sprite: Sprite) : Component, Comparable override fun type() = Graphic override fun compareTo(other: Graphic): Int = when { + z < other.z -> -1 + z > other.z -> 1 sprite.y < other.sprite.y -> -1 sprite.y > other.sprite.y -> 1 sprite.x < other.sprite.x -> -1 @@ -23,7 +25,5 @@ data class Graphic(val sprite: Sprite) : Component, Comparable else -> 0 } - operator fun component2() = center - companion object : ComponentType() } diff --git a/core/src/main/kotlin/com/quillraven/github/quillyjumper/system/RenderSystem.kt b/core/src/main/kotlin/com/quillraven/github/quillyjumper/system/RenderSystem.kt index f0703a9..1ae9bdf 100644 --- a/core/src/main/kotlin/com/quillraven/github/quillyjumper/system/RenderSystem.kt +++ b/core/src/main/kotlin/com/quillraven/github/quillyjumper/system/RenderSystem.kt @@ -7,16 +7,15 @@ import com.badlogic.gdx.maps.tiled.TiledMapTileLayer import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer import com.badlogic.gdx.scenes.scene2d.Stage import com.badlogic.gdx.utils.viewport.Viewport -import com.github.quillraven.fleks.Family -import com.github.quillraven.fleks.IntervalSystem +import com.github.quillraven.fleks.Entity +import com.github.quillraven.fleks.IteratingSystem import com.github.quillraven.fleks.World.Companion.family import com.github.quillraven.fleks.World.Companion.inject +import com.github.quillraven.fleks.collection.MutableEntityBag import com.github.quillraven.fleks.collection.compareEntityBy import com.quillraven.github.quillyjumper.Assets import com.quillraven.github.quillyjumper.Quillyjumper import com.quillraven.github.quillyjumper.ShaderAsset -import com.quillraven.github.quillyjumper.component.EntityTag.BACKGROUND -import com.quillraven.github.quillyjumper.component.EntityTag.FOREGROUND import com.quillraven.github.quillyjumper.component.Flash import com.quillraven.github.quillyjumper.component.Graphic import com.quillraven.github.quillyjumper.event.GameEvent @@ -34,35 +33,43 @@ class RenderSystem( private val stage: Stage = inject(), private val gameCamera: OrthographicCamera = inject(), assets: Assets = inject() -) : IntervalSystem(), GameEventListener { +) : IteratingSystem(family = family { all(Graphic) }, comparator = compareEntityBy(Graphic)), GameEventListener { private val mapRenderer = OrthogonalTiledMapRenderer(null, Quillyjumper.UNIT_SCALE, batch) private val bgdLayers = mutableListOf() private val fgdLayers = mutableListOf() - private val entityComparator = compareEntityBy(Graphic) - private val bgdEntities = family { all(Graphic, BACKGROUND) } - private val entities = family { all(Graphic).none(BACKGROUND, FOREGROUND) } - private val fgdEntities = family { all(Graphic, FOREGROUND) } + private val bgdEntities = MutableEntityBag() + private val entities = MutableEntityBag() + private val fgdEntities = MutableEntityBag() + private val tmpEntities = MutableEntityBag() private val flashShader = assets[ShaderAsset.FLASH] private val uLocFlashColor = flashShader.getUniformLocation("u_FlashColor") private val uLocFlashWeight = flashShader.getUniformLocation("u_FlashWeight") override fun onTick() { + // split render entities into three parts (background, normal and foreground entities) + onSort() + family.entities.partitionTo(bgdEntities, tmpEntities) { it[Graphic].z < 0 } + tmpEntities.partitionTo(fgdEntities, entities) { it[Graphic].z > 0 } + // game rendering gameViewport.apply() mapRenderer.use(gameCamera) { // background rendering - bgdEntities.renderEntities() + bgdEntities.forEach { onTickEntity(it) } + batch.resetShader() bgdLayers.forEach { mapRenderer.renderTileLayer(it) } // middle layer rendering - entities.renderEntities() + entities.forEach { onTickEntity(it) } + batch.resetShader() // foreground rendering fgdLayers.forEach { mapRenderer.renderTileLayer(it) } - fgdEntities.renderEntities() + fgdEntities.forEach { onTickEntity(it) } + batch.resetShader() } // ui rendering @@ -71,26 +78,21 @@ class RenderSystem( stage.draw() } - private fun Family.renderEntities() { - sort(entityComparator) - forEach { entity -> - val flashCmp = entity.getOrNull(Flash) - if (flashCmp != null && flashCmp.doFlash) { - if (batch.shader != flashShader) { - batch.shader = flashShader - } - flashShader.use { - flashShader.setUniformf(uLocFlashColor, flashCmp.color) - flashShader.setUniformf(uLocFlashWeight, flashCmp.weight) - } - } else { - batch.resetShader() + override fun onTickEntity(entity: Entity) { + val flashCmp = entity.getOrNull(Flash) + if (flashCmp != null && flashCmp.doFlash) { + if (batch.shader != flashShader) { + batch.shader = flashShader } - - entity[Graphic].sprite.draw(batch) + flashShader.use { + flashShader.setUniformf(uLocFlashColor, flashCmp.color) + flashShader.setUniformf(uLocFlashWeight, flashCmp.weight) + } + } else { + batch.resetShader() } - batch.resetShader() + entity[Graphic].sprite.draw(batch) } private fun Batch.resetShader() { diff --git a/core/src/main/kotlin/com/quillraven/github/quillyjumper/tiled/TiledService.kt b/core/src/main/kotlin/com/quillraven/github/quillyjumper/tiled/TiledService.kt index b389f80..228d612 100644 --- a/core/src/main/kotlin/com/quillraven/github/quillyjumper/tiled/TiledService.kt +++ b/core/src/main/kotlin/com/quillraven/github/quillyjumper/tiled/TiledService.kt @@ -174,11 +174,7 @@ class TiledService( // the flipX information of the sprite will always be false. // Since the AnimationSystem is updating the region of the sprite and is also // restoring the flip information, we should set the Sprite region already at this point. - it += Graphic(sprite(gameObject, AnimationType.IDLE.atlasKey, body.position)) - when { - zIndex < 0 -> it += EntityTag.BACKGROUND - zIndex > 0 -> it += EntityTag.FOREGROUND - } + it += Graphic(sprite(gameObject, AnimationType.IDLE.atlasKey, body.position), zIndex) configureEntityTags(it, tile) // check for player tag and remember player start location if (it has EntityTag.PLAYER) { diff --git a/core/src/test/kotlin/RenderTestScreen.kt b/core/src/test/kotlin/RenderTestScreen.kt index 8516d89..87d14d6 100644 --- a/core/src/test/kotlin/RenderTestScreen.kt +++ b/core/src/test/kotlin/RenderTestScreen.kt @@ -62,7 +62,7 @@ class RenderTestScreen : KtxScreen { setPosition(3f, 1f) setSize(1f, 1f) } - it += Graphic(entitySprite) + it += Graphic(entitySprite, 0) } world.entity { val entitySprite = Sprite(textureRegion("frog/idle")).apply { @@ -70,7 +70,7 @@ class RenderTestScreen : KtxScreen { setSize(1f, 1f) setFlip(true, false) } - it += Graphic(entitySprite) + it += Graphic(entitySprite, 0) } // animation entities @@ -80,7 +80,7 @@ class RenderTestScreen : KtxScreen { setSize(1f, 1f) } it += Tiled(GameObject.FROG, 0) - it += Graphic(entitySprite) + it += Graphic(entitySprite, 0) it += Animation(animationService.gdxAnimation(GameObject.FROG, AnimationType.IDLE), type = NORMAL_ANIMATION) } world.entity { @@ -90,7 +90,7 @@ class RenderTestScreen : KtxScreen { setFlip(true, false) } it += Tiled(GameObject.FROG, 0) - it += Graphic(entitySprite) + it += Graphic(entitySprite, 0) it += Animation(animationService.gdxAnimation(GameObject.FROG, AnimationType.IDLE), type = NORMAL_ANIMATION) } }