local Textbox = require("textbox") local HUD = {} HUD.__index = HUD HUD.slots = { { enabled = false, object = "key", name = "Key" }, { enabled = false, object = "dbljump", name = "Double Jump" }, { enabled = false }, { enabled = false }, } local SLOT_SIZE = 16 local SLOT_SPACING = 8 local function createMissingTexture() local size = SLOT_SIZE local half = size / 2 local imgData = love.image.newImageData(size, size) for y = 0, size - 1 do for x = 0, size - 1 do local inBlack = (x < half and y < half) or (x >= half and y >= half) if inBlack then imgData:setPixel(x, y, 0, 0, 0, 1) else imgData:setPixel(x, y, 1, 0, 1, 1) end end end local img = love.graphics.newImage(imgData) img:setFilter("nearest", "nearest") return img end function HUD:new() local self = setmetatable({}, HUD) self.missingTexture = createMissingTexture() self.textbox = Textbox:new() self.hoveredSlot = nil self.slotRects = {} self.screenW = 0 self.screenH = 0 self.drawScale = 1 self.player = nil for _, slot in ipairs(HUD.slots) do if slot.object == "key" then slot.image = love.graphics.newImage("assets/misc/key.png") slot.image:setFilter("nearest", "nearest") elseif slot.object == "dbljump" then slot.image = love.graphics.newImage("assets/misc/dbljump.png") slot.image:setFilter("nearest", "nearest") end end return self end function HUD:computeSlotRects(screenW, screenH, drawScale) local slotW = SLOT_SIZE * drawScale local slotH = SLOT_SIZE * drawScale local spacing = SLOT_SPACING * drawScale local totalW = 4 * slotW + 3 * spacing local startX = math.floor((screenW - totalW) / 2) local startY = math.floor(screenH / 2 - slotH / 2) local rects = {} for i = 1, 4 do rects[i] = { x = startX + (i - 1) * (slotW + spacing), y = startY, w = slotW, h = slotH, } end return rects end function HUD:update(dt, screenW, screenH, drawScale, player) self.screenW = screenW self.screenH = screenH self.drawScale = drawScale self.player = player self.slotRects = self:computeSlotRects(screenW, screenH, drawScale) if player and player.pickups then for _, slot in ipairs(HUD.slots) do if slot.object then slot.enabled = (player.pickups[slot.object] or 0) > 0 end end end local mx, my = love.mouse.getPosition() local prevHovered = self.hoveredSlot self.hoveredSlot = nil for i, rect in ipairs(self.slotRects) do if mx >= rect.x and mx < rect.x + rect.w and my >= rect.y and my < rect.y + rect.h then self.hoveredSlot = i break end end if self.hoveredSlot and self.hoveredSlot ~= prevHovered then local slot = HUD.slots[self.hoveredSlot] local text = "Planned feature that didn't make it into the game ;(" if slot.name then local count = 0 if player and player.pickups and slot.object then count = player.pickups[slot.object] or 0 end text = slot.name .. " x" .. count end local rect = self.slotRects[self.hoveredSlot] local centerX = screenW / 2 local topY = rect.y + rect.h + 8 * drawScale self.textbox:show(text, { centerX, topY, "center" }, "show", { fontSize = 16, centeredText = true, wrapToFit = true, maxChars = 40, }) self.textbox.y = topY + self.textbox.height / 2 elseif not self.hoveredSlot and prevHovered then self.textbox:hide() end self.textbox:update(dt) end function HUD:mousepressed(mx, my, button) if button ~= 1 then return end for i, rect in ipairs(self.slotRects) do if mx >= rect.x and mx < rect.x + rect.w and my >= rect.y and my < rect.y + rect.h then --HUD.slots[i].enabled = not HUD.slots[i].enabled break end end end function HUD:draw() local screenW = self.screenW local screenH = self.screenH local drawScale = self.drawScale love.graphics.setColor(0, 0, 0, 0.4) love.graphics.rectangle("fill", 0, 0, screenW, screenH) for i, rect in ipairs(self.slotRects) do local slot = HUD.slots[i] local img = slot.image or self.missingTexture if slot.enabled then love.graphics.setColor(1, 1, 1, 1) else love.graphics.setColor(1, 1, 1, 0.25) end love.graphics.draw(img, rect.x, rect.y, 0, drawScale, drawScale) if slot.enabled then love.graphics.setColor(0, 1, 0, 0.3) love.graphics.rectangle("fill", rect.x, rect.y, rect.w, rect.h) end if self.hoveredSlot == i then love.graphics.setColor(1, 1, 0, 1) love.graphics.setLineWidth(2) else love.graphics.setColor(1, 1, 1, 0.5) love.graphics.setLineWidth(1) end love.graphics.rectangle("line", rect.x, rect.y, rect.w, rect.h) end love.graphics.setLineWidth(1) love.graphics.setColor(1, 1, 1, 1) self.textbox:draw() end return HUD