DEADSOFTWARE

Add RenderModule code generation
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / render / HudRenderer.kt
1 package ru.deadsoftware.cavedroid.game.render
3 import com.badlogic.gdx.graphics.g2d.SpriteBatch
4 import com.badlogic.gdx.graphics.glutils.ShapeRenderer
5 import com.badlogic.gdx.math.Rectangle
6 import ru.deadsoftware.cavedroid.game.GameScope
7 import ru.deadsoftware.cavedroid.game.mobs.MobsController
8 import ru.deadsoftware.cavedroid.game.mobs.player.Player
9 import ru.deadsoftware.cavedroid.game.mobs.player.Player.ControlMode
10 import ru.deadsoftware.cavedroid.game.ui.TooltipManager
11 import ru.deadsoftware.cavedroid.game.world.GameWorld
12 import ru.deadsoftware.cavedroid.misc.Assets
13 import ru.deadsoftware.cavedroid.misc.utils.drawString
14 import ru.deadsoftware.cavedroid.misc.utils.px
15 import javax.inject.Inject
17 @GameScope
18 @GameRenderer
19 class HudRenderer @Inject constructor(
20 private val gameWorld: GameWorld,
21 private val mobsController: MobsController,
22 private val tooltipManager: TooltipManager,
23 ) : IGameRenderer {
25 override val renderLayer = RENDER_LAYER
27 private val cursorTexture get() = requireNotNull(Assets.textureRegions[CURSOR_KEY])
28 private val hotbarTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_KEY])
29 private val hotbarSelectorTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_SELECTOR_KEY])
30 private val wholeHeartTexture get() = requireNotNull(Assets.textureRegions[WHOLE_HEART_KEY])
31 private val emptyHeartTexture get() = requireNotNull(Assets.textureRegions[EMPTY_HEART_KEY])
32 private val halfHeartTexture get() = requireNotNull(Assets.textureRegions[HALF_HEART_KEY])
34 private fun drawCursor(spriteBatch: SpriteBatch, viewport: Rectangle) {
35 val cursorX = mobsController.player.cursorX
36 val cursorY = mobsController.player.cursorY
38 if (gameWorld.hasForeAt(cursorX, cursorY) ||
39 gameWorld.hasBackAt(cursorX, cursorY) ||
40 mobsController.player.controlMode == ControlMode.CURSOR
41 ) {
42 spriteBatch.draw(cursorTexture, cursorX.px - viewport.x, cursorY.px - viewport.y)
43 }
44 }
46 private fun drawHealth(spriteBatch: SpriteBatch, x: Float, y: Float) {
47 val player = mobsController.player
49 if (player.gameMode == 1) {
50 return
51 }
53 val wholeHeart = wholeHeartTexture
54 val halfHeart = halfHeartTexture
55 val emptyHeart = emptyHeartTexture
57 val totalHearts = Player.MAX_HEALTH / 2
58 val wholeHearts = player.health / 2
60 for (i in 0..< totalHearts) {
61 if (i < wholeHearts) {
62 spriteBatch.draw(wholeHeart, x + i * wholeHeart.regionWidth, y)
63 } else if (i == wholeHearts && player.health % 2 == 1) {
64 spriteBatch.draw(halfHeart, x + i * wholeHeart.regionWidth, y)
65 } else {
66 spriteBatch.draw(emptyHeart, x + i * wholeHeart.regionWidth, y)
67 }
68 }
73 }
75 private fun drawHotbarItems(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, hotbarX: Float) {
76 mobsController.player.inventory.items.asSequence().take(HotbarConfig.hotbarCells)
77 .forEachIndexed { index, item ->
78 if (item.item.isNone()) {
79 return@forEachIndexed
80 }
82 item.draw(
83 spriteBatch = spriteBatch,
84 shapeRenderer = shapeRenderer,
85 x = hotbarX + HotbarConfig.horizontalMargin +
86 index * (HotbarConfig.itemSeparatorWidth + HotbarConfig.itemSlotSpace),
87 y = HotbarConfig.verticalMargin,
88 )
89 }
90 }
92 private fun drawHotbarSelector(spriteBatch: SpriteBatch, hotbarX: Float) {
93 spriteBatch.draw(
94 /* region = */ hotbarSelectorTexture,
95 /* x = */ hotbarX - HotbarSelectorConfig.horizontalPadding
96 + mobsController.player.inventory.activeSlot * (HotbarConfig.itemSeparatorWidth + HotbarConfig.itemSlotSpace),
97 /* y = */ -HotbarSelectorConfig.verticalPadding
98 )
99 }
101 private fun drawHotbar(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle) {
102 val hotbar = hotbarTexture
103 val hotbarX = viewport.width / 2 - hotbar.regionWidth / 2
105 spriteBatch.draw(hotbar, hotbarX, 0f)
106 drawHealth(spriteBatch, hotbarX, hotbarTexture.regionHeight.toFloat())
107 drawHotbarSelector(spriteBatch, hotbarX)
108 drawHotbarItems(spriteBatch, shapeRenderer, hotbarX)
110 val tooltip = tooltipManager.currentHotbarTooltip
111 if (tooltip.isNotBlank()) {
112 spriteBatch.drawString(
113 str = tooltip,
114 x = viewport.width / 2 - Assets.getStringWidth(tooltip) / 2,
115 y = hotbarTexture.regionHeight.toFloat()
120 override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) {
121 drawCursor(spriteBatch, viewport)
122 drawHotbar(spriteBatch, shapeRenderer, viewport)
125 companion object {
126 private const val RENDER_LAYER = 100500
128 private const val CURSOR_KEY = "cursor"
129 private const val HOTBAR_KEY = "hotbar"
130 private const val HOTBAR_SELECTOR_KEY = "hotbar_selector"
131 private const val WHOLE_HEART_KEY = "heart_whole"
132 private const val HALF_HEART_KEY = "heart_half"
133 private const val EMPTY_HEART_KEY = "heart_empty"
135 private data object HotbarConfig {
136 const val horizontalMargin = 3f
137 const val verticalMargin = 3f
138 const val itemSeparatorWidth = 4f
139 const val itemSlotSpace = 16f
140 const val hotbarCells = 9
143 private data object HotbarSelectorConfig {
144 const val horizontalPadding = 1f
145 const val verticalPadding = 1f