HU/Scripting the GUI - Tutorial 2
Scripting the GUI - Tutorial 2 (Gates and Keypads)
Ebben a tutoriálban meg fogjuk nézni a GUI keypad létrehozását egy kombinációs kód használatával a map által meghatározott kapu objecthez. We will be using serverside keycodes, with some client - server interaction to verify the codes and report the outcome.
Ne feledje, hogy ez a tutoriál feltételezi azt, hogy tisztában van az előző tutoriálban bemutatott összes tartalommal
A billentyűzet létrehozása
Kezdésként nyisson meg egy client oldali lua fájlt (ha követte a bevezetés a scriptelésbe oldalt, akkor ez a gui.lua lesz) amivel majd dolgozni fog.
A GUI létrehozása
Mostanra a GUI létrehozása viszonylag egyenesen előre láthatónak tűnhet, ezért nem fogunk túl nagy részleteiben belemenni. Ahogy az előző tutoriálban is, itt is absolute értékeket fogunk használni.
function createKeypad() -- 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 = 142,276 local X = (sWidth/2) - (Width/2) local Y = (sHeight/2) - (Height/2) keypadWindow = guiCreateWindow(X,Y,Width,Height,"Keypad",false) -- don't allow people to resize the keypad guiWindowSetSizable(keypadWindow,false) -- create buttons labeled 0-9, "*", "#", "Enter" and "C" (clear) keypadButton1 = guiCreateButton(13,68,37,36,"1",false,keypadWindow) keypadButton2 = guiCreateButton(53,68,37,36,"2",false,keypadWindow) keypadButton3 = guiCreateButton(93,68,37,36,"3",false,keypadWindow) keypadButton4 = guiCreateButton(13,108,37,36,"4",false,keypadWindow) keypadButton5 = guiCreateButton(53,108,37,36,"5",false,keypadWindow) keypadButton6 = guiCreateButton(93,108,37,36,"6",false,keypadWindow) keypadButton7 = guiCreateButton(13,148,37,36,"7",false,keypadWindow) keypadButton8 = guiCreateButton(53,148,37,36,"8",false,keypadWindow) keypadButton9 = guiCreateButton(93,148,37,36,"9",false,keypadWindow) keypadButtonAsterix = guiCreateButton(13,188,37,36,"*",false,keypadWindow) keypadButton0 = guiCreateButton(53,188,37,36,"0",false,keypadWindow) keypadButtonHash = guiCreateButton(93,188,37,36,"#",false,keypadWindow) keypadButtonExit = guiCreateButton(13,228,37,36,"Exit",false,keypadWindow) keypadButtonEnter = guiCreateButton(53,228,37,36,"Enter",false,keypadWindow) keypadButtonClear = guiCreateButton(93,228,37,36,"Clear",false,keypadWindow) -- create a gridlist to act as a backdrop on the kaypad display keypadGridlistDisplay = guiCreateGridList(13,25,117,33,false,keypadWindow) guiGridListSetSelectionMode(keypadGridlistDisplay,2) guiSetAlpha(keypadGridlistDisplay,0.6) -- create a label so we can write text on the keypad display keypadLabelDisplay = guiCreateLabel(14,26,115,30,"Enter Keycode.",false,keypadWindow) guiLabelSetColor(keypadLabelDisplay,255,000,000) guiLabelSetVerticalAlign(keypadLabelDisplay,"center") guiLabelSetHorizontalAlign(keypadLabelDisplay,"center",false) guiSetVisible(keypadWindow,false) end -- create the GUI when the resource starts addEventHandler("onClientResourceStart",getResourceRootElement(getThisResource()),createKeypad)
Ahogy azt láthatja, a keypad 10 numerikus billentyűből áll (0-9), két karakterből (* és #), egy törlés gombból, valamint egy bezár és egy indító gombból. Ez azt jelenti, hogy a keypad-on használt kódok tartalmazhatják ezeket a karaktereket (0123456789*#).
A kijelző kezelése
Kezdjük azzal, hogy egy kis funkciót írunk a keypad kijelzőjének a szabályozására. Ez megtehető úgy, hogy megírunk egy függvényt amely tartalmaz számos hívást, melyek a szöveg megváltoztatásához szükségesek, ez lehetővé teszi a számunkra, hogy a későbbiekben könnyedén tudjunk hozzáadni/eltávolítani szövegetek a kijelzőről.
function updateDisplay(text) s if text then -- if its a digit or * or #, then append it to the end of the display if tonumber(text) or text == "*" or text == "#" then guiSetText(keypadLabelDisplay,guiGetText(keypadLabelDisplay) .. text) -- otherwise replace the display with the new text else guiSetText(keypadLabelDisplay,text) end -- if we pass nil, clear the display entirely else guiSetText(keypadLabelDisplay,"") end end
Így egyszerűen meghívhatjuk az updateDisplay-t(our text), hogy megváltoztassa a szöveget a kijelzőn, vagy az updateDisplay(nil)-t, hogy kiürítse azt.
A klikk észlelése
Sok gomb van, amelyek hasonló feladatokat végeznek a keypad-on, két módszer áll a rendelkezésünkre, hogy észleljük amikor a játékos rájuk kattint.
Hozzáadhatjuk egyenként mindegyik gombhoz az onClientGUIClick event-et, ahogy azt az előző tutoriálban is tettük; vagy hozzáadhatunk egy onClientGUIClick handler-t az ablakhoz (amely az összes többi keypad GUI elemünk szülője), majd szűrjük az eredményt, hogy csak a kívánt gombokat tartalmazza, és meghívjuk a saját egyedi event-ünket.
Ennek a tutoriálnak a céljából, és a többféle megközelítés felvázolása érdekében megnézzük a második módszert is, mindkét megoldás elfogadható.
addEventHandler("onClientGUIClick",keypadWindow,processKeypadClicks,true)
Ne feledje, hogy az utolsó paraméter az 'true'. Ez azt jelenti, hogy a fa ugyanazon ágán lévő bármely elemre való kattintást meghívja ezt a handler-t.
Adja hozzá ezt a sort a createKeypad függvényhez, a létrehozott GUI után.
Most, hogy az összes kattintást észlelni tudjuk a GUI-nkon, ki kell szűrnünk azt az egyet, amelyiket nem szeretnénk kezelni (azaz: az ablakon vagy a kijelzőn történő kattintást) és hívjuk meg az egyedi event-ünket:
function processKeypadClicks(button,state) if button == "left" and state == "up" then -- if the source of this event is a gui button if getElementType(source) == "gui-button" then -- trigger our custom event and send the keypad id of this keypad as an argument triggerEvent("onKeypadButtonClicked",source,getElementData(keypadWindow,"keypadID")) end end end
Ahogy azt láthatja, meghívjuk az egyedi "onKeypadButtonClicked" event-ünket, amikor valaki rákattint a gombra a keypad-on. Also note we use element data "keypadID" to differentiate between keypads. This data will need to be set whenever the player is shown a new keypad. Erről majd a későbbiekben fogunk részletesen beszélni.
A klikk kezelése
Úgy, mint az előző tutoriálban használt triggerServerEvent, most meg kell határoznunk az eventet, csak itt most client oldali:
addEvent("onKeypadButtonClicked",false) addEventHandler("onKeypadButtonClicked",root, function(keypadID) end )
Vegye figyelembe, hogy az addEvent második paramétere false-ra van állítva, jelezve, hogy ezt az eventet nem lehet meghívni a szerverről. Valamint azt is vegye figyelembe, hogy az addEventHandler-ben használt függvénynek nincs neve. Ha összevonod és eltávolítot a szóközt, akkor ezt kapot:
addEventHandler("onKeypadButtonClicked",root,function() ... end)
Ez egyszerűen annyit jelent, hogy ahelyett, hogy a függvény mutatóját egy változóban tároljuk, simán megadjuk mint argumentum. Ez gyakran tisztábbá teszi a kód átláthatóságát, és könyebbé a mukálatokat.
Most, hogy az eventet létrehoztuk, megírhatjuk a kód logikai részét, ami vezérelni fogja a gombunk lenyomását.
addEvent("onKeypadButtonClicked",false) addEventHandler("onKeypadButtonClicked",root, function(keypadID) -- clear the display if this is the first time its being used if guiGetText(keypadLabelDisplay) == "Enter Keycode." or guiGetText(keypadLabelDisplay) == "Invalid Keycode." then updateDisplay() end -- if its the clear button if guiGetText(source) == "Clear" then -- clear the display updateDisplay() -- if its the enter button elseif guiGetText(source) == "Enter" then -- get the currently entered code from the display local code = guiGetText(keypadLabelDisplay) -- if they have entered a code if code then -- trigger the server so we can verify their code triggerServerEvent("verifyKeypadCode",getLocalPlayer(),code,keypadID) end -- if its the exit button elseif guiGetText(source) == "Exit" then -- hide the keypad and reset the display text ready for next time guiSetVisible(keypadWindow,false) updateDisplay("Enter Keycode.") showCursor(false,false) -- otherwise, it must be a character button else updateDisplay(guiGetText(source)) end end )
Ne feledje, hogy a kijelző törléséhez csak egyszerűen meg kell hívnunk az updateDisplay()-t argumentumok nélkül. Nem kell megadnunk neki a 'nil' értéket, mivel alapértelmezetten az összes paraméter (és a változók) nil.
Szerver oldal ellenőrzése
A tutoriál további részéhez meg kell nyitnia a szerver oldali lua fájlt a resource-ból, amivel majd dolgozni fog.
A keycode meghatározása
Most, hogy befejeztük a keypad-nak a klikkelés részét, tovább kell haladnunk, hogy ellenőrizzük a bevitt kódot a keypad-ba. Ehhez kelleni fog nekünk a megfelelő kód valahol a szerver oldalon elmentve, amihez majd a játékos kódját tudjuk ellenőrizni.
Megjegyzés: Ne tároljon bizalmas adatokat a kliens oldali fájlokban, mint például keycode-okat, vagy jelszavakat. Minden kliens oldali fájlok lementésre kerülnek a játékos számítógépére, és bárki, aki felcsatlakozik a szerverre az képes hozzáférni és olvasni ezeket a fájlokat. |
Ennek a tutoriálnak a céljából most csak egyszerűen egy szerver oldali táblában fogjuk tárolni a kódot, bár ezt számos módon megteheti (mint például a szerver oldali xml fájlok, vagy MySQL adatbázisok).
local keypadCodes = { ["a51MainGateKeypadCode"] = "4455*#" }
Ez a tábla egy "a51MainGateKeypadCode"-nak nevezett bejegyzést tárol a 4455*# kóddal
Ez a keycode, amit majd használni fog a kapu kinyitásához a tutoriál későbbi részében.
A kód megerősítése
Most, hogy van egy keycode-unk, amit ellenőrizni tudunk, megírhatjuk a szerver oldali event-ünket:
addEvent("verifyKeypadCode",true) addEventHandler("verifyKeypadCode",root,function(code,keypadID) if code then -- using the table we created earlier, check if the code supplied is the same as the code for this gate if code == keypadCodes[keypadID] then -- if it is, tell the client that it was successful triggerClientEvent(client,"onKeypadVerificationSuccessful",client,keypadID) else -- if it is not, tell the client that it was not successful triggerClientEvent(client,"onKeypadVerificationFailed",client,keypadID) end end end)
Itt használni fogjuk a táblánkat és a játékos által beírt keypadID-t, hogy ellenőrizzük, hogy a kód az egyezik-e.
Ha nem használ táblát a kódok tárálásához, akkor ki kell cserélni a 'keypadCodes[keypadID]'-t a saját tárolási módszerével. Miután sikeres lett az ellenőrzés (vagy nem), meghívhatjuk a kliens oldali szkriptünket, hogy a megfelelő információt jelenítse meg a keypad kijelzőjén.
Az eredmény megtekintése
Ezzel be is befejeztük a tutoriál szerver oldali részét, szóval most meg kell nyitnia a kliens oldali lua fájlt a resource-jából, amivel az előzőekben dolgozott.
Miután a kódunk meg lett erősítve, a szerver visszaküldi a választ a kliensnek.
Ugyan úgy, mint a client -> server közötti kommunikációnál, hozzá kell adnunk a klienshez azt az eseményt, amelyet a szerver fog meghívni.
Az eredmény elfogása és feldolgozása
Először hozzáadunk egy eseményt, ha a megerősítés sikeres:
addEvent("onKeypadVerificationSuccessful",true) addEventHandler("onKeypadVerificationSuccessful",root, function() -- hide the keypad and reset the display text ready for next time guiSetVisible(keypadWindow,false) updateDisplay("Enter Keycode.") showCursor(false,false) end )
Végül hozzáadunk még egy eseményt, ha a megerősítés sikertelen:
addEvent("onKeypadVerificationFailed",true) addEventHandler("onKeypadVerificationFailed",root, function() -- update the display text to show the code was invalid updateDisplay("Invalid Keycode.") end )
Ezzel lezárjuk a tutoriál keypad részét.
Egy példa arról, hogy hogyan lehet ezt megvalósítani egy működő kapu rendszerben, folytassa a fejezet olvasását.
A Keypad alkalmazása
A keypad használatához szükségünk lesz valamire, amivel használni tudjuk. Ehhez a tutoriálhoz kapukat fogunk használni, és ahogyan korábban említettük egy fő kaput fogunk létrehozni az A51-be.
A kapu létrehozása
Mindenek előtt létre kell hoznunk egy kapu objektumot. Ennek a példának a céljából egy .map fájlt fogunk használni az objektum tárolásához. Habár ez egy ajánlott módja az objektumok meghatározásához, nem ez az egyetlen módja, hogy kivitelezzük ezt.
Menjen a resource mappához, és hozzon létre egy új fájt gate.map néven, majd adja hozzá ehhez az új fájlhoz a meta.xml-t:
<map src="gate.map"/>
Ha nem biztos a map fájl szintaxisában, kérjük látogassa meg a Játékmódok írása, vagy az Object-t oldalt a további segítségért.
<map> <object id="a51MainGateKeypadCode" model="971" posX="96.736" posY="1918.352" posZ="20.694" rotX="0" rotY="0" rotZ="270.40" newPosX="96.751" newPosY="1914.474" newPosZ="20.694" /> </map>
Ez létrehoz egy kapu objektumot az A51 bejáratánál. Az objektnek most lesz pozíció és tengely körüli forgatás adata, ami a newPosX,newPosY és newPosZ, amivel képesek leszünk mozgatni.
Ne felejde, hogy az objekt id megegyezik a korábban létrehozott táblázatbejegyzéssel, hogy megtartsa a hozzáférési kódot. Ez az egyik lehetséges módszer, amelyhez hozzá lehet férni a kapu összekapcsolásához az adott keycode-val.
A keypad megnyitása
Térjünk vissza a klisensoldali lua fájlhoz ismét, most már dolgozhatunk a kapu és a keypad összekapcsolásán.
Most, hogy a kapunk megvan, kell egy mód, hogy hozzáférjünk a keypadhoz, hogy kinyissa a kaput. Ennek a tutoriálnak a céljából egy egyszerű parancsot fogunk használni, emellett persze könnyedén használhat colshape-t, vagy gomblenyomást.
addCommandHandler("a51gate",function() guiSetVisible(keypadWindow,true) showCursor(true,true) setElementData(keypadWindow,"keypadID","a51MainGateKeypadCode") end)
Vegye figyelembe, hogy beállítottuk az elementdata-t a "keypadID"-re. Ez nagyon fontos, mert lehetővé teszi a számunkra, hogy nyomon tudjuk követni, hogy melyik kaput próbáljuk kinyitni (ebben az esetben ez a "a51MainGateKeypadCode" kapu).
A kapu kinyitása
A létrehozott kapunkkal és a készenálló keypaddal, már csak annyi maradt hátra, hogy kinyissuk a kaput. Having created custom events earlier for successfully and unsuccessfully verifying the code, this now becomes very easy to do. All we do is add an event handler for our custom "success" event, and using the keypadID we defined earlier we can move the gate inside it:
addEventHandler("onKeypadVerificationSuccessful",root, -- keypadID is sent back from the server function(keypadID) -- get the gate object (this is where the id="a51MainGateKeypadCode" tag in the map file becomes useful) local gate = getElementByID(keypadID) -- if we found the object if gate then -- get the new position (as we defined in the map file) local x = tonumber(getElementData(gate,"newPosX")) local y = tonumber(getElementData(gate,"newPosY")) local z = tonumber(getElementData(gate,"newPosZ")) -- move the gate moveObject(gate,1500,x,y,z) -- get the original position x = tonumber(getElementData(gate,"posX")) y = tonumber(getElementData(gate,"posY")) z = tonumber(getElementData(gate,"posZ")) -- set a timer to close the gate in 5 seconds setTimer(moveObject,5000,1,gate,1500,x,y,z) end end )
Note how by using the keypadID sent back from the server, we can use if statements and checks against the id to control any number of gates from the same function.
You should now have a working example of a GUI Keypad controlling an A51 Gate.
Az előző GUI tutoriálokért látogassa meg a GUI készítése - Tutorial 1 (Gridlists) oldalt
A további GUI tutoriálokért látogassa meg a GUI készítése - Tutorial 3 (Scrolling News Feed) oldalt
Fordította
2018.11.26. Surge