HU/Introduction to Scripting the GUI - Part 2
Ebben a tutoriálban létre fogunk hozni egy egyszerű szabályok ablakot egy elfogadási gombbal, és egy listával a szerver összes szabályairól, és infórmációiról.
Megjegyzés: Vegye figyelembe, hogy ez a tutoriál a Bevezetés a GUI készítésébe tartalmára épül. |
A GUI készítése
Alapbeállítások
Az első dolog, amit létre kell hoznunk, az a GUI elem. Ehhez a tutoriálhoz egy ablakot, egy gombot és egy címkét használunk. Abszolút pozícióértékeket fogunk használni.
Ahogy az előző tutoriálban is említettük, minden GUI-t client oldalon kell létrehozni.
Ha követte az utasításokat az előző tutoriálból, akkor nyissa meg a gui.lua fájlt, amivel majd dolgozni fog.
Ha nem, lépjen a /Your MTA Server/mods/deathmatch/resources/myserver/ könyvtárba, és hozzon létre egy mappát "client" néven. A /client/ könyvtárban hozzon létre egy szöveges fájlt "gui.lua" néven.
Ha még nem tette meg, ne felejtse el hozzáadni az új gui.lua fájlt a meta.xml-hez a fő resource-ba, és adja meg client script-ként:
<script src="client/gui.lua" type="client" />
Ablak létrehozása
Ebben a fájlban írni fogunk egy function-t, ami kirajzolja az ablakot:
-- create the function that will hold our gui creation code function createRulesWindow() -- get the screen width and height local sWidth, sHeight = guiGetScreenSize() -- create the window, using some maths to find the centre of the screen local Width,Height = 445,445 local X = (sWidth/2) - (Width/2) local Y = (sHeight/2) - (Height/2) -- create the window rulesWindow = guiCreateWindow(X,Y,Width,Height,"Rules",false) -- stop players from being able to simply move the window out of the way guiWindowSetMovable(rulesWindow,false) -- stop players from being able to resize the window guiWindowSetSizable(rulesWindow,false) end
Ez létre fog hozni egy alap ablakot a képernyő közepére, ez az ablak nem mozgatható és méretezhető.
Gomb létrehozása
Most létrehozzuk a gombot az ablak aljára, melyre a játékos rá tud kattintani, hogy elfogadja a szabályokat:
Mostpedig több kódot adunk hozzá a már meglévő 'createRulesWindow' function-ünkhöz. Ez nem egy új function, hanem a már meglévőt helyettesíti.
function createRulesWindow() -- get the screen width and height local sWidth, sHeight = guiGetScreenSize() -- create the window, using some maths to find the centre of the screen local Width,Height = 445,445 local X = (sWidth/2) - (Width/2) local Y = (sHeight/2) - (Height/2) -- create the window and save the window gui element in a variable called 'rulesWindow' rulesWindow = guiCreateWindow(X,Y,Width,Height,"Rules",false) -- stop players from being able to simply move the window out of the way -- note that we use our 'rulesWindow' variable to make changes to the window guiWindowSetMovable(rulesWindow,false) -- stop players from being able to resize the window guiWindowSetSizable(rulesWindow,false) -- create the button and save the button gui element in a variable called 'rulesButton' rulesButton = guiCreateButton(137,394,158,37,"Accept",false,rulesWindow) end
Címke létrehozása
Most hozzáadjuk a címkét az ablakunk közepére, hogy megjelenítsük a szabályainkat:
Mostpedig több kódot adunk hozzá a már meglévő 'createRulesWindow' function-ünkhöz. Ez nem egy új function, hanem a már meglévőt helyettesíti.
function createRulesWindow() -- get the screen width and height local sWidth, sHeight = guiGetScreenSize() -- create the window, using some maths to find the centre of the screen local Width,Height = 445,445 local X = (sWidth/2) - (Width/2) local Y = (sHeight/2) - (Height/2) -- create the window and save the window gui element in a variable called 'rulesWindow' rulesWindow = guiCreateWindow(X,Y,Width,Height,"Rules",false) -- stop players from being able to simply move the window out of the way -- note that we use our 'rulesWindow' variable to make changes to the window guiWindowSetMovable(rulesWindow,false) -- stop players from being able to resize the window guiWindowSetSizable(rulesWindow,false) -- create the button and save the button gui element in a variable called 'rulesButton' rulesButton = guiCreateButton(137,394,158,37,"Accept",false,rulesWindow) -- create the label and save the label gui element in a variable called 'rulesLabel' -- we set the text of the label to our rules rulesLabel = guiCreateLabel(10,25,425,359,[[ Welcome to my MTA Server! Please carefully read the rules before accepting. By accepting the rules, you are agreeing to play by them. Anyone caught breaking these rules will be kicked and/or banned from this server. If you do not accept the rules within 90 seconds, you will be kicked. 1: No cheating. 2: No bug abuse. 3: No mods to your game. 4: No flaming. 5: Respect other players. 6: Be nice!]],false,rulesWindow) -- set the horizontal alignment of the label to center (ie: in the middle of the window) -- also note the final argument "true" -- this turns on wordwrap so if your text goes over the edge of the label, it will wrap around and start a new line automatically guiLabelSetHorizontalAlign(rulesLabel,"center",true) end
Vegye figyelembe, hogy a szöveg egy másik módon van hozzáadva (nem használunk idézőjeleket, "").
Szöveg
Két módja létezik a címke szövegének megadására. A legtöbb esetben az ajánlott módszer az, hogy az összes szöveget idézőjelek közé írja be:
guiSetText(guiElement,"My text here")
Azonban, ha egynél több sort szeretnénk a szövegünkbe helyezni, akkor ugyan olyan könnyen használhatjuk a második módszert. Csupán a helyzettől, és a személyes választástól függ, hogy melyik módszert válasszuk. A tisztánlátás érdekében röviden ismertetem mind a kettőt.
Idézőjelek használata esetén használhatjuk az újsor karaktert: "\n" Ez lehetővé teszi a számunkra, hogy új sort szúrjunk a szövegünkbe.
Például:
guiSetText(guiElement,"This is line 1. \n This is line 2. \n This is line 3.")
Azonban, ha zárójeleket közé helyezzük a szöveget idézőjelek helyett, akkor nem kell aggódni azon, hogy egy plusz karaktert addjunk a szöveghez.
Könnyedén beírhatjuk azt a szöveget, amit majd meg szeretnénk jeleníteni a címkében. Például:
guiSetText(guiElement,[[This is line 1. This is line 2. This is line 3.]])
Mindkét példa ugyan azt a szöveget fogja létrehozni a címkében. Egyedűl attól függ, hogy melyik módszert szeretné választani a használathoz.
A function használata
A createRulesWindow function most már kész, de nem fog csinálni semmit, míg meg nem hívjuk. Ajánlott az összes GUI létrehozás, amikor a client resource elindul. Rejtse el őket, majd amikor szükség van rá, jelenítse meg a játékosnak.
Ezért írni fogunk egy eseménykezelőt az onClientResourceStart-ra, hogy hozza létre az ablakot:
-- attach the event handler to the root element of the resource -- this means it will only trigger when its own resource is started addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), function () -- call the createRulesWindow function to create our gui createRulesWindow() end )
Mivel ez egy szabályok ablak, ezért ezt meg kell jelenítenünk a játékosnak, amikor csatlakozik. Szerencsére a GUI elemek alapértelmezetten láthatóek, ezért nem kell több kódot írni ennek megvalósítása érdekében.
Azonban láthatóvá kell tenni a kurzort a játékosoknak is. Ezt megtehetjük ugyan azzal az eventel használva, onClientResourceStart, így módosítani tudjuk a fenti kódot, hogy láthatóvá tegye a kurzort:
Mostpedig több kódot adunk hozzá a már meglévő 'onClientResourceStart' event-ünkhöz. Ez nem egy új function, hanem a már meglévőt helyettesíti.
-- attach the event handler to the root element of the resource -- this means it will only trigger when its own resource is started addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), function () -- call the createRulesWindow function to create our gui createRulesWindow() -- show the cursor to the player showCursor(true,true) end )
Most már van egy kész szabályok ablakunk. Ezután megkell írnunk a gomb müködését az elfogadás gombhoz.
A gomb megírása
Most, hogy létrehoztuk a GUI-t, működővé is kell hogy tegyük.
A klikk észlelése
Ha egy játékos rákattint a GUI bármely részére, akkor az "onClientGUIClick" event meg fog hívodni arra a GUI részre, amelyre kattintott. Ez lehetővé teszi a számunkra, hogy kennyedén észlelni tudjunk bármilyen kattintást a GUI elemen, amit használni akarunk. Például, hozzá tudjuk csatolni a 'rulesButton' eventet a gombhoz, hogy érzékelje a kattintásokat rajta:
-- attach the event onClientGUIClick to rulesButton and set it to trigger the 'acceptRules' function addEventHandler("onClientGUIClick", rulesButton, acceptRules, false)
Vegye figyelembe, hogy az utolsó paraméter az "false". Ez azt mutatja, hogy az event közvetlenül csak a rulesButton-on hívodik meg, és nem akkor, ha az event magasabb, vagy alacsonyabb ágon van. Gui elem csatolása közben, ha "true"-ra állítja, akkor az azt jelenti, hogy bármely ugyan azon ágon lévő elemre kattintás során az event meghívodik.
Ezt a kódot már hozzá is adhatjuk a 'createRulesWindow' function-höz. Gyakori hiba, hogy eventeket próbálnak meg csatolni egy nem létező GUI-hoz, ezért győződjön meg arról, hogy mindig a létrehozott GUI elem után csatolja az eventet (ebben az esetben a gomb):
function createRulesWindow() -- create all our GUI elements ... -- now add our onClientGUIClick event to the button we just created addEventHandler("onClientGUIClick", rulesButton, acceptRules, false)
A klikk kezelése
Most, hogy észlelni tudjuk, hogy a játékos mikor kattint a gombra, írnunk kell egy kódot, ami kezelni tudja ezt, amikor a játékos kattint. A mi onClientGUIClick event handler-ünkben azt mondtuk, hogy hívja meg a 'acceptRules' function-t, amikor a 'rulesButton'-ra kattintottak. Ezért most már használhatjuk a 'acceptRules' function-t annak ellenőrzésére, hogy mi történik a gomb megnyomásakor:
-- create the function and define the 'button' and 'state' parameters -- (these are passed automatically by onClientGUIClick) function acceptRules(button,state) -- if our accept button was clicked with the left mouse button, and the state of the mouse button is up if button == "left" and state == "up" then -- hide the window and all the components guiSetVisible(rulesWindow, false) -- hide the mouse cursor showCursor(false,false) -- output a message to the player outputChatBox("Thank you for accepting our rules. Have fun!") -- if the warning timer exists if rulesWarningTimer then -- stop the timer and set the variable to nil -- this is the timer used to kick players who do not accept the rules. We will cover this in more detail in the next section. killTimer(rulesWarningTimer) rulesWarningTimer = nil end end end
Most, amikor a gombot megnyomják, akkor az ablak és a kurzor elrejtődik.
Elfogadás ellenőrzése
Jelenleg a mi ablakunk akkkor fog megjelenni, amikor a játékos csatlakozik a szerverre, és csak az elfogadás után tünik el. Azonban, ha nem fogjadja el, akkor bármeddig a szerveren maradhat a nyitott ablakkal együtt.
Az időzítő beállítása
Ennek elkerülésének érdekében egy setTimer-t adunk hozzá, hogy egy bizonyos idő után kickelje a játékost, ha nem fogadta el a szabályokat. Előszőr is szükségünk lesz egy globális változóra, hogy tárolni tudjuk az időt:
local rulesWarningTimer = nil
Helyezze ezt a sort a script legtetejére (nem kell, hogy a function-on belül legyen)
Ezután létre hozzuk az időzítőt:
Mostpedig több kódot adunk hozzá a már meglévő 'createRulesWindow' function-ünkhöz
function createRulesWindow() -- create all of our gui ... -- set a timer for 30 seconds and set it to call our 'inactivePlayer' function with "1" as an argument rulesWarningTimer = setTimer(inactivePlayer,30000,1,1) end
Helyezze ezt a setTimer sort a 'createRulesWindow' function közepére. Ez létre fog hozni egy időzítőt, amely 30 másodperc után fog meghívódni.
Figyelmeztetés
Most megfogjuk írni az 'inactivePlayer' function-ünket, hogy figyelmeztetést adjon a játékosnak, és végül kickelje is ki, ha nem fogadja el:
-- create our function and define the 'status' parameter -- the value of status will be passed from our setTimer function call function inactivePlayer(status) -- if status is 1 (this means it is the first warning) if status == 1 then -- output a warning outputChatBox("Please accept our rules or be kicked.") -- set another timer to call inactivePlayer in another 30 seconds, with "2" as an argument rulesWarningTimer = setTimer(inactivePlayer,30000,1,2) -- if status is 2 (the second warning) elseif status == 2 then -- output a final warning outputChatBox("FINAL WARNING: Please accept our rules or be kicked.") -- set a final timer to call inactivePlayer in another 30 seconds, with "3" as an argument rulesWarningTimer = setTimer(inactivePlayer,30000,1,3) elseif status == 3 then -- trigger the server so we can kick the player triggerServerEvent("clientKickInactivePlayer",getLocalPlayer()) end end
Vegye figyelembe a triggerServerEvent használatát, hogy meghívja a szervert. Tapasztalatának kell lennie a client-server kommunikációjáról az előző tutorialból. Ha nincs, vissza mehet és elolvashatja a teljes magyarázatot.
Ezzel be is fejeztük a teljes clint oldali kódunkat ehhez a tutoriálhoz.
A játékos kickelése
Most foglalkoznunk kell azzal a server oldali eventel, amit a client oldalon hívtunk meg. Nyissa meg a server oldali lua fájlt, amivel dolgozni fogunk.
Kezdésként hozzá fogjuk adni az eventet a szerverhez:
-- add the event, note the final argument "true" indicates it can be triggered from the client addEvent("clientKickInactivePlayer",true) -- add an event handler for this event to trigger the kickInactivePlayer function addEventHandler("clientKickInactivePlayer",root,kickInactivePlayer)
Győződjön meg arról, hogy hozzáadta az event handler-t miután meghatározta a 'kickInactivePlayer' function-t.
Vegye figyelembe az addEvent és az addEventHandler használatát a szerveren. Mostanra már rendelkeznie kell némi tapasztalattal a client-server kommunikációjáról az előző tutorialból. Ha nincs, vissza mehet és elolvashatja a teljes magyarázatot.
Végezetűl hozzáadjuk a 'kickInactivePlayer' function-t, hogy kezelje a játékos kickelését:
-- create our function function kickInactivePlayer() -- kick the player kickPlayer(client,"Please accept our rules.") end
Vegye figyelembe a 'client' változó használatát, ez egy MTA specifikus változó, ami az eseményt hívó client-et (player elementet) tartalmazza.
Vegye figyelembe, hogy a kickPlayer-nek rendelkeznie kell ACL hozzáféréssel.
Ez a legegyszerűbb módja a resouce hozzáadásának az ACL-ben:
<group name="Admin"> ... <object name="resource.YourResourceName" /> ... </group>
További információért az ACL-ról, látogassa meg ACL wiki oldalt.
Ez fejezi be ezt a tutoriált. Most már rendelkeznie kell egy teljesen működő 'szabályok' ablakkal a szerverén.
A GUI-val való további segítségért látogassa meg a GUI tutorials oldalt.
Fordította
2018.11.08. Surge