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
|
end
|
||||||
|
|
||||||
function editorMouseHandler(x, y, button)
|
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
|
-- map from real window coords into the sidebar's fixed virtual space
|
||||||
-- (same transform used to scale the sidebar canvas up in love.draw)
|
-- (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
|
y = y * sb.h / sideBarBox.h
|
||||||
|
|
||||||
if editorView == "room" then
|
if editorView == "room" then
|
||||||
|
|
|
||||||
14
main.lua
14
main.lua
|
|
@ -15,6 +15,7 @@ require "room"
|
||||||
require "world"
|
require "world"
|
||||||
require "world_seed"
|
require "world_seed"
|
||||||
require "shaders"
|
require "shaders"
|
||||||
|
GameUI = require "game_ui"
|
||||||
require "level_editor/editor"
|
require "level_editor/editor"
|
||||||
|
|
||||||
-- Ink dialogue: ship the pre-parsed book (LÖVE has no lpeg to parse .ink at
|
-- Ink dialogue: ship the pre-parsed book (LÖVE has no lpeg to parse .ink at
|
||||||
|
|
@ -110,6 +111,7 @@ function love.draw()
|
||||||
else
|
else
|
||||||
currentRoom:draw()
|
currentRoom:draw()
|
||||||
end
|
end
|
||||||
|
GameUI.drawColorVenn(currentRoom)
|
||||||
|
|
||||||
love.graphics.setCanvas(finalCanvas)
|
love.graphics.setCanvas(finalCanvas)
|
||||||
love.graphics.clear()
|
love.graphics.clear()
|
||||||
|
|
@ -158,6 +160,10 @@ function love.draw()
|
||||||
love.graphics.setBlendMode("alpha")
|
love.graphics.setBlendMode("alpha")
|
||||||
love.graphics.setColor(1, 1, 1, 1)
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
love.graphics.draw(finalCanvas, 0, 0)
|
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
|
if DEBUG then love.graphics.draw(sideBarCanvas, sideBarBox.x, sideBarBox.y) end
|
||||||
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
|
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
|
||||||
PerfProfiler:draw()
|
PerfProfiler:draw()
|
||||||
|
|
@ -265,7 +271,7 @@ end
|
||||||
function love.wheelmoved(dx, dy)
|
function love.wheelmoved(dx, dy)
|
||||||
if not DEBUG then return end
|
if not DEBUG then return end
|
||||||
-- Scroll the editor's asset/folder list when the cursor is over the sidebar.
|
-- 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)
|
editorScrollRoomList(dy)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -304,7 +310,10 @@ function _computeDimensions()
|
||||||
height = width
|
height = width
|
||||||
end
|
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
|
-- 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
|
-- fill the real panel, so every element keeps the same size relative to the
|
||||||
|
|
@ -333,6 +342,7 @@ function _initCanvases()
|
||||||
porousRoomCanvas = love.graphics.newCanvas()
|
porousRoomCanvas = love.graphics.newCanvas()
|
||||||
sideBarCanvas = love.graphics.newCanvas(math.max(1, sideBarBox.w), math.max(1, sideBarBox.h))
|
sideBarCanvas = love.graphics.newCanvas(math.max(1, sideBarBox.w), math.max(1, sideBarBox.h))
|
||||||
sideBarCanvas:setFilter("nearest", "nearest") -- never average when sampled
|
sideBarCanvas:setFilter("nearest", "nearest") -- never average when sampled
|
||||||
|
GameUI.init()
|
||||||
end
|
end
|
||||||
|
|
||||||
function _initGridVars()
|
function _initGridVars()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue