Add player color Venn HUD
This commit is contained in:
parent
9b5b9ce182
commit
6f4b2fe696
3 changed files with 102 additions and 4 deletions
88
game_ui.lua
Normal file
88
game_ui.lua
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
-- Player-facing HUD drawn into gameCanvas. Keeping it here (rather than in
|
||||
-- the editor sidebar) means its RGB circles use the same screen blend as the
|
||||
-- room, so their overlaps are the real additive colour combinations.
|
||||
local GameUI = {}
|
||||
|
||||
local channelColor = {
|
||||
red = {1, 0, 0},
|
||||
green = {0, 1, 0},
|
||||
blue = {0, 0, 1},
|
||||
}
|
||||
|
||||
local vennSize = 32
|
||||
local vennLayout = {
|
||||
red = {x = 12, y = 10},
|
||||
green = {x = 20, y = 10},
|
||||
blue = {x = 16, y = 18},
|
||||
}
|
||||
|
||||
local function drawDottedCircle(x, y, radius, color, dotRadius)
|
||||
local dots = math.max(14, math.floor((2 * math.pi * radius) / (dotRadius * 4)))
|
||||
love.graphics.setColor(color[1], color[2], color[3], 1)
|
||||
for index = 0, dots - 1 do
|
||||
local angle = index / dots * math.pi * 2
|
||||
love.graphics.circle("fill", x + math.cos(angle) * radius, y + math.sin(angle) * radius, dotRadius)
|
||||
end
|
||||
end
|
||||
|
||||
function GameUI.init()
|
||||
uiVennCanvas = love.graphics.newCanvas(vennSize, vennSize)
|
||||
uiVennCanvas:setFilter("nearest", "nearest")
|
||||
end
|
||||
|
||||
function GameUI.drawBacking()
|
||||
if not gameUiBox then return end
|
||||
love.graphics.setBlendMode("alpha")
|
||||
love.graphics.setColor(0, 0, 0, 1)
|
||||
love.graphics.rectangle("fill", gameUiBox.x, gameUiBox.y, gameUiBox.w, gameUiBox.h)
|
||||
end
|
||||
|
||||
function GameUI.drawVennOverlay()
|
||||
if not gameUiBox or not uiVennCanvas then return end
|
||||
local cellSize = width / gridWidth
|
||||
local sidebarWidth = cellSize * 2
|
||||
if gameUiBox.w < sidebarWidth then return end
|
||||
|
||||
love.graphics.setBlendMode("screen")
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
local scale = cellSize / 22
|
||||
local vennWidth = vennSize * scale
|
||||
local left = gameUiBox.x + (gameUiBox.w - vennWidth) / 2
|
||||
love.graphics.draw(uiVennCanvas, left, cellSize * 1.1, 0, scale, scale)
|
||||
end
|
||||
|
||||
function GameUI.drawColorVenn(room)
|
||||
if not room or not gameUiBox then return end
|
||||
GameUI.drawBacking()
|
||||
|
||||
local cellSize = width / gridWidth
|
||||
local sidebarWidth = cellSize * 2
|
||||
if gameUiBox.w < sidebarWidth or not uiVennCanvas then return end
|
||||
|
||||
love.graphics.setCanvas(uiVennCanvas)
|
||||
love.graphics.clear(0, 0, 0, 0)
|
||||
love.graphics.setBlendMode("screen")
|
||||
local radius = 9
|
||||
local dotRadius = 1
|
||||
local active = {}
|
||||
for _, color in ipairs(room:getActiveColors()) do active[color] = true end
|
||||
|
||||
for _, color in ipairs({"red", "green", "blue"}) do
|
||||
if room.player[color] then
|
||||
local layout = vennLayout[color]
|
||||
local x, y = layout.x, layout.y
|
||||
local rgb = channelColor[color]
|
||||
if active[color] then
|
||||
love.graphics.setColor(rgb[1], rgb[2], rgb[3], 1)
|
||||
love.graphics.circle("fill", x, y, radius)
|
||||
else
|
||||
drawDottedCircle(x, y, radius, rgb, dotRadius)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
love.graphics.setCanvas(gameCanvas)
|
||||
GameUI.drawVennOverlay()
|
||||
end
|
||||
|
||||
return GameUI
|
||||
|
|
@ -1138,10 +1138,10 @@ local function openWorldRoom(cellX, cellY)
|
|||
end
|
||||
|
||||
function editorMouseHandler(x, y, button)
|
||||
if x > width then
|
||||
if x >= sideBarBox.x and x < sideBarBox.x + sideBarBox.w then
|
||||
-- map from real window coords into the sidebar's fixed virtual space
|
||||
-- (same transform used to scale the sidebar canvas up in love.draw)
|
||||
x = (x - width) * sb.w / sideBarBox.w
|
||||
x = (x - sideBarBox.x) * sb.w / sideBarBox.w
|
||||
y = y * sb.h / sideBarBox.h
|
||||
|
||||
if editorView == "room" then
|
||||
|
|
|
|||
14
main.lua
14
main.lua
|
|
@ -15,6 +15,7 @@ require "room"
|
|||
require "world"
|
||||
require "world_seed"
|
||||
require "shaders"
|
||||
GameUI = require "game_ui"
|
||||
require "level_editor/editor"
|
||||
|
||||
-- Ink dialogue: ship the pre-parsed book (LÖVE has no lpeg to parse .ink at
|
||||
|
|
@ -110,6 +111,7 @@ function love.draw()
|
|||
else
|
||||
currentRoom:draw()
|
||||
end
|
||||
GameUI.drawColorVenn(currentRoom)
|
||||
|
||||
love.graphics.setCanvas(finalCanvas)
|
||||
love.graphics.clear()
|
||||
|
|
@ -158,6 +160,10 @@ function love.draw()
|
|||
love.graphics.setBlendMode("alpha")
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
love.graphics.draw(finalCanvas, 0, 0)
|
||||
GameUI.drawBacking()
|
||||
GameUI.drawVennOverlay()
|
||||
love.graphics.setBlendMode("alpha")
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
if DEBUG then love.graphics.draw(sideBarCanvas, sideBarBox.x, sideBarBox.y) end
|
||||
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
|
||||
PerfProfiler:draw()
|
||||
|
|
@ -265,7 +271,7 @@ end
|
|||
function love.wheelmoved(dx, dy)
|
||||
if not DEBUG then return end
|
||||
-- Scroll the editor's asset/folder list when the cursor is over the sidebar.
|
||||
if editorView == "room" and love.mouse.getX() > width then
|
||||
if editorView == "room" and love.mouse.getX() >= sideBarBox.x then
|
||||
editorScrollRoomList(dy)
|
||||
end
|
||||
end
|
||||
|
|
@ -304,7 +310,10 @@ function _computeDimensions()
|
|||
height = width
|
||||
end
|
||||
|
||||
sideBarBox = {x = width, y = 0, w = love.graphics.getWidth() - width, h = height}
|
||||
local availableWidth = love.graphics.getWidth() - width
|
||||
local hudWidth = math.min(availableWidth, width / (gridWidth or 11) * 2)
|
||||
gameUiBox = {x = width, y = 0, w = hudWidth, h = height}
|
||||
sideBarBox = {x = gameUiBox.x + gameUiBox.w, y = 0, w = availableWidth - gameUiBox.w, h = height}
|
||||
|
||||
-- The editor sidebar is authored in a fixed virtual space and scaled up to
|
||||
-- fill the real panel, so every element keeps the same size relative to the
|
||||
|
|
@ -333,6 +342,7 @@ function _initCanvases()
|
|||
porousRoomCanvas = love.graphics.newCanvas()
|
||||
sideBarCanvas = love.graphics.newCanvas(math.max(1, sideBarBox.w), math.max(1, sideBarBox.h))
|
||||
sideBarCanvas:setFilter("nearest", "nearest") -- never average when sampled
|
||||
GameUI.init()
|
||||
end
|
||||
|
||||
function _initGridVars()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue