thehankinator Posted March 27, 2016 Share Posted March 27, 2016 The Hankinator's UI library http://steamcommunity.com/sharedfiles/filedetails/?id=653673604 This is a rudimentary GUI library with the goal of simplicity but with flexibility. Only basic widgets are included, Label, Button, Checkbox and Combobox. This should satisfy the majority of GUI needs but if you come up with a good case to include others let me know. All widgets can be themed with images for beautification. THUI is built around groups of GUI elements. Every group has a name, this name is used to activate (make visible) when you need it to. Only one group can be active at a time. THUI contains helper functions so that you can ensure the GUI will scale and look similar on different resolutions. The easiest way to layout a menu system is to create a script for each group, then apply the scripts to pivots in your level. If you wish to design it so, you can use the flow graph to control how the user navigates between groups. It is fairly straight forward to create your own widgets that don't look so bland. To kick things off, I am going to start with required changes to Main.lua, a simple example, pause screen, journal, and finally the API reference. When I was thinking about this post, I was thinking I'd have more to say about each example but now that I've gotten to it, the ideas are gone. Please ask if things need additional clarification. I've put a lot of thought into the design of this library so that it could be used in the majority of use cases but if I have forgotten something obvious, please let me know! I publish updates to steam as I see fit but any development occurs on github first: https://github.com/airbrett/THUI Main.lua modifications: It should be pretty trivial to make the same modifications to App.lua but I like Main.lua best and I don't want to spend time talking about App.lua. There is an example Main.lua in the examples directory with all these changes. 1) First thing is first, import THUI at the top of the file and initialize some variables import "Addons/THUI/THUI.lua" paused = false exit_game = false 2) Immediately after the context is created, initialize THUI THUI:Initialize() 3) Change the while loop not to exit when we hit escape, this is for our pause menu example while not exit_game do 4) Next we need to change the program flow to only update the time and the world when the game isn't paused. if not paused then --Update the app timing Time:Update() --Update the world world:Update() end 5) Immediately after world:Render(), we need to update THUI THUI:Update() Simple example: This is a simple example of how to build a simple GUI screen with a label and a button. self.group = THUI:CreateGroup("hello_world", self, THUI.AUTOSCALE, 0, 0, 1023, 767) local title = THUI.Label:Create(512, 50, 0, 0, "Hello World!", THUI.JUSTIFY.CENTER, THUI.JUSTIFY.MIDDLE) title.font_size = 24 local button1 = THUI.Button:Create(512, 300, 200, 50, "A button") self.group:Add(title) self.group:Add(button1) Pause screen example: This script will pause the game when the user hits the escape key. This example is utilizing the ANCHOR functionality to position all widgets to the left middle of the screen. It is pretty straight forward but the interesting parts we do in this order: 1) We create the group 2) Create a label for the title 3) Create a Resume button 4) Set the click callback for the resume button 5) Create an Exit button 6) Set the click callback for the exit button 7) Add all the widgets to the group import "Addons/THUI/THUI.lua" function Script:Start() self.group = THUI:CreateGroup("pause_menu", self, THUI.AUTOSCALE, nil, nil, 1023, 767) self.group.update = THUI:Callback(self.UpdateUI, self, nil) local title = THUI.Label:Create(512, 50, 0, 0, "Paused!", THUI.CENTER, THUI.MIDDLE) title.font_size = 24 local width = 200 local button1 = THUI.Button:Create(512, 300, width, 50, "Resume", THUI.CENTER, THUI.MIDDLE) button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(512, 400, width, 50, "Exit", THUI.CENTER, THUI.MIDDLE) exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) end function Script:ResumeButtonclicked(button) self:HideMenu() end function Script:ExitButtonclicked(button) exit_game = true end function Script:UpdateWorld() if window:KeyHit(Key.Escape) then if not paused then self:ShowMenu() end end end function Script:UpdateUI(group, arg) if window:KeyHit(Key.Escape) then if paused then self:HideMenu() end end end function Script:ShowMenu() THUI:PauseGame(true) THUI:Show("pause_menu") end function Script:HideMenu() THUI:PauseGame(false) THUI:Hide("pause_menu") --FPSPlayer.lua measures the distance from the middle of the screen to figure out how much --the player is trying to look so we need to reset it when the user is done with the UI local context = Context:GetCurrent() Window:GetCurrent():SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2)) end Journal example: This is a little bit more complicated. But the first thing we need to do is create the journal menu itself. This is pretty simple but I will leave it to you to make the fancy things . In this script I create 10 buttons, each button is created with the active flag false so that it is greyed out. When the player picks up a journal entry, the button will be set to active and they can click on the button to view the entry. The Journal Entry script should be put on the object itself, like a piece of paper, cassette tape, or whatever. Journal script: import "Addons/THUI/THUI.lua" function Script:Start() Journal = self --global that entries can use to add themselves self.pg = THUI:CreateGroup("journal", self, THUI.AUTOSCALE, nil, nil, 1023, 767) local title = THUI.Label:Create(512, 50, 0, 0, "Journal", THUI.CENTER, THUI.MIDDLE) title.font_size = 24 local button1 = THUI.Button:Create(50, 700, 200, 50, "Resume") button1.click = THUI:Callback(self.ResumeButtonclicked, self) self.pg:Add(title) self.pg:Add(button1) self.entries = {} self.entry_buttons = {} for i=1, 10 do local b = THUI.Button:Create(512, 45 + 55 * i, 200, 50, "????", THUI.CENTER, THUI.MIDDLE) b.active = false b.click = THUI:Callback(self.EntryButtonclicked, self, i) self.pg:Add(b) self.entry_buttons[i] = b end self.journal_entry = THUI:CreateGroup("journal_entry", self) end function Script:UpdateWorld() if window:KeyHit(Key.J) then if not THUI:GamePaused() then THUI:PauseGame(true) THUI:Show(self.pg) end end end function Script:EntryButtonclicked(button, index) THUI:Hide("journal") THUI:Show(self.entries[index].grp.name) end function Script:ResumeButtonclicked(button) THUI:PauseGame(false) THUI:Hide(self.pg) --FPSPlayer.lua measures the distance from the middle of the screen to figure out how much --the player is trying to look so we need to reset it when the user is done with the UI local context = Context:GetCurrent() Window:GetCurrent():SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2)) end function Script:AddJounalEntry(entry) self.entries[entry.index] = entry local b = self.entry_buttons[entry.index] b.active = true b.text = entry.title end Journal entry script: import "Addons/THUI/THUI.lua" Script.index = 3 Script.title = "Entry 3" function Script:Start() local text = { "Day 45", "", "I have earned the Germans' trust.", "They still do not realize I am a bear." } self.grp = THUI:CreateGroup("entry1", self, THUI.AUTOSCALE, nil, nil, 1023, 767) local label = THUI.Label:Create(512, 10, 0, 0, self.title, THUI.CENTER, THUI.MIDDLE) label.font_size = 24 self.grp:Add(label) local y = 150 local leading = label.font:GetHeight() * 1.3 for i=0, #text do label = THUI.Label:Create(512, y, 0, 0, text[i], THUI.CENTER, THUI.MIDDLE) label.font_size = 24 self.grp:Add(label) y = y + leading end local journal_button = THUI.Button:Create(100, 700, 200, 50, "Journal") journal_button.click = THUI:Callback(self.JournalButtonclick, self, nil) self.grp:Add(journal_button) end function Script:Use() Journal:AddJounalEntry(self) THUI:Show("entry1") THUI:PauseGame(true) self.entity:Hide() end function Script:JournalButtonclick(button, arg) THUI:Hide("entry1") THUI:Show("journal") end 4 Quote Link to comment Share on other sites More sharing options...
thehankinator Posted March 27, 2016 Author Share Posted March 27, 2016 (edited) Reference: This is where the majority if interesting text goes. If something up above doesn't make sense, it might be made clear in this section. THUI constants THUI.ABSOLUTE THUI.AUTOSCALE THUI.ANCHOR These values are using when creating a widget group, they will dictate the behavior of how the size and dimensions of the widgets will be modified (if at all) when added to the group. THUI.LEFT --x axis THUI.CENTER --x axis THUI.RIGHT --x axis THUI.MIDDLE --y axis THUI.TOP --y axis THUI.BOTTOM -- y axis This is used for defining how a widget is positioned via the justify flags. properties THUI.default_fg_color --Foreground color used by widgets THUI.default_bg_color --Background color used by widgets THUI.default_inactive_color --Inactive color used by widgets THUI.default_hover_color --Color used by widgets when mouse is hovering over them THUI.default_mouse_down_color --Color used by widgets when mouse is hovering over them and the left mouse button is down functions THUI:Initialize() Initializes THUI variables. Required for use. THUI:CreateGroup(name, data, mode, anchorx, anchory, width, height) name=the name of the group, this is the name you will use when you want to show this group data=this is any data you want to be able to retrieve from the group at a later time (usually with LookUpByName()) mode=this can be THUI.AUTOSCALE, THUI.ABSOLUTE, or THUI.ANCHOR. THUI.AUTOSCALE will stretch all widgets in relation to the width and height specified. THUI.ABSOLUTE will make no adjustments to the widgets dimensions. THUI.ANCHOR will utilize anchorx, anchory, width and height parameters to move the widgets to the position specified. anchorx=THUI.LEFT, THUI.CENTER, THUI.RIGHT used by THUI.AUTOSCALE anchory=THUI.MIDDLE, THUI.TOP, THUI.BOTTOM used by THUI.AUTOSCALE width=width of the widget group, this is used by THUI.AUTOSCALE and THUI.ANCHOR height=height of the widget group, this is used by THUI.AUTOSCALE and THUI.ANCHOR return=group table This function creates a group to add widgets to. THUI:Show(name) name=group or name of group If name is group, it will be shown. If name is a string, all groups with matching name will be shown. THUI:Hide() name=group or name of group If name is group, it will be hidden. If name is a string, all groups with matching name will be hidden. THUI:Update() This function should be called from Main.lua every iteration. It will redraw any widgets and also fire off any callbacks that are ready to be fired THUI:PauseGame(pause) pause=true will pause, false will resume Convenience function for pausing and resuming the game when Main.lua has required changes (see Main.lua in examples directory) THUI:GamePaused() Returns true if game is paused, false if not paused. THUI:GetFont(path, size) path=Path of the font size=Size of the font Returns a font from cache THUI:MouseOverUI() Returns true if the mouse is hovering over a widget, false otherwise THUI:Callback(func, tbl, arg) func=function to callback tbl=table the function exists in, can be nil if func is a global function arg=arg that should be used when calling the function, can be nil This function creates a callback that is used by buttons to do a task. Group properties group.update --function callback called every frame when group is active functions group:Add(widget) widget=widget to add to the group Adds a specified widget to the group. At this time the widget's position and dimensions are finalized depending on the group's mode. Label properties label.text --Text to be displayed label.font_path --Path to the font label.font_size --Font size label.img --Texture to be drawn instead of text functions THUI.Label:Create(x, y, width, height, text, justify_x, justify_y) x=x position y=y position width=width, required when img property is set height=height, required when img property set justify_x=can be THUI.LEFT, THUI.CENTER or THUI.RIGHT justify_y=can be THUI.MIDDLE, THUI.TOP, or THUI.BOTTOM return=label table Button properties button.text --Text to be displayed button.font_path --Path to the font button.font_size --Font size button.active --This flag determines if the button is enabled or not. button.visible --Hides or shows the button button.click --Function callback for when button is clicked button.fg_color --color used in idle state button.bg_color --background color button.hover_color --mouse hovering over widget button.mouse_down_color --mouse hovering and mouse button down button.inactive_color --active flag false Colors used to draw the button when not themed with textures. button.img_mouseup --idle state button.img_hover --mouse hovering over widget button.img_mouse_down --mouse hovering and mouse button down button.img_inactive --active flag false Textures to be rendered for different states of the button. functions THUI.Button:Create(x, y, width, height, text, justify_x, justify_y) x=x position y=y position width=width height=height justify_x=can be THUI.LEFT, THUI.CENTER or THUI.RIGHT justify_y=can be THUI.MIDDLE, THUI.TOP, or THUI.BOTTOM return=button table Checkbox properties checkbox.active --This flag determines if the checkbox is enabled or not. checkbox.checked --Set to true if box is checked inactive_color --active flag false mouse_down_color --mouse hovering and mouse button down hover_color --mouse hovering over widget fg_color --color used in idle state bg_color --background color Colors used to draw the checkbox when not themed with textures. checkbox.img_inactive --active flag false checkbox.img_mouse_down --mouse hovering and mouse button down checkbox.img_hover --mouse hovering over widget checkbox.img_mouseup --idle state checkbox.img_checked_inactive --active flag false while checked checkbox.img_checked_mouse_down --mouse hovering and mouse button down while checked checkbox.img_checked_hover --mouse hovering over widget while checked checkbox.img_checked_mouseup --idle state while checked Textures to be rendered for different states of the checkbox. functions THUI.CheckBox:Create(x, y, width, height, justify_x, justify_y) x=x position y=y position width=width height=height justify_x=can be THUI.LEFT, THUI.CENTER or THUI.RIGHT justify_y=can be THUI.MIDDLE, THUI.TOP, or THUI.BOTTOM return=checkbox table Combobox The combobox isn't really a widget on it's own. It's a combination of 2 buttons and a label. properties combo.left_button --left button table, see button reference combo.right_button --right button table, see button reference combo.selected --The currently selected item in the list of values functions THUI.ComboBox:Create(x, y, width, height, values, selected, justify_x, justify_y) x=x position y=y position width=width height=height values=table of possible values that can be selected selected=the index of the default value to be selected justify_x=can be THUI.LEFT, THUI.CENTER or THUI.RIGHT justify_y=can be THUI.MIDDLE, THUI.TOP, or THUI.BOTTOM return=combobox table Edited September 14, 2016 by thehankinator Quote Link to comment Share on other sites More sharing options...
Rick Posted March 27, 2016 Share Posted March 27, 2016 What about windows/panels that contain these widgets and the pos/anchoring is relative to them vs the screen? Or maybe everything can be relative to the screen as long as you position elements that look like they are on top of a window/panel. Just curious, why have the users call the THUI:Rel2Ab*() functions at all? As I'm using this, it seems a little tedious and not needed when you can call it behind the scenes for us and we can just pass in values since we would want these to be converted all the time wouldn't we? The entire point of using the lib would be because it handles screen/aspect for us right? [EDIT] This doesn't seem to work through different aspect ratios. I know you have the default width & height variables and I can set those, but it may be a good idea to have defaults for each aspect ratio maybe so the users of the lib don't have to worry about figuring out which aspect ratio they are in and then setting these 2 variables based on that? Just an idea. I love this library and am going to be using some ideas from it in our game and will probably modify it to do some of these things but just want to give feedback as much as I can as I'll be a big user of some of the functionality from it. Some of the more rare screen resolutions don't seem to work that I can see. 1280x800 (8:5) works for sizing but positioning is off, even when I set my default w/h to 1280x800. I bring that up because that's what the LE game player allows players to set as. There are a few strange ones that I think would be troublesome. How would these be handled? Quote Link to comment Share on other sites More sharing options...
thehankinator Posted March 27, 2016 Author Share Posted March 27, 2016 What about windows/panels that contain these widgets and the pos/anchoring is relative to them vs the screen? Or maybe everything can be relative to the screen as long as you position elements that look like they are on top of a window/panel. Just curious, why have the users call the THUI:Rel2Ab*() functions at all? As I'm using this, it seems a little tedious and not needed when you can call it behind the scenes for us and we can just pass in values since we would want these to be converted all the time wouldn't we? The entire point of using the lib would be because it handles screen/aspect for us right? [EDIT] This doesn't seem to work through different aspect ratios. I know you have the default width & height variables and I can set those, but it may be a good idea to have defaults for each aspect ratio maybe so the users of the lib don't have to worry about figuring out which aspect ratio they are in and then setting these 2 variables based on that? Just an idea. I love this library and am going to be using some ideas from it in our game and will probably modify it to do some of these things but just want to give feedback as much as I can as I'll be a big user of some of the functionality from it. Some of the more rare screen resolutions don't seem to work that I can see. 1280x800 (8:5) works for sizing but positioning is off, even when I set my default w/h to 1280x800. I bring that up because that's what the LE game player allows players to set as. There are a few strange ones that I think would be troublesome. How would these be handled? Hey Rick, Thanks for looking at this. I completely forgot about anchoring, luckily I was add it in by adding a mode to the CreateGroup function. Also it allowed me to add a mode for what I am calling Autoscale. This will eliminate the ridiculous amount of Rel2Abs() calls since in autoscale they will be done by the group when they widget is added to it. I just thought of a problem and that is if the same widget gets added to two different groups, that could be a problem but also not a terrible limitation so I'll leave it in for now. I'll have to take a look at why scaling/positioning are off at some of these different ratios. The result of this change (which I'll be pushing to the workshop momentarily) is that CreateGroup now has a lot more arguments. The additional arguments are only for anchoring, as mode defaults to THUI.AUTOSCALE. To Anchor a group of widgets you would do something like the pause menu below. All the contents of the JUSTIFY table within THUI are now directly in THUI, so that could be code breaking if anyone is actually using this yet. self.group = THUI:CreateGroup("pause_menu", self, THUI.ANCHOR, THUI.LEFT, THUI.MIDDLE, 200, 200) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32)) local title = THUI.Label:Create(100, 0, 0, 0, "Paused!", THUI.CENTER, THUI.TOP) title.font = title_font local button1 = THUI.Button:Create(0, 50, 200, 50, "Resume") button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(0, 150, 200, 50, "Exit") exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) Quote Link to comment Share on other sites More sharing options...
Rick Posted March 27, 2016 Share Posted March 27, 2016 That looks a lot cleaner now. The result of this change (which I'll be pushing to the workshop momentarily) is that CreateGroup now has a lot more arguments. That's nothing compared to Win32 programming lol. Honestly it's not that bad and we only have to do it once per group which is not many compared to the controls we'd have potentially. Let me know when it's updated and I'll check it out. Quote Link to comment Share on other sites More sharing options...
thehankinator Posted March 27, 2016 Author Share Posted March 27, 2016 I got to thinking more about it and I've never liked the default_width or default_height so I decided that if a group is going to scale it's widgets it should know it's size so it can scale up when the widget is added to it. I think this should make it more clear what's actually going on. I've updated the documentation to reflect these changes. I've probably got a couple copy/paste errors somewhere so if anyone spots something weird, please let me know. I've pushed the update to steam. I've still not looked at why the positioning was wrong is different aspect ratios. Probably wont get a chance to look at that till tonight or tomorrow. Quote Link to comment Share on other sites More sharing options...
Rick Posted March 27, 2016 Share Posted March 27, 2016 I guess I don't get the changes you've made. So if I pass 1024,767 to CreateGroup() it works, but buttons are stretched with a 16:9 ratio. If I change the values to CreateGroup() to 1919, 1079 then when I test with 1920x1080 the button's placement is not where it should be. It's way to the left. self.group = THUI:CreateGroup("hello_world", self, THUI.AUTOSCALE, 0, 0, 1919, 1079) local title = THUI.Label:Create(512, 50, 0, 0, "Hello World!", THUI.CENTER, THUI.MIDDLE) title.font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32,767)) local button1 = THUI.Button:Create(512, 300, 200, 50, "A button") button1.font = title.font self.group:Add(title) self.group:Add(button1) THUI:Activate("hello_world") Quote Link to comment Share on other sites More sharing options...
thehankinator Posted March 27, 2016 Author Share Posted March 27, 2016 If the group is 1024x767 units in measure, 512 is the center of the x axis so when the group is stretched out to the current resolution, it's in the middle. When you change the group to 1919x1079 units in measure the center is now around 960 of the x axis not 512, so it is on the left. When autoscale is used, the widget's position and dimensions are relative to the group's dimension. Does that make sense? Quote Link to comment Share on other sites More sharing options...
Rick Posted March 27, 2016 Share Posted March 27, 2016 I get it now. So I can code to a specific res and it'll scale for me no matter what res. I've seen games that allow you to universally scale the UI too. Think something like that could be added? Like it auto scales and that would be 100% but then from the result of the autoscale we can provide 1 scale value which is a % from the 100% (normal autoscale)? That might be handy to give players some freedom. http://cdn1.eveonline.com/www/newssystem/media/2783/3017/Esc_Scaling.png http://cdn1.eveonline.com/www/newssystem/media/2783/3017/UI_Scaling_01.png Quote Link to comment Share on other sites More sharing options...
thehankinator Posted March 27, 2016 Author Share Posted March 27, 2016 For anchor mode I don't think it'd be too hard to do that. Not sure if it'd make sense to have that feature on absolute or autoscale mode.. I'll need to think about it for a while. Quote Link to comment Share on other sites More sharing options...
Slastraf Posted March 29, 2016 Share Posted March 29, 2016 "I have earned the Germans' trust.", "They still do not realize I am a bear." Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted May 10, 2016 Share Posted May 10, 2016 Not sure what I am doing wrong. I apply both the example Main and the example Pause to separate Pivots. When I try to run the game, an endless series of blacks screens open up. Any help? Quote Link to comment Share on other sites More sharing options...
thehankinator Posted May 10, 2016 Author Share Posted May 10, 2016 I probably should make the documentation more clear. The example Main should not be on a pivot, it would replace Main.lua in your scripts directory. Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted May 22, 2016 Share Posted May 22, 2016 I'm just not sure where I am going wrong, I have tried to replace the normal main.lua with the example one. I also have tried following the instructions on this page in an attempt to try and make a simple GUI Menu. When I press the esc key, nothing happens. Any help? Quote Link to comment Share on other sites More sharing options...
thehankinator Posted May 22, 2016 Author Share Posted May 22, 2016 I'm just not sure where I am going wrong, I have tried to replace the normal main.lua with the example one. I also have tried following the instructions on this page in an attempt to try and make a simple GUI Menu. When I press the esc key, nothing happens. Any help? Would you post the code for your menu? I'll take a look. Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted May 25, 2016 Share Posted May 25, 2016 --Initialize Steamworks (optional) Steamworks:Initialize() --Set the application title title="Game" --Create a window local windowstyle = window.Titlebar if System:GetProperty("fullscreen")=="1" then windowstyle=windowstyle+window.FullScreen end window=Window:Create(title,0,0,System:GetProperty("screenwidth","1024"),System:GetProperty("screenheight","768"),windowstyle) window:HideMouse() --Create the graphics context context=Context:Create(window,0) if context==nil then return end --Create a world world=World:Create() world:SetLightQuality((System:GetProperty("lightquality","1"))) --Load a map local mapfile = System:GetProperty("map","Maps/start.map") if Map:Load(mapfile)==false then return end while window:KeyDown(Key.Escape)==false do --If window has been closed, end the program if window:Closed() then break end --Handle map change if changemapname~=nil then --Clear all entities world:Clear() --Load the next map Time:Pause() if Map:Load("Maps/"..changemapname..".map")==false then return end Time:Resume() changemapname = nil end --Update the app timing Time:Update() --Update the world world:Update() --Render the world world:Render() --Render statistics context:SetBlendMode(Blend.Alpha) if DEBUG then context:SetColor(1,0,0,1) context:DrawText("Debug Mode",2,2) context:SetColor(1,1,1,1) context:DrawStats(2,22) context:SetBlendMode(Blend.Solid) else --Toggle statistics on and off if (window:KeyHit(Key.F11)) then showstats = not showstats end if showstats then context:SetColor(1,1,1,1) context:DrawText("FPS: "..Math:Round(Time:UPS()),2,2) end end --Refresh the screen context:Sync(true) end Here it is Quote Link to comment Share on other sites More sharing options...
thehankinator Posted May 26, 2016 Author Share Posted May 26, 2016 Here it is This Main.lua does not have the changes required for the UI system to work. The Main.lua in Addons/THUI/Examples should have all the changes you need, Copy it your Scripts directory. Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted May 27, 2016 Share Posted May 27, 2016 Sorry, posted the backup script by accident.This is the real one that I have been using (The Example one). import "Addons/THUI/THUI.lua" --Initialize Steamworks (optional) Steamworks:Initialize() --Set the application title title="MyGame" --Create a window local windowstyle = window.Titlebar if System:GetProperty("fullscreen")=="1" then windowstyle=windowstyle+window.FullScreen end window=Window:Create(title,0,0,System:GetProperty("screenwidth","1024"),System:GetProperty("screenheight","768"),windowstyle) window:HideMouse() --Create the graphics context context=Context:Create(window,0) if context==nil then return end THUI:Initialize() --Create a world world=World:Create() world:SetLightQuality((System:GetProperty("lightquality","1"))) --Load a map local mapfile = System:GetProperty("map","Maps/start.map") if Map:Load(mapfile)==false then return end paused = false exit_game = false while not exit_game do --If window has been closed, end the program if window:Closed() then break end --Handle map change if changemapname~=nil then --Clear all entities world:Clear() --Load the next map Time:Pause() if Map:Load("Maps/"..changemapname..".map")==false then return end Time:Resume() changemapname = nil end if not paused then --Update the app timing Time:Update() --Update the world world:Update() end --Render the world world:Render() THUI:Update() --Render statistics context:SetBlendMode(Blend.Alpha) if DEBUG then context:SetColor(1,0,0,1) context:DrawText("Debug Mode",2,2) context:SetColor(1,1,1,1) context:DrawStats(2,22) context:SetBlendMode(Blend.Solid) else --Toggle statistics on and off if (window:KeyHit(Key.F11)) then showstats = not showstats end if showstats then context:SetColor(1,1,1,1) context:DrawText("FPS: "..Math:Round(Time:UPS()),2,2) end end --Refresh the screen context:Sync(true) end import "Addons/THUI/THUI.lua" function Script:Start() --Autoscale version ---[[ self.group = THUI:CreateGroup("pause_menu", self, THUI.AUTOSCALE, nil, nil, 1023, 767) self.group.update = THUI:Callback(self.UpdateUI, self, nil) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32, 767)) local title = THUI.Label:Create(512, 50, 0, 0, "Paused!", THUI.CENTER, THUI.MIDDLE) title.font = title_font local width = 200 local button1 = THUI.Button:Create(512, 300, width, 50, "Resume", THUI.CENTER, THUI.MIDDLE) button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(512, 400, width, 50, "Exit", THUI.CENTER, THUI.MIDDLE) exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) --]] --Anchored version --[[ self.group = THUI:CreateGroup("pause_menu", self, THUI.ANCHOR, THUI.LEFT, THUI.MIDDLE, 200, 200) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32, 767)) local title = THUI.Label:Create(100, 0, 0, 0, "Paused!", THUI.CENTER, THUI.TOP) title.font = title_font local button1 = THUI.Button:Create(0, 50, 200, 50, "Resume") button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(0, 150, 200, 50, "Exit") exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) --]] --Absolute version --[[ self.group = THUI:CreateGroup("pause_menu", self, THUI.ABSOLUTE) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32, 767)) local title = THUI.Label:Create(400, 200, 0, 0, "Paused!", THUI.CENTER, THUI.TOP) title.font = title_font local button1 = THUI.Button:Create(300, 250, 200, 50, "Resume") button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(300, 350, 200, 50, "Exit") exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) --]] end function Script:ResumeButtonclicked(button) self:HideMenu() end function Script:ExitButtonclicked(button) exit_game = true end function Script:UpdateWorld() if window:KeyHit(Key.Escape) then if not paused then self:ShowMenu() end end end function Script:UpdateUI(group, arg) if window:KeyHit(Key.Escape) then if paused then self:HideMenu() end end end function Script:ShowMenu() paused = true Time:Pause() THUI:Activate("pause_menu") end function Script:HideMenu() paused = false Time:Resume() THUI:Deactivate() --FPSPlayer.lua measures the distance from the middle of the screen to figure out how much --the player is trying to look so we need to reset it when the user is done with the UI local context = Context:GetCurrent() Window:GetCurrent():SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2)) end Quote Link to comment Share on other sites More sharing options...
thehankinator Posted May 28, 2016 Author Share Posted May 28, 2016 Sorry, posted the backup script by accident.This is the real one that I have been using (The Example one). Is that whole thing in your Main.lua? If so, you've got the pause screen script combined with the Main.lua script. The second portion (starting with the second "import" line to the end) should go in it's own script and be assigned to a pivot in your level. Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted May 28, 2016 Share Posted May 28, 2016 Thanks, it now works! Sorry for being a bit dim. Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted May 31, 2016 Share Posted May 31, 2016 I was doing some edits to the pause menu to make it pop up once the player starts the game-and it does. Unfortunately I can't seem to it so once the player clicks on Resume the script goes back to normal. Heres a copy of my most succesful attempt --The Hankinator's UI library --For this script to work, you need to modify your Main.lua to --only call Time:Update() and world:Update() when paused is false. --Take a look at the Main.lua in the example's directory import "Addons/THUI/THUI.lua" Script.startPause = true function Script:Start() --Autoscale version ---[[ self.group = THUI:CreateGroup("pause2", self, THUI.AUTOSCALE, nil, nil, 1023, 767) self.group.update = THUI:Callback(self.UpdateUI, self, nil) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32, 767)) local title = THUI.Label:Create(512, 50, 0, 0, "Parkour Game", THUI.CENTER, THUI.MIDDLE) title.font = title_font local width = 200 local button1 = THUI.Button:Create(512, 300, width, 50, "Play", THUI.CENTER, THUI.MIDDLE) button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(512, 400, width, 50, "Exit", THUI.CENTER, THUI.MIDDLE) exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) --]] --Anchored version --[[ self.group = THUI:CreateGroup("pause_menu", self, THUI.ANCHOR, THUI.LEFT, THUI.MIDDLE, 200, 200) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32, 767)) local title = THUI.Label:Create(100, 0, 0, 0, "Paused!", THUI.CENTER, THUI.TOP) title.font = title_font local button1 = THUI.Button:Create(0, 50, 200, 50, "Resume") button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(0, 150, 200, 50, "Exit") exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) --]] --Absolute version --[[ self.group = THUI:CreateGroup("pause_menu", self, THUI.ABSOLUTE) local title_font = Font:Load("Fonts/arial.ttf", THUI:Rel2AbsY(32, 767)) local title = THUI.Label:Create(400, 200, 0, 0, "Paused!", THUI.CENTER, THUI.TOP) title.font = title_font local button1 = THUI.Button:Create(300, 250, 200, 50, "Resume") button1.click = THUI:Callback(self.ResumeButtonclicked, self) local exitbutton = THUI.Button:Create(300, 350, 200, 50, "Exit") exitbutton.click = THUI:Callback(self.ExitButtonclicked, self) self.group:Add(title) self.group:Add(button1) self.group:Add(exitbutton) --]] end function Script:ResumeButtonclicked(button) if self.startPause==true then self.startPause = false end self:HideMenu() end function Script:ExitButtonclicked(button) exit_game = true end function Script:UpdateWorld() if window:KeyHit(Key.Escape) or self.startPause == true then if not paused then self:ShowMenu() end end end function Script:UpdateUI(group, arg) if window:KeyHit(Key.Escape) then if paused then self:HideMenu() end end end function Script:ShowMenu() paused = true Time:Pause() THUI:Activate("pause2") end function Script:HideMenu() paused = false Time:Resume() THUI:Deactivate() --FPSPlayer.lua measures the distance from the middle of the screen to figure out how much --the player is trying to look so we need to reset it when the user is done with the UI local context = Context:GetCurrent() Window:GetCurrent():SetMousePosition(Math:Round(context:GetWidth()/2), Math:Round(context:GetHeight()/2)) end Quote Link to comment Share on other sites More sharing options...
thehankinator Posted June 1, 2016 Author Share Posted June 1, 2016 I was doing some edits to the pause menu to make it pop up once the player starts the game-and it does. Unfortunately I can't seem to it so once the player clicks on Resume the script goes back to normal. Heres a copy of my most succesful attempt What are you trying to achieve? When I tried your script, the game starts paused with your menu up. Something I noticed is that I placed paused = false in an unfortunate spot in Main.lua. I should have put it above loading the map. If you do that, to show the Pause menu when the game starts you can just put self:ShowMenu() at the end the Start() function in your script. The solution you have now is perfectly fine though. Quote Link to comment Share on other sites More sharing options...
Sargeant12344 Posted June 5, 2016 Share Posted June 5, 2016 NM, I had a platform without any mass. Quote Link to comment Share on other sites More sharing options...
CangoJoe Posted July 3, 2016 Share Posted July 3, 2016 Hi, I've been testing the Pause and Journal scripts following the provided instructions. I managed to get Pause to work fine but it seems that the Journal script creates a script error in Core.lua on Line 74 (attempt to index a nil value). For testing, do I simply attach JournalEntry.lua to a Model or am I missing something? I'm new to Leadwerks and Lua so please forgive any newb oversights. Thanks! Quote Link to comment Share on other sites More sharing options...
thehankinator Posted July 3, 2016 Author Share Posted July 3, 2016 Hi, I've been testing the Pause and Journal scripts following the provided instructions. I managed to get Pause to work fine but it seems that the Journal script creates a script error in Core.lua on Line 74 (attempt to index a nil value). For testing, do I simply attach JournalEntry.lua to a Model or am I missing something? I'm new to Leadwerks and Lua so please forgive any newb oversights. Thanks! Do you have the Journal.lua script on a pivot in your scene? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.