Skip to content

Commit

Permalink
Add coordinate conversion helper for GUI picking, & demo script (#14)
Browse files Browse the repository at this point in the history
- Credit to subsoap / Pkeod for commissioning this feature.
  • Loading branch information
rgrams committed Aug 20, 2023
1 parent b693732 commit 05dcd0f
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 2 deletions.
32 changes: 32 additions & 0 deletions game/lowrezjam/hover_hud_heart.gui_script
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

-- A sample script to demonstrate GUI node hovering with the mouse.

local coords = require "lowrezjam.render.coords"

function init(self)
msg.post(".", "acquire_input_focus")
self.hearts = {}
for i=1,3 do
self.hearts[i] = gui.get_node("life"..i)
end
end

local function update_hover(self, x, y)
local hit_i, hit_heart
for i,heart in ipairs(self.hearts) do
if gui.pick_node(heart, x, y) then
gui.set_alpha(heart, 0.5)
hit_i, hit_heart = i, heart
else
gui.set_alpha(heart, 1)
end
end
return hit_i, hit_heart
end

function on_input(self, action_id, action)
if not action_id then
local px, py = coords.action_to_gui_pick(action.x, action.y)
update_hover(self, px, py)
end
end
2 changes: 1 addition & 1 deletion game/lowrezjam/hud.gui
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
script: ""
script: "/game/lowrezjam/hover_hud_heart.gui_script"
fonts {
name: "pixelfont"
font: "/lowrezjam/fonts/pixelfont.font"
Expand Down
57 changes: 57 additions & 0 deletions lowrezjam/render/coords.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

-- A module for converting mouse coordinates to GUI coordinates for checking collision with GUI nodes.

local M = {}

local proj_w = sys.get_config_int("display.width", 960)
local proj_h = sys.get_config_int("display.height", 640)

M.window_width, M.window_height = proj_w, proj_h
M.game_width = 64
M.game_height = 64
M.scale_snap = true

local function get_zoom()
local zoom = math.min(M.window_width / M.game_width, M.window_height / M.game_height)
if M.scale_snap then
zoom = math.max(1, math.floor(zoom))
end
return zoom
end

local function get_offset(zoom)
local w, h = M.game_width * zoom, M.game_height * zoom
return (M.window_width - w)/2, (M.window_height - h)/2
end

function M.action_to_screen(ax, ay)
local sx = (ax / proj_w) * M.window_width
local sy = (ay / proj_h) * M.window_height
return sx, sy
end
local action_to_screen = M.action_to_screen

function M.screen_to_action(sx, sy)
local ax = sx * proj_w / M.window_width
local ay = sy * proj_h / M.window_height
return ax, ay
end
local screen_to_action = M.screen_to_action

function M.action_to_gui_pick(ax, ay)
local sx, sy = action_to_screen(ax, ay) -- It's way less confusing to work in real screen coords.

local action_width, action_height = screen_to_action(M.game_width, M.game_height) -- Bottom left of gui is always at 0, 0.
local scalex, scaley = action_width/M.game_width, action_height/M.game_height

local zoom = get_zoom()
local ox, oy = get_offset(zoom)

local x = (sx - ox)/zoom -- Zero to `width` inside canvas area.
local y = (sy - oy)/zoom -- Zero to `height` inside canvas area.
x, y = x * scalex, y * scaley

return x, y -- NOTE: Not rounded to even pixels.
end

return M
13 changes: 12 additions & 1 deletion lowrezjam/render/lowrez.render_script
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ local SET_SIZE = hash("set_size")

local IDENTITY = vmath.matrix4()

local coords = require "lowrezjam.render.coords"

local function setup(self, width, height)
self.width = width
self.height = height
self.lowrez_projection = vmath.matrix4_orthographic(0, width, 0, height, -1, 1)
coords.game_width, coords.game_height = width, height

-- render target buffer parameters
local color_params = {
Expand Down Expand Up @@ -70,6 +73,10 @@ function init(self)

self.upscale_material = hash("lowrez")
self.scale_snap = true
coords.scale_snap = true
local window_width = render.get_window_width()
local window_height = render.get_window_height()
coords.window_width, coords.window_height = window_width, window_height
end


Expand Down Expand Up @@ -154,7 +161,10 @@ local function draw_controls(self)
end

function update(self)
clear(self, render.get_window_width(), render.get_window_height())
local window_width = render.get_window_width()
local window_height = render.get_window_height()
coords.window_width, coords.window_height = window_width, window_height
clear(self, window_width, window_height)
render.enable_render_target(self.rt)
draw_game(self)
render.disable_render_target(self.rt)
Expand All @@ -175,6 +185,7 @@ function on_message(self, message_id, message)
else
self.scale_snap = true
end
coords.scale_snap = self.scale_snap
elseif message_id == SET_SIZE then
setup(self, message.width, message.height)
end
Expand Down

0 comments on commit 05dcd0f

Please sign in to comment.