DEADSOFTWARE

Add top slabs
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / render / BlocksRenderer.kt
1 package ru.deadsoftware.cavedroid.game.render
3 import com.badlogic.gdx.graphics.g2d.Sprite
4 import com.badlogic.gdx.graphics.g2d.SpriteBatch
5 import com.badlogic.gdx.graphics.g2d.TextureRegion
6 import com.badlogic.gdx.graphics.glutils.ShapeRenderer
7 import com.badlogic.gdx.math.MathUtils
8 import com.badlogic.gdx.math.Rectangle
9 import ru.deadsoftware.cavedroid.game.mobs.MobsController
10 import ru.deadsoftware.cavedroid.game.model.block.Block
11 import ru.deadsoftware.cavedroid.game.world.GameWorld
12 import ru.deadsoftware.cavedroid.misc.Assets
13 import ru.deadsoftware.cavedroid.misc.utils.px
15 abstract class BlocksRenderer(
16 protected val gameWorld: GameWorld,
17 protected val mobsController: MobsController,
18 ) : IGameRenderer {
20 protected abstract val background: Boolean
22 private val Block.canSeeThrough
23 get() = isNone() || params.isTransparent
25 private fun blockDamageSprite(index: Int): Sprite? {
26 if (index !in 0..MAX_BLOCK_DAMAGE_INDEX) {
27 return null
28 }
29 return Assets.blockDamageSprites[index]
30 }
32 protected fun drawBlockDamage(spriteBatch: SpriteBatch, viewport: Rectangle) {
33 val player = mobsController.player
34 val blockDamage = player.blockDamage.takeIf { it > 0f } ?: return
35 val cursorX = player.cursorX
36 val cursorY = player.cursorY
38 val block = if (background) {
39 gameWorld.getBackMap(cursorX, cursorY)
40 } else {
41 gameWorld.getForeMap(cursorX, cursorY)
42 }
44 val index = (MAX_BLOCK_DAMAGE_INDEX.toFloat() * (blockDamage.toFloat() / block.params.hitPoints.toFloat()))
45 .let(MathUtils::floor)
46 val sprite = blockDamageSprite(index) ?: return
48 if (gameWorld.hasForeAt(cursorX, cursorY) != background) {
49 sprite.setBounds(
50 /* x = */ cursorX.px - viewport.x + block.params.spriteMargins.left,
51 /* y = */ cursorY.px - viewport.y + block.params.spriteMargins.top,
52 /* width = */ block.spriteWidth,
53 /* height = */ block.spriteHeight
54 )
55 sprite.draw(spriteBatch)
56 }
57 }
59 protected fun shadeBackMap(
60 shapeRenderer: ShapeRenderer,
61 viewport: Rectangle,
62 x: Int,
63 y: Int
64 ) {
65 val foregroundBlock = gameWorld.getForeMap(x, y)
66 val backgroundBlock = gameWorld.getBackMap(x, y)
68 if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) {
69 val drawX = x.px - viewport.x
70 val drawY = y.px - viewport.y
71 val marginLeft = backgroundBlock.params.spriteMargins.left
72 val marginTop = backgroundBlock.params.spriteMargins.top
74 shapeRenderer.rect(
75 /* x = */ drawX + marginLeft,
76 /* y = */ drawY + marginTop,
77 /* width = */ backgroundBlock.width,
78 /* height = */ backgroundBlock.height
79 )
80 }
81 }
83 protected fun drawBackMap(spriteBatch: SpriteBatch, viewport: Rectangle, x: Int, y: Int) {
84 val foregroundBlock = gameWorld.getForeMap(x, y)
85 val backgroundBlock = gameWorld.getBackMap(x, y)
87 if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) {
88 val drawX = x.px - viewport.x
89 val drawY = y.px - viewport.y
90 backgroundBlock.draw(spriteBatch, drawX, drawY)
91 }
92 }
94 protected fun drawForeMap(spriteBatch: SpriteBatch, viewport: Rectangle, x: Int, y: Int) {
95 val foregroundBlock = gameWorld.getForeMap(x, y)
97 if (!foregroundBlock.isNone() && foregroundBlock.params.isBackground == background) {
98 val drawX = x.px - viewport.x
99 val drawY = y.px - viewport.y
100 foregroundBlock.draw(spriteBatch, drawX, drawY)
104 companion object {
105 private const val MAX_BLOCK_DAMAGE_INDEX = 10