Jump to content

Basic GUI


Haydenmango
 Share

Recommended Posts

I am trying to create a settings menu for my game and to do that I want to be able to click on selection boxes on the menu screen to trigger changes.

 

What is a good way to check if your mouse is above a context image?

 

Picks don't seem to work and distance checks haven't yet worked for me either. Any advice would be appreciated!

Link to comment
Share on other sites

Yeah I tried both of them to no avail.

I did create my own solution just now though that works pretty good. After a mouse hit I check the distance from all the selection boxes to the mouses position and the selection box with the smallest distance is then selected.

 

The code looks like this-

function App:Loop()

self.context:SetColor(1,1,1)
self.context:SetBlendMode(Blend.Alpha)
self.context:SetScale(2.5,2.5)

local font=self.context:GetFont()
local pos={}

local text="Return True"
local tx = (self.context:GetWidth() - font:GetTextWidth(text))/1.5
local ty = self.context:GetHeight() - font:GetHeight() - 162
pos[1]=Vec2(tx+50,ty)
self.context:DrawText(text,tx,ty)

text="Return False"
tx =(self.context:GetWidth() - font:GetTextWidth(text))/3
ty = self.context:GetHeight() - font:GetHeight() - 162
pos[2]=Vec2(tx+50,ty)
self.context:DrawText(text,tx,ty)

if self.window:MouseHit(1) then
local mousepos=self.window:GetMousePosition():xy()
local lastdistance=0
local hit=0
for n=1,#pos do
if pos[n]~=nil then
local d=mousepos:DistanceToPoint(pos[n])
if d<300 then
 if lastdistance>d or lastdistance==0 then
 lastdistance=d
 hit=n
 end
end
end
end
if hit>0 then
System:Print("hit" ..tostring(hit))
if hit==1 then
return true
elseif hit==2 then
return false
end
end
end

end

Link to comment
Share on other sites

What is a good way to check if your mouse is above a context image?

 

It sounds like you are dealing with 2D here so no picking or distances will work here since those are for 3D. My question would be why do you want to check if your mouse is just above a 2D image?

 

I want to be able to click on selection boxes

 

This sounds like you want buttons? If so then you want a function to check if the 2D mouse position is inside a rectangle area.

 

function PointInRect(mpos, rect)
if mpos.x < rect.left then return false end
if mpos.x > rect.left + rect.width then return false end
if mpos.y < rect.top then return false end
if mpos.y > rect.top + rect.height then return false end

return true
end

 

 

So if MouseHit() and PointInRect(window:GetMousePosition(), buttonRect) then you have a click of the button.

 

So this means you construct buttons that have a rectangle table where .top & .left are the x/y position and .width & .height is the button size.

 

This would be your starting point for a basic GUI. However you'll find that this basic GUI won't work well for all screen resolutions. It gets a little more involved to make your GUI screen resolution independent. Aggror mentioned he has a new version of FlowGUI coming out soon. I wasn't aware of this and so I created some lua "classes" that are similar but just for buttons atm. I don't have text drawing on them yet though, but I'll attach the files here if you want to look at them. I allow callback functions to be assigned to each button so you can break your click event out into it's own function easily making the code cleaner than checking for all button clicks inside your own update.

 

The usage of my code would be to create a GUITheme object once defining the button theme (this isn't complete atm as it just uses the normal button image):

 

self.guiTheme = GUITheme:Create()
self.guiTheme:ButtonImages(Texture:Load("Materials/GUI/button.tex"), Texture:Load("Materials/GUI/button.tex"), Texture:Load("Materials/GUI/button.tex"))

 

Then you create the RGUI object that holds the theme and where you will add all "widgets" (just buttons in this case) to:

 

self.gui = RGUI:Create(window:GetWidth(), window:GetHeight(), self.guiTheme)

 

Then you create your buttons and assign click events:

 

self.btnExit = Button:Create("btnExit", Anchor.TopLeft, .1, .1, .2, .1)
self.btnExit.events.onClick:AddHandler(self, self.btnExit_Click)


-- tell the gui container about this button so it can be drawn and checked for events like click
self.gui:AddWidget(self.btnExit)

 


function Script:btnExit_Click(sender, e)
  -- the btnExit was clicked because that's the only one we assigned here but we can assign the same callback to multiple buttons if we want and the sender parameter would be the button that raised this event. e is nothing now but it'll be extra params for that event if needed
end

 

You notice the Anchor and the position and size values might seem odd. The screen resolution independent part is really about this. Anchors are where your widget is, well, anchored too. This makes things relative to that anchor. The x, y, w, h are then relative to the anchor point and screen resolution. x, y, w, h get calculated to get the actual pixel value to be draw at.

 

Then in PostRender() you call the draw for the gui container which will draw the widgets and in UpdateWorld() you call update for the gui container to look for events like clicking. You can Show/Hide widgets for drawing and Enable/Disable for event checking.

 

function Script:PostRender(context)
  self.gui:Draw(context)
end

function Script:UpdateWorld()
  self.gui:Update()
end

rGUI.rar

  • Upvote 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...