DEADSOFTWARE

65d9e0ade81636d8855f1c509b51ae13a889f08f
[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.SpriteBatch
4 import com.badlogic.gdx.graphics.g2d.TextureRegion
5 import com.badlogic.gdx.graphics.glutils.ShapeRenderer
6 import com.badlogic.gdx.math.MathUtils
7 import com.badlogic.gdx.math.Rectangle
8 import ru.deadsoftware.cavedroid.game.GameInput
9 import ru.deadsoftware.cavedroid.game.model.block.Block
10 import ru.deadsoftware.cavedroid.game.world.GameWorld
11 import ru.deadsoftware.cavedroid.misc.Assets
12 import ru.deadsoftware.cavedroid.misc.utils.px
14 abstract class BlocksRenderer(
15 protected val gameWorld: GameWorld,
16 protected val gameInput: GameInput,
17 ) : IGameRenderer {
19 protected abstract val background: Boolean
21 private val Block.canSeeThrough
22 get() = isNone() || params.isTransparent
24 private fun blockDamageTexture(index: Int): TextureRegion? {
25 if (index !in 0..MAX_BLOCK_DAMAGE_INDEX) {
26 return null
27 }
28 val textureKey = "$BLOCK_DAMAGE_TEXTURE_PREFIX$index"
29 return Assets.textureRegions[textureKey]
30 }
32 protected fun drawBlockDamage(spriteBatch: SpriteBatch, viewport: Rectangle) {
33 val blockDamage = gameInput.blockDamage
34 if (blockDamage <= 0) {
35 return
36 }
38 val block = if (background) {
39 gameWorld.getBackMap(gameInput.curX, gameInput.curY)
40 } else {
41 gameWorld.getForeMap(gameInput.curX, gameInput.curY)
42 }
44 val index = (MAX_BLOCK_DAMAGE_INDEX.toFloat() * (blockDamage.toFloat() / block.params.hitPoints.toFloat()))
45 .let(MathUtils::floor)
46 val texture = blockDamageTexture(index) ?: return
48 if (gameWorld.hasForeAt(gameInput.curX, gameInput.curY) != background) {
49 spriteBatch.draw(texture, gameInput.curX.px - viewport.x, gameInput.curY.px - viewport.y)
50 }
51 }
53 protected fun shadeBackMap(
54 shapeRenderer: ShapeRenderer,
55 viewport: Rectangle,
56 x: Int,
57 y: Int
58 ) {
59 val foregroundBlock = gameWorld.getForeMap(x, y)
60 val backgroundBlock = gameWorld.getBackMap(x, y)
62 if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) {
63 val drawX = x.px - viewport.x
64 val drawY = y.px - viewport.y
65 val marginLeft = backgroundBlock.params.spriteMargins.left
66 val marginTop = backgroundBlock.params.spriteMargins.top
68 shapeRenderer.rect(
69 /* x = */ drawX + marginLeft,
70 /* y = */ drawY + marginTop,
71 /* width = */ backgroundBlock.width,
72 /* height = */ backgroundBlock.height
73 )
74 }
75 }
77 protected fun drawBackMap(spriteBatch: SpriteBatch, viewport: Rectangle, x: Int, y: Int) {
78 val foregroundBlock = gameWorld.getForeMap(x, y)
79 val backgroundBlock = gameWorld.getBackMap(x, y)
81 if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) {
82 val drawX = x.px - viewport.x
83 val drawY = y.px - viewport.y
84 backgroundBlock.draw(spriteBatch, drawX, drawY)
85 }
86 }
88 protected fun drawForeMap(spriteBatch: SpriteBatch, viewport: Rectangle, x: Int, y: Int) {
89 val foregroundBlock = gameWorld.getForeMap(x, y)
91 if (!foregroundBlock.isNone() && foregroundBlock.params.isBackground == background) {
92 val drawX = x.px - viewport.x
93 val drawY = y.px - viewport.y
94 foregroundBlock.draw(spriteBatch, drawX, drawY)
95 }
96 }
98 companion object {
99 private const val BLOCK_DAMAGE_TEXTURE_PREFIX = "break_"
100 private const val MAX_BLOCK_DAMAGE_INDEX = 10