..:D&G:.. Posted March 25, 2016 Share Posted March 25, 2016 So I made this login panel with DX, but after a few seconds having the window (renderLoginWindow()) open and clicking the buttons a few times, my game freezes but it doesn't go into "not responding". loginMod = 0 local rustFont = dxCreateFont(":Main/files/Rust.ttf", 30) function build_loginWin() loginMod = 1 dxDrawText("Login", s[1]*161/1920, s[2]*635/1080, s[1]*357/1920, s[2]*718/1080, tocolor(255, 255, 255, 255), 1.00, rustFont, "center", "center", false, false, false, false, false) dxDrawText("Register", s[1]*136/1920, s[2]*728/1080, s[1]*380/1920, s[2]*799/1080, tocolor(255, 255, 255, 255), 1.00, rustFont, "center", "center", false, false, false, false, false) dxDrawText("Quit", s[1]*161/1920, s[2]*809/1080, s[1]*347/1920, s[2]*886/1080, tocolor(255, 255, 255, 255), 1.00, rustFont, "center", "center", false, false, false, false, false) showChat(false) showCursor(true) guiSetInputMode("no_binds_when_editing") end function showLoginOnJoin() addEventHandler("onClientRender",root,build_loginWin) addEventHandler("onClientClick", getRootElement(), onLoginButtonsClick ) end addEventHandler("onClientPlayerJoin", getRootElement(), showLoginOnJoin) function showLoginOnStartup() showLoginOnJoin() end addEventHandler("onClientResourceStart", getRootElement(), showLoginOnJoin) function renderLoginWindow() createLoginEditBoxes() loginMod = 2 dxDrawText("Close", s[1]*1130/1920, s[2]*613/1080, s[1]*1260/1920, s[2]*662/1080, tocolor(255, 255, 255, 255), 1.00, lRustFont1, "center", "center", false, false, false, false, false) dxDrawText("Login", s[1]*931/1920, s[2]*613/1080, s[1]*1109/1920, s[2]*662/1080, tocolor(255, 255, 255, 255), 1.00, lRustFont1, "center", "center", false, false, false, false, false) end function onLoginButtonsClick() if clickLoginClose and (getElementData(getLocalPlayer(), "loggedin") == false) and (loginMod == 2) then removeEventHandler("onClientRender",getRootElement(),renderLoginWindow) loginMod = 1 elseif clickLoginButt and (getElementData(getLocalPlayer(), "loggedin") == false) and (loginMod == 2) then -- LOGIN FUNCTION elseif clickLogin and (getElementData(getLocalPlayer(), "loggedin") == false) and (loginMod == 1) then addEventHandler("onClientRender",root,renderLoginWindow) elseif clickRegister and (getElementData(getLocalPlayer(), "loggedin") == false) and (loginMod == 1) then outputDebugString("Clicked register") --addEventHandler("onClientRender",root,renderRegisterWindow) elseif clickQuit and (getElementData(getLocalPlayer(), "loggedin") == false) and (loginMod == 1) then outputDebugString("Quit") --addEventHandler("onClientRender",root,renderQuitWindow) end end Thanks. Link to comment
Mr_Moose Posted March 26, 2016 Share Posted March 26, 2016 That's simply to heavy to run, remember that onClientRender already uses a large amount of system resources just being executed. You're also using two events to trigger the client render (onClientPlayerJoin) and (onClientResourceStart) of which one of them triggers as soon another player joins. You have multiple GUI's drawing on top of each others, on line 39 you're also adding another onClientRender to draw yet another GUI instead of removing it which would have been the logical choice. This means you won't need many clicks on the login button until your game freezes. Link to comment
..:D&G:.. Posted March 26, 2016 Author Share Posted March 26, 2016 I sorted it out now, now it removes the handler for the old function before adding it to a new one, and now there is only 1 function for the buttons. But now after a few seconds, the font just failes and turns to a boolean, and when I click a "button", it clicks 2 times instead of once... Link to comment
Simple0x47 Posted March 26, 2016 Share Posted March 26, 2016 Why don't you make a .png based login? It's gonna be nicer and easier to make. Link to comment
..:D&G:.. Posted March 26, 2016 Author Share Posted March 26, 2016 Why don't you make a .png based login? It's gonna be nicer and easier to make. I like DX, it looks nicer and it's better optimized (in a way...). Link to comment
Dealman Posted March 26, 2016 Share Posted March 26, 2016 You'll need to read the function and event descriptions more thoroughly. All the answers you're looking are there. 1. Render events are run with every frame, so whatever you do here need to be done carefully. As stated before, you were probably creating new GUI elements with every frame. This would mean 30-60 new GUI elements per second. No wonder it stops responding, eh? 2. The reason onClientClick is triggering twice is because you're not checking whether it was pressed down or released. It triggers for both of those. Example; function ExampleCode(theButton, theState) if(theButton == "left" and theState == "down") then -- Left mouse button was pressed down end end Link to comment
..:D&G:.. Posted March 26, 2016 Author Share Posted March 26, 2016 You'll need to read the function and event descriptions more thoroughly. All the answers you're looking are there.1. Render events are run with every frame, so whatever you do here need to be done carefully. As stated before, you were probably creating new GUI elements with every frame. This would mean 30-60 new GUI elements per second. No wonder it stops responding, eh? 2. The reason onClientClick is triggering twice is because you're not checking whether it was pressed down or released. It triggers for both of those. Example; function ExampleCode(theButton, theState) if(theButton == "left" and theState == "down") then -- Left mouse button was pressed down end end Fucking finally someone to point me in the right direction! Now that I fixed the double clicking, what other event should I use? Link to comment
Dealman Posted March 27, 2016 Share Posted March 27, 2016 [quote name=..&G:..] finally someone to point me in the right direction! Now that I fixed the double clicking, what other event should I use? For what? For the above you use onClientClick. Or are you referring to the rendering? What you're doing should work just fine just make sure stuff like createLoginEditBoxes() is only run once when needed. You can do so by either using an if statement or simply executing it when they click a button instead - which would be the logical way to go. Edit: Just noticed that you're trying to use onClientClick on GUI elements. For this you'll want to use onClientGUIClick instead. Edit2: I was bored, so I re-wrote your code a bit to show how I personally would write it. Of course, nothing is tested so don't copy and paste it and expect it to work. It's very likely I may have missed something It's just to give you an idea of how it could be better organized. local rustFont = dxCreateFont(":Main/files/Rust", 30) -- Use this table to control what is being rendered, thus, you can keep it all undere one drawing function. Add entires as you want, remember to add a new elseif statement to DX_MenuDrawing! local activeMenu = { ["MainMenu"] = true, ["LoginMenu"] = false, ["RegisterMenu"] = false } function DX_MenuDrawing() if(activeMenu["MainMenu"] == true) then -- Main menu is currently true, so draw any necessary DX stuff here. dxDrawText("Login", s[1]*161/1920, s[2]*635/1080, s[1]*357/1920, s[2]*718/1080, tocolor(255, 255, 255, 255), 1.00, rustFont, "center", "center", false, false, false, false, false) dxDrawText("Register", s[1]*136/1920, s[2]*728/1080, s[1]*380/1920, s[2]*799/1080, tocolor(255, 255, 255, 255), 1.00, rustFont, "center", "center", false, false, false, false, false) dxDrawText("Quit", s[1]*161/1920, s[2]*809/1080, s[1]*347/1920, s[2]*886/1080, tocolor(255, 255, 255, 255), 1.00, rustFont, "center", "center", false, false, false, false, false) elseif(activeMenu["LoginMenu"] == true) then -- Login menu is currently true, so draw any necessary DX stuff here. dxDrawText("Close", s[1]*1130/1920, s[2]*613/1080, s[1]*1260/1920, s[2]*662/1080, tocolor(255, 255, 255, 255), 1.00, lRustFont1, "center", "center", false, false, false, false, false) dxDrawText("Login", s[1]*931/1920, s[2]*613/1080, s[1]*1109/1920, s[2]*662/1080, tocolor(255, 255, 255, 255), 1.00, lRustFont1, "center", "center", false, false, false, false, false) elseif(activeMenu["RegisterMenu"] == true) then -- Register menu is currently true, so draw any necessary DX stuff here. end end function DetectMenuClicks_Handler(theButton, theState) if(theButton == "left" and theState == "up") then if(source == clickLoginClose) then -- elseif(source == clickLoginButt) then -- elseif(source == clickLogin and activeMenu["LoginMenu"] == false and getElementData(localPlayer, "loggedin") == false) then -- Make sure that the new menu is not already showing, to avoid clicking things not currently visible. -- Since now after you've clicked it, it's active - so update the status activeMenu["MainMenu"] = false -- Make sure the previous stage stops rendering activeMenu["LoginMenu"] = true createLoginEditBoxes() -- Alternatively you can create them on start and just use guiSetVisible. elseif(source == clickRegister and activeMenu["RegisterMenu"] == false and getElementData(localPlayer, "loggedin") == false) then activeMenu["MainMenu"] = false -- Make sure the previous stage stops rendering activeMenu["RegisterMenu"] = true elseif(source == clickQuit) then -- Make sure you stop drawing, not necessary if the player quits the server, obviously. removeEventHandler("onClientRender", root, DX_MenuDrawing) end end end addEventHandler("onClientGUIClick", root, DetectMenuClicks_Handler) function OnStart_Handler() -- Stuff like these only need to be run once, instead of with every frame. showChat(false) showCursor(true) guiSetInputMode("no_binds_when_editing") -- addEventHandler("onClientRender", root, DX_MenuDrawing) end addEventHandler("onClientResourceStart", resourceRoot, OnStart_Handler) Also to further optimize it, you'll want to avoid doing hardcoded math when drawing frames if necessary. For example, you're doing this to make your drawings relative; s[1]*161/1920 you could instead do this s[1]*0.0838541666666667. Yes, it looks uglier, but it's one calculation less. And this is a calculation you'll be doing every frame. While the difference may not be noticeable at all, it's good to keep such things in mind as optimization is very important. To speed the process up you can use this; I use a website where you can run Lua code to make the process very fast and straight forward, since doing it all manually is a very tedious process. Especially with DX functions. Simply paste this code(into the website linked above) and enter the appropriate values. Then copy the output and you're golden. local sX, sY, wX, hY = 480, 240, 969, 570; -- Paste the absolute values here local sourceWidth = 1920; -- Change those to the source values. local sourceHeight = 1080; -- Change those to the source values. local nSX, nSY, nWX, nHY = (sX/sourceWidth), (sY/sourceHeight), (wX/sourceWidth), (hY/sourceHeight); for i=0, 47 do print(""); -- This is just to clear the print window, so you don't confused what to copy. end print(tostring(nSX).."*screenX, "..tostring(nSY).."*screenY, "..tostring(nWX).."*screenX, "..tostring(nHY).."*screenY"); Link to comment
..:D&G:.. Posted March 27, 2016 Author Share Posted March 27, 2016 Lol, that was really useful, thanks a lot! Now it works like a charm Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now