DEADSOFTWARE

Update version script
[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.annotations.multibinding.BindRenderer
14 import ru.deadsoftware.cavedroid.misc.utils.drawString
15 import ru.deadsoftware.cavedroid.misc.utils.px
16 import javax.inject.Inject
18 @GameScope
19 @BindRenderer
20 class HudRenderer @Inject constructor(
21 private val gameWorld: GameWorld,
22 private val mobsController: MobsController,
23 private val tooltipManager: TooltipManager,
24 ) : IGameRenderer {
26 override val renderLayer = RENDER_LAYER
28 private val cursorTexture get() = requireNotNull(Assets.textureRegions[CURSOR_KEY])
29 private val hotbarTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_KEY])
30 private val hotbarSelectorTexture get() = requireNotNull(Assets.textureRegions[HOTBAR_SELECTOR_KEY])
31 private val wholeHeartTexture get() = requireNotNull(Assets.textureRegions[WHOLE_HEART_KEY])
32 private val emptyHeartTexture get() = requireNotNull(Assets.textureRegions[EMPTY_HEART_KEY])
33 private val halfHeartTexture get() = requireNotNull(Assets.textureRegions[HALF_HEART_KEY])
35 private fun drawCursor(spriteBatch: SpriteBatch, viewport: Rectangle) {
36 val cursorX = mobsController.player.cursorX
37 val cursorY = mobsController.player.cursorY
39 if (gameWorld.hasForeAt(cursorX, cursorY) ||
40 gameWorld.hasBackAt(cursorX, cursorY) ||
41 mobsController.player.controlMode == ControlMode.CURSOR
42 ) {
43 spriteBatch.draw(cursorTexture, cursorX.px - viewport.x, cursorY.px - viewport.y)
44 }
45 }
47 private fun drawHealth(spriteBatch: SpriteBatch, x: Float, y: Float) {
48 val player = mobsController.player
50 if (player.gameMode == 1) {
51 return
52 }
54 val wholeHeart = wholeHeartTexture
55 val halfHeart = halfHeartTexture
56 val emptyHeart = emptyHeartTexture
58 val totalHearts = Player.MAX_HEALTH / 2
59 val wholeHearts = player.health / 2
61 for (i in 0..< totalHearts) {
62 if (i < wholeHearts) {
63 spriteBatch.draw(wholeHeart, x + i * wholeHeart.regionWidth, y)
64 } else if (i == wholeHearts && player.health % 2 == 1) {
65 spriteBatch.draw(halfHeart, x + i * wholeHeart.regionWidth, y)
66 } else {
67 spriteBatch.draw(emptyHeart, x + i * wholeHeart.regionWidth, y)
68 }
69 }
74 }
76 private fun drawHotbarItems(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, hotbarX: Float) {
77 mobsController.player.inventory.items.asSequence().take(HotbarConfig.hotbarCells)
78 .forEachIndexed { index, item ->
79 if (item.item.isNone()) {
80 return@forEachIndexed
81 }
83 item.draw(
84 spriteBatch = spriteBatch,
85 shapeRenderer = shapeRenderer,
86 x = hotbarX + HotbarConfig.horizontalMargin +
87 index * (HotbarConfig.itemSeparatorWidth + HotbarConfig.itemSlotSpace),
88 y = HotbarConfig.verticalMargin,
89 )
90 }
91 }
93 private fun drawHotbarSelector(spriteBatch: SpriteBatch, hotbarX: Float) {
94 spriteBatch.draw(
95 /* region = */ hotbarSelectorTexture,
96 /* x = */ hotbarX - HotbarSelectorConfig.horizontalPadding
97 + mobsController.player.inventory.activeSlot * (HotbarConfig.itemSeparatorWidth + HotbarConfig.itemSlotSpace),
98 /* y = */ -HotbarSelectorConfig.verticalPadding
99 )
102 private fun drawHotbar(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle) {
103 val hotbar = hotbarTexture
104 val hotbarX = viewport.width / 2 - hotbar.regionWidth / 2
106 spriteBatch.draw(hotbar, hotbarX, 0f)
107 drawHealth(spriteBatch, hotbarX, hotbarTexture.regionHeight.toFloat())
108 drawHotbarSelector(spriteBatch, hotbarX)
109 drawHotbarItems(spriteBatch, shapeRenderer, hotbarX)
111 val tooltip = tooltipManager.currentHotbarTooltip
112 if (tooltip.isNotBlank()) {
113 spriteBatch.drawString(
114 str = tooltip,
115 x = viewport.width / 2 - Assets.getStringWidth(tooltip) / 2,
116 y = hotbarTexture.regionHeight.toFloat()
121 override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) {
122 drawCursor(spriteBatch, viewport)
123 drawHotbar(spriteBatch, shapeRenderer, viewport)
126 companion object {
127 private const val RENDER_LAYER = 100500
129 private const val CURSOR_KEY = "cursor"
130 private const val HOTBAR_KEY = "hotbar"
131 private const val HOTBAR_SELECTOR_KEY = "hotbar_selector"
132 private const val WHOLE_HEART_KEY = "heart_whole"
133 private const val HALF_HEART_KEY = "heart_half"
134 private const val EMPTY_HEART_KEY = "heart_empty"
136 private data object HotbarConfig {
137 const val horizontalMargin = 3f
138 const val verticalMargin = 3f
139 const val itemSeparatorWidth = 4f
140 const val itemSlotSpace = 16f
141 const val hotbarCells = 9
144 private data object HotbarSelectorConfig {
145 const val horizontalPadding = 1f
146 const val verticalPadding = 1f