DEADSOFTWARE

Add tooltips
[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 class HudRenderer @Inject constructor(
19 private val gameWorld: GameWorld,
20 private val mobsController: MobsController,
21 private val tooltipManager: TooltipManager,
22 ) : IGameRenderer {
24 override val renderLayer = RENDER_LAYER
26 private val cursorTexture get() = requireNotNull(Assets.textureRegions[CURSOR_KEY])
27 private val hotbarTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_KEY])
28 private val hotbarSelectorTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_SELECTOR_KEY])
29 private val wholeHeartTexture get() = requireNotNull(Assets.textureRegions[WHOLE_HEART_KEY])
30 private val emptyHeartTexture get() = requireNotNull(Assets.textureRegions[EMPTY_HEART_KEY])
31 private val halfHeartTexture get() = requireNotNull(Assets.textureRegions[HALF_HEART_KEY])
33 private fun drawCursor(spriteBatch: SpriteBatch, viewport: Rectangle) {
34 val cursorX = mobsController.player.cursorX
35 val cursorY = mobsController.player.cursorY
37 if (gameWorld.hasForeAt(cursorX, cursorY) ||
38 gameWorld.hasBackAt(cursorX, cursorY) ||
39 mobsController.player.controlMode == ControlMode.CURSOR
40 ) {
41 spriteBatch.draw(cursorTexture, cursorX.px - viewport.x, cursorY.px - viewport.y)
42 }
43 }
45 private fun drawHealth(spriteBatch: SpriteBatch, x: Float, y: Float) {
46 val player = mobsController.player
48 if (player.gameMode == 1) {
49 return
50 }
52 val wholeHeart = wholeHeartTexture
53 val halfHeart = halfHeartTexture
54 val emptyHeart = emptyHeartTexture
56 val totalHearts = Player.MAX_HEALTH / 2
57 val wholeHearts = player.health / 2
59 for (i in 0..< totalHearts) {
60 if (i < wholeHearts) {
61 spriteBatch.draw(wholeHeart, x + i * wholeHeart.regionWidth, y)
62 } else if (i == wholeHearts && player.health % 2 == 1) {
63 spriteBatch.draw(halfHeart, x + i * wholeHeart.regionWidth, y)
64 } else {
65 spriteBatch.draw(emptyHeart, x + i * wholeHeart.regionWidth, y)
66 }
67 }
72 }
74 private fun drawHotbarItems(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, hotbarX: Float) {
75 mobsController.player.inventory.items.asSequence().take(HotbarConfig.hotbarCells)
76 .forEachIndexed { index, item ->
77 if (item.item.isNone()) {
78 return@forEachIndexed
79 }
81 item.draw(
82 spriteBatch = spriteBatch,
83 shapeRenderer = shapeRenderer,
84 x = hotbarX + HotbarConfig.horizontalMargin +
85 index * (HotbarConfig.itemSeparatorWidth + HotbarConfig.itemSlotSpace),
86 y = HotbarConfig.verticalMargin,
87 )
88 }
89 }
91 private fun drawHotbarSelector(spriteBatch: SpriteBatch, hotbarX: Float) {
92 spriteBatch.draw(
93 /* region = */ hotbarSelectorTexture,
94 /* x = */ hotbarX - HotbarSelectorConfig.horizontalPadding
95 + mobsController.player.inventory.activeSlot * (HotbarConfig.itemSeparatorWidth + HotbarConfig.itemSlotSpace),
96 /* y = */ -HotbarSelectorConfig.verticalPadding
97 )
98 }
100 private fun drawHotbar(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle) {
101 val hotbar = hotbarTexture
102 val hotbarX = viewport.width / 2 - hotbar.regionWidth / 2
104 spriteBatch.draw(hotbar, hotbarX, 0f)
105 drawHealth(spriteBatch, hotbarX, hotbarTexture.regionHeight.toFloat())
106 drawHotbarSelector(spriteBatch, hotbarX)
107 drawHotbarItems(spriteBatch, shapeRenderer, hotbarX)
109 val tooltip = tooltipManager.currentHotbarTooltip
110 if (tooltip.isNotBlank()) {
111 spriteBatch.drawString(
112 str = tooltip,
113 x = viewport.width / 2 - Assets.getStringWidth(tooltip) / 2,
114 y = hotbarTexture.regionHeight.toFloat()
119 override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) {
120 drawCursor(spriteBatch, viewport)
121 drawHotbar(spriteBatch, shapeRenderer, viewport)
124 companion object {
125 private const val RENDER_LAYER = 100500
127 private const val CURSOR_KEY = "cursor"
128 private const val HOTBAR_KEY = "hotbar"
129 private const val HOTBAR_SELECTOR_KEY = "hotbar_selector"
130 private const val WHOLE_HEART_KEY = "heart_whole"
131 private const val HALF_HEART_KEY = "heart_half"
132 private const val EMPTY_HEART_KEY = "heart_empty"
134 private data object HotbarConfig {
135 const val horizontalMargin = 3f
136 const val verticalMargin = 3f
137 const val itemSeparatorWidth = 4f
138 const val itemSlotSpace = 16f
139 const val hotbarCells = 9
142 private data object HotbarSelectorConfig {
143 const val horizontalPadding = 1f
144 const val verticalPadding = 1f