HU/Scripting the GUI - Tutorial 1: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
No edit summary
 
(28 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''GUI készítése - Tutorial 1 (Gridlists)'''
'''GUI készítése - Tutorial 1 (Gridlists)'''


Ebben a tutoriálban fel fogjuk fedezni a gridlist-ek használatát egy járműválasztási kijelzőn egy opcionális kliensoldali jármű xml olvasással.
Ebben a tutoriálban fel fogjuk fedezni a gridlist-ek használatát egy járműválasztási kijelzőn egy tetszőleges kliensoldali jármű xml olvasással.


'''Ne feledje, hogy ez a tutoriál feltételezi azt, hogy tisztában van az [[HU/Introduction to Scripting the GUI|előző tutoriálban]] bemutatott összes tartalommal'''
'''Ne feledje, hogy ez a tutoriál feltételezi azt, hogy tisztában van az [[HU/Introduction to Scripting the GUI|előző tutoriálban]] bemutatott összes tartalommal'''




==A jármű választásának létrehozása==
==A jármű kiválasztásának létrehozása==


===A GUI készítése===
===A GUI létrehozása===
Kezdésként nyisson meg egy client oldali lua fájlt (ha követte a [[HU/Bevezetés a scriptelésbe]] oldalt, akkor ez a gui.lua) amivel majd dolgozni fog.
Kezdésként nyisson meg egy client oldali lua fájlt (ha követte a [[HU/Bevezetés a scriptelésbe|bevezetés a scriptelésbe]] oldalt, akkor ez a gui.lua lesz) amivel majd dolgozni fog.


Ebben a fájlban elfogjuk kezdeni megírni a saját function-ünket a GUI létrehozásához.
Ebben a fájlban elfogjuk kezdeni megírni a saját function-ünket a GUI létrehozásához.
Line 51: Line 51:
</syntaxhighlight>
</syntaxhighlight>


Most ezt a function-t meg is kell hívnunk valamivel, külöben a GUI sosem lesz létrehozva.
Most ezt a function-t meg is kell hívnunk valamivel, különben a GUI sosem lesz létrehozva.
Ahogy az előző tutoriálban is az [[onClientResourceStart]]-ot hívtuk segítségül, hogy elvégezze ezt a feladatot.
Ahogy az előző tutoriálban is az [[onClientResourceStart]]-ot hívtuk segítségül, hogy elvégezze ezt a feladatot.
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
Line 105: Line 105:
Helyezze ezt a kódot a script legtetejére (nem kell, hogy egy funkción belül legyen).
Helyezze ezt a kódot a script legtetejére (nem kell, hogy egy funkción belül legyen).


Next, we can write our "populateGridlist" function which will fill the Gridlist with all the vehicles in the table.
Most megírhatjuk a "populateGridlist" function, amely feltölti a Gridlist-et a táblázatban szereplő összes járművel.
To do this we simply need to loop through all the values in the table, adding each one to the gridlist as we go.
Ehhez egyszerűen csak végig kell mennünk a táblában szereplő értékeken, és hozzáadni a gridlist-hez.
We will also set hidden data using [[guiGridListSetItemData]] to store the vehicle id:
Valamint beállítjuk a rejtett adatokat a [[guiGridListSetItemData]] használatával, hogy tároljuk a járművek id-jét:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function populateGridlist()
function populateGridlist()
Line 124: Line 124:
end
end
end
end
</syntaxhighlight>  
</syntaxhighlight>


===Managing the click===
===A klikk kezelése===
Now that we have our GUI completed, we need to be able to catch any clicks made on the "create" button.
Most, hogy elkészült a GUI-nk, észlelnünk is kell minden kattintást a "Create" gombon.
We have attached the [[onClientGUIClick]] event to buttonCreate already, so now we need to write the function that it calls.
Már hozzácsatoltuk az [[onClientGUIClick]] event-et a buttonCreate-hez, így most meg kell írjuk azt a function-t, ami meghívja.
In this function we do some basic error checking, such as making sure a vehicle has been selected in the list.  
Ebben a function-ben elvégzünk néhány alapvető hibaellenőrzést, mint például, hogy meggyőződjünk arról, hogy a jármű az a listából lett-e kiválasztva.
We can then use some maths to find a position infront of the player and send the server this information to spawn the vehicle (using [[triggerServerEvent]])  
Ezután használhatunk néhány számítási feladatot, hogy megtaláljuk a játékos pozícióját, majd elküldjök ezt az infórmációt a szervernek, hogy lespawnolja a járművet a játékos elé ([[triggerServerEvent]] használatával)  
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function createVehicleHandler(button,state)
function createVehicleHandler(button,state)
Line 170: Line 170:
</syntaxhighlight>
</syntaxhighlight>


===Creating the Vehicle===
===A jármű létrehozása===
At this point we now have all the code needed on the client side, so open up a serverside .lua file to work with.  
Ezen a ponton az összes szükséges client oldali kódunk már megvan, szóval nyisson meg egy szerver oldalu .lua fájlt, amivel majd dolgozni fog.  


On the server side, we will first of all need to define the custom event that we triggered before from the client. This can be done using [[addEvent]] and [[addEventHandler]].
Mindenekelőtt a szerver oldalon meg kell adnunk egy egyedi event-et, amit már meghívtunk a client oldalról. Ezt megtehetjük az [[addEvent]] és az [[addEventHandler]] használatával.
Finally we will need a small function for creating the vehicle:
Végezetűl szükségünk lesz egy pici function-re, hogy létrehozzuk a járművet:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function createMyVehicle(vehicleid,x,y,z)
function createMyVehicle(vehicleid,x,y,z)
Line 186: Line 186:
addEventHandler("createVehicleFromGUI",root,createMyVehicle)
addEventHandler("createVehicleFromGUI",root,createMyVehicle)
</syntaxhighlight>
</syntaxhighlight>
Note the use of the "root" variable. This is an MTA variable containing the root element; every resource has one.
Vegye figyelembe a "root" változó használatát. Ez egy MTA változó, amely tartalmazza a root elemet; minden resource-nak van egy.


This completes the first section of the tutorial. You should now have a basic, working vehicle spawn script.
Ezzel be is fejeztük a tutoriál első részét. Mostanra rendelkeznie kell egy alap, működő jármű spawnoló script-el.


In the second section, we will cover collapsible gridlist data and clientside xml file reading.
A második részben megnézzük a gridlist adatok kezelhetőségét, és a client oldali xml fájlok olvasását.


==A kód bővítése==
Ez a rész számos módon fogja részletezni a már meglévő kódunk fejlesztését.


==Expanding the code==
===Adatok importálása===
This section will detail several ways to improve upon the code you now have.
Egy nagy előrehaladás az előző módszerhez képest, hogy külső fájlokat használunk a jármű információinak tárolásához, ez lehetővé teszi a számunkra, hogy gyorsabban és egyszerűbben kezeljünk nagy mennyiségű adatokat.
Ebben a tutoriálban clinet oldali xml fájlt fogunk használni az információ tárolásához.


===Importing Data===
Mindenek előtt létre kell hoznia egy xml fájlt, szóval keresse meg a resource könyvtárát, és hozzon létre egy új vehicles.xml fájlt:
One big improvement over the previously mentioned method is to use external files to store the vehicle information, allowing us to much more quickly and easily manage large amounts of data.
For this tutorial, we will use a clientside xml file to hold the information.


First of all you will need to create your xml file, so navigate to your resources directory and create a new file named vehicles.xml:
''Ennek a tutoriálnak a céljából csak egy kis részét fogjuk felvenni a teljes járműkészletből, azonban a fájl könnyen bővíthető, így a későbbiekben majd az összeset hozzá fogjuk tudni adni''


''For the purpose of this example, we will include only a small fraction of the total vehicles, however the file can easily be expanded to include them all.''
Ha még nem biztos az xml adatok felépítésében, akkor böngézhet a [[Server_Scripting_Functions#XML_functions|MTA xml function-ok]] között a további információkért.
 
If you are unsure of xml data structures, you can browse the [[Server_Scripting_Functions#XML_functions| MTA xml functions]] for help.
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
<root>
<root>
Line 247: Line 246:
</root>
</root>
</syntaxhighlight>
</syntaxhighlight>
Once you have created your file, do not forget to add it to the meta.xml of your resource with the appropriate client tag.
Miután létrehozta a fájlt, ne felejtse el hozzáadni a resource meta.xml fájljához a megfelelő client taggal.


Note the group "type" tag. This is an arbitrary description of the vehicles contained within the group and can be renamed or added as any text.
Vegye figyelembe a "type" tagot. Ez a groupon belüli járművek tetszőleges leírása, ami átnevezhető, vagy hozzáadható bármilyen szöveg.
Similarly, the vehicle "name" tag is also just a textual description of the vehicle and does not need to be the exact vehicle name.
Hasonlóképenn a vehicle "name" tag is csak egy szöveges leírás a járműről, és nem kell, hogy a jármű valódi neve legyen.


Now that we have the data, we can import it into the game and display it in the GUI.
Most, hogy rendelkezünk az adatokkal, importálni tudjuk a játékba és megjeleníteni a GUI-n.
'''If you are following on from the first section of this tutorial, this new code will replace what is inside your existing 'populateGridlist' function.'''
'''Ha követte ezt a tutoriált az első résztől kezdve, akkor ez az új kód a 'populateGridlist' function-ben lévő kódot cseréli ki.'''
First, we need to load the file:
Először be kell töltenünk a fájlt:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function populateGridlist()
function populateGridlist()
Line 267: Line 266:
end
end
</syntaxhighlight>
</syntaxhighlight>
Always make sure you unload any files once you are finished using them.
Mindig bizonyosodjon meg arróla, hogy lezárta a fájlt, mikor már végeztél a szerkesztésével.




We can now start collecting the data from the file and entering it into our gridlist.
Most már elkezdhetjük az adatok gyűjtését, és hozzáadhatjuk a gridlist-hez.
We can do this by looping through the xml data (in a similar manner to looping through the vehicle table earlier in this tutorial) and adding each entry into the list.
We can do this by looping through the xml data (in a similar manner to looping through the vehicle table earlier in this tutorial) and adding each entry into the list.
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
Line 314: Line 313:
end
end
</syntaxhighlight>
</syntaxhighlight>
Note the use of for loops in the code with [[xmlNodeGetChildren]]. This saves us a lot of time and effort as we do not have to manually code each group and vehicle into the list.
Figyelje meg a for ciklus [[xmlNodeGetChildren]] függvénnyel való használatát a kódban. Ez sok időt, és energiát takarít meg nekünk, mivel nem kell manuálisan megírnunk minden egyes group-ot és járművet a listába.


You should now have a fully working vehicle selection menu, reading all of its data from a clientside xml file.
Mostanra már rendelkeznie kell egy teljesen működő járműválasztási menüvel, amely minden adatot a client oldali xml fájlból olvas.
Next, we will examine how to generate the appearance of collapsing and expanding sections in a gridlist.
Következőnek pedig megnézzük, hogy hogyan csináljuk meg a megjelenését a lenyíló részeknek a gridlistben.


===Collapsing/Expanding the Gridlist===
===A Gridlist megnyitása/összecsukása===
Allowing sections of the gridlist to be collapsed or expanded gives much more control over the visible content to the user.
A gridlistben lévő lenyitható menük lehetővé teszik, hogy egy sokkal átláthatóbb panelt készítsünk.
This frees up space on the screen and makes the whole menu much more comfortable to use.
Ezzel helyet takarít meg a képernyőn, és sokkal kényelmesebbé teszi az egész menüt.


===Loading the data===
===Az adatok betöltése===
To be able to achieve this effect (as it is not a natural feature of gridlists) we will need to load the vehicle information into a table (from the xml file), rather than directly including it all in the gridlist.
Ennek a hatásnak az eléréshez (mivel ez nem a gridlisták természetes tulajdonsága) a járműinformációkat egy táblázatba kell betöltenünke (az xml fájlból), ahelyett, hogy közvetlenül a gridlist-be helyeznénk.
'''If you are following on from a previous section of this tutorial, this new code will replace what is inside your existing 'populateGridlist' function.'''
'''Ha követte ezt a tutoriált az első résztől kezdve, akkor ez az új kód a 'populateGridlist' function-ben lévő kódot cseréli ki'''


This works in much the same way the previous xml loading example does, only this time instead of saving the data into the gridlist, we save it into a table entry instead.
Ez is ugyanúgy működik, mint az előző példában szereplő xml betöltési rész, csak ahelyett, hogy az adatokat a grlidlist-be mentenénk, helyette egy táblába mentjük el.
We also set the custom data "header" on the gridlist slots to denote which gridlist entries are our "group" entries and which are vehicles.
Beállítjuk a "header" elementData-t is a gridlist cellákban, hogy meg tudjuk különböztetni, hogy melyik elem egy "group" és melyik egy jármű.
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function populateGridlist()
function populateGridlist()
Line 370: Line 369:
</syntaxhighlight>
</syntaxhighlight>


Now that we have all the data stored, we can quickly manipulate it when neccessary.
Most, hogy tároltuk az összes adatot, gyorsan kezelni is tudjuk, amikor szükséges.


===Managing the double click===
===Dupla kattintás kezelése===
To enable the player to simply double click on a group name to expand/collapse it we need to use the [[onClientGUIDoubleClick]] event.
Annak engedélyezéséhez, hogy a játékos egyszerűen tudjon duplán kattintani a group nevére, hogy azt lenyissa/összecsukja az [[onClientGUIDoubleClick]] event-et kell használunk.
If we attach it to the gridlist, we can then catch any double clicks on the group names in it:
Ha ezt a gridlist-hez csatoljuk, akkor az összes dupla kattintást a group neveken észlelni tudjuk:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
-- attach the onClientGUIDoubleClick event to the gridlist and set it to call processDoubleClick
-- attach the onClientGUIDoubleClick event to the gridlist and set it to call processDoubleClick
addEventHandler("onClientGUIDoubleClick",gridlistVehicleSelection,processDoubleClick,false)
addEventHandler("onClientGUIDoubleClick",gridlistVehicleSelection,processDoubleClick,false)
</syntaxhighlight>
</syntaxhighlight>
Add this line of code in your createVehicleSelection, after the gridlist has been created.
Adja hozzá ezt a sort a createVehicleSelection-hoz, a létrehozott gridlist után.




As the gridlist items are not separate GUI elements, we must capture all clicks from anywhere on the gridlist then process them to filter out the ones we do not want.
Mivel a gridlist-ek nem önálló GUI elemek, ezért rögzítenünk kell az összes kattintást a gridlist-ről, majd feldolgozni, hogy kitudjuk szűrűni azt, amelyiket nem akarjuk figyelembe venni.
This can be done by checking if an item is selected, then checking if the item is one of our "group" values (using our previously mentioned "header" data):
Ezt megtehetjük egy kiválasztott elem ellenőrzésével, majd ellenőrizzük, hogy az elem az a mi egyik "group" értékünk (a korábban említett "header" adat használatával):
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function processDoubleClick(button,state)
function processDoubleClick(button,state)
Line 403: Line 402:
</syntaxhighlight>
</syntaxhighlight>


Once we have narrowed down the double clicks to only those done on our group headers, we can expand/collapse them appropriately.
Miután leszűkítettük a dupla kattintás, hogy csak a header-en történő kattintásra reagáljon, azután megfelelően tudjuk lenyitni/összecsuk őket.
This can be done by simply setting new text values in the gridlist according to the newly expanded/collapsed group, which creates the convincing illusion of collapsable menus.
Ez könnyen megtehető úgy, hogy új szövegértékeket adunk meg a gridlistben az újonnan lenyitott/összezárt csoportot figyelembe véve, ami azt a meggyőző illúziót kelti, hogy a menüelemek lenyitothatók/összezárhatók.




Note that much of the following code is reused from previous areas of this tutorial. While it is generally bad practice to clone sections of code in this way, for the purposes of this example it is far easier to understand.
Ne feledje, hogy a következő kódnak a nagy része újra felhasználásra került a tutorial előző részeiből. Bár általában ez rossz gyakorlat a kód részleteinek az ilyen módon történő másolása, ennek a példának a célja, hogy sokkal könnyebb legyen ezt megérteni.
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function changeGridlistState(group)
function changeGridlistState(group)
Line 456: Line 455:
</syntaxhighlight>
</syntaxhighlight>


This comletes the second section of the tutorial.
Ezzel be is fejeztük a tutoriál második részét.


For further GUI tutorials, see [[Scripting the GUI - Tutorial 2|Tutorial 2 (Gates and Keypads)]]
A további GUI tutoriálokért látogassa meg a [[HU/Scripting the GUI - Tutorial 2|GUI készítése - Tutorial 2 (Gates and Keypads)]] oldalt.


[[Category:GUI_Tutorials]]
[[Category:GUI_Tutorials]]


[[en:Scripting the GUI - Tutorial 1]]
[[en:Scripting the GUI - Tutorial 1]]
==Fordította==
'''2018.11.25.''' <font size="3">'''[https://wiki.multitheftauto.com/wiki/User:Surge Surge]'''</font>

Latest revision as of 12:53, 13 May 2019

GUI készítése - Tutorial 1 (Gridlists)

Ebben a tutoriálban fel fogjuk fedezni a gridlist-ek használatát egy járműválasztási kijelzőn egy tetszőleges kliensoldali jármű xml olvasással.

Ne feledje, hogy ez a tutoriál feltételezi azt, hogy tisztában van az előző tutoriálban bemutatott összes tartalommal


A jármű kiválasztásának létrehozása

A GUI 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.

Ebben a fájlban elfogjuk kezdeni megírni a saját function-ünket a GUI létrehozásához. Ahogy azt az előző tutoriálban említettük, a gui létrehozásakor 2 értéktípus közül tudunk választani: relative és absolute.

Ennek a tutoriálnak a céljából most absolute értékeket fogunk használni.


Ez létre fog hozni egy egyszerű GUI ablakot, egy gridlist-et, és egy gombot:

function createVehicleSelection()
	-- get the screen width and height
	local sWidth, sHeight = guiGetScreenSize()
	
	-- use some simple maths to position the window in the centre of the screen
	local Width,Height = 376,259
	local X = (sWidth/2) - (Width/2)
	local Y = (sHeight/2) - (Height/2)
	windowVehicleSelection = guiCreateWindow(X,Y,Width,Height,"Vehicle Selection Window",false)
	
	gridlistVehicleSelection = guiCreateGridList(10,26,357,192,false,windowVehicleSelection)
	-- add a "Vehicle" and a "Type" collumn to the gridlist
	guiGridListAddColumn(gridlistVehicleSelection,"Vehicle",0.2)
	guiGridListAddColumn(gridlistVehicleSelection,"Type",0.2)
	
	-- set the default width of the columns to roughly half the size of the gridlist (each)
	guiGridListSetColumnWidth(gridlistVehicleSelection,1,0.4,true)
	guiGridListSetColumnWidth(gridlistVehicleSelection,2,0.5,true)
	
	buttonCreate = guiCreateButton(121,227,120,20,"Create",false,windowVehicleSelection)
	
	-- add the event handler for when the button is clicked
	addEventHandler("onClientGUIClick",buttonCreate,createVehicleHandler,false)
	
	-- hide the GUI
	guiSetVisible(windowVehicleSelection,false)
	
	-- this will add all the vehicle options onto the gridlist, it is explained later in this tutorial
	populateGridlist()
end

Most ezt a function-t meg is kell hívnunk valamivel, különben a GUI sosem lesz létrehozva. Ahogy az előző tutoriálban is az onClientResourceStart-ot hívtuk segítségül, hogy elvégezze ezt a feladatot.

-- when the resource is started, create the GUI and hide it
addEventHandler("onClientResourceStart",getResourceRootElement(getThisResource()),
	function()
		createVehicleSelection()
	end
)

A GUI megjelenítése

Az előző tutoriállal ellentétben itt azt akarjuk, hogy a játékos képes legyen az ablakot megnyitni, amikor csak szeretné, és ne akkor, amikor a resource elindul. Így hozzáadhatunk egy parancsot ennek elvégzéséhez.

-- create the function that will show the window
function showVehicleSelection()
	-- if the window isnt visible, show it
	if not guiGetVisible(windowVehicleSelection) then
		guiSetVisible(windowVehicleSelection,true)
		
		showCursor(true,true)
	end
end

-- add the command /vehicleselection and set it to call the showVehicleSelection function
addCommandHandler("vehicleselection",showVehicleSelection)

A Gridlist feltöltése egy táblából

Most, hogy van egy alap GUI-nk, fel is kell töltenünk a gridlistet az összes járművünkel.

Ezt kezdésként egy egyszerű client oldali táblával fogjuk megcsinálni. A tutoriál későbbi részében ezt a módszert kibővítjük egy .xml fájl használatával az információk tárolásához. Kezdésként létrehozunk egy táblát, mely tartalmazza a kiválasztott járműveket, amelyeket majd le tudunk spawnolni.

A tábla tartalmazza a járműveket ebben a formában ["description"] = vehicle_id :

-- create the table and fill it with a selection of vehicle ids and names
local vehicleSelectionTable = {
	["Sparrow"] = 469,
	["Stuntplane"] = 513,
	["BF-400"] = 581,
	["Freeway"] = 463,
	["Speeder"] = 452,
	["Jester"] = 559,
	["Sabre"] = 475,
	["Police Ranger"] = 599,
	["Utility Van"] = 552,
	["Tug"] = 583
}

Helyezze ezt a kódot a script legtetejére (nem kell, hogy egy funkción belül legyen).

Most megírhatjuk a "populateGridlist" function, amely feltölti a Gridlist-et a táblázatban szereplő összes járművel. Ehhez egyszerűen csak végig kell mennünk a táblában szereplő értékeken, és hozzáadni a gridlist-hez. Valamint beállítjuk a rejtett adatokat a guiGridListSetItemData használatával, hogy tároljuk a járművek id-jét:

function populateGridlist()
	-- loop through the table
	for name,vehicle in pairs(vehicleSelectionTable) do
		-- add a new row to the gridlist
		local row = guiGridListAddRow(gridlistVehicleSelection)

		-- set the text in the first column to the vehicle name
		guiGridListSetItemText(gridlistVehicleSelection,row,1,name,false,false)
		-- set the text in the second column to the vehicle type
		guiGridListSetItemText(gridlistVehicleSelection,row,2,getVehicleType(vehicle),false,false)
		
		-- set the data for gridlist slot as the vehicle id
		guiGridListSetItemData(gridlistVehicleSelection,row,1,tostring(vehicle))
	end
end

A klikk kezelése

Most, hogy elkészült a GUI-nk, észlelnünk is kell minden kattintást a "Create" gombon. Már hozzácsatoltuk az onClientGUIClick event-et a buttonCreate-hez, így most meg kell írjuk azt a function-t, ami meghívja. Ebben a function-ben elvégzünk néhány alapvető hibaellenőrzést, mint például, hogy meggyőződjünk arról, hogy a jármű az a listából lett-e kiválasztva. Ezután használhatunk néhány számítási feladatot, hogy megtaláljuk a játékos pozícióját, majd elküldjök ezt az infórmációt a szervernek, hogy lespawnolja a járművet a játékos elé (triggerServerEvent használatával)

function createVehicleHandler(button,state)
	if button == "left" and state == "up" then
		-- get the selected item in the gridlist
		local row,col = guiGridListGetSelectedItem(gridlistVehicleSelection)
		
		-- if something is selected
		if row and col and row ~= -1 and col ~= -1 then
			-- get the vehicle id data from the gridlist that is selected
			local selected = guiGridListGetItemData(gridlistVehicleSelection,row,col)
			
			-- make sure the vehicle id is a number not a string
			selected = tonumber(selected)
						
			-- get the players position and rotation
			local rotz = getPedRotation(getLocalPlayer())
			local x,y,z = getElementPosition(getLocalPlayer())
			-- find the position directly infront of the player
			x = x + ( math.cos ( math.rad ( rotz+90 ) ) * 3)
			y = y + ( math.sin ( math.rad ( rotz+90 ) ) * 3)
			
			if selected and x and y and z then
				-- trigger the server
				triggerServerEvent("createVehicleFromGUI",getRootElement(),selected,x,y,z)
				
				-- hide the gui and the cursor
				guiSetVisible(windowVehicleSelection,false)
				showCursor(false,false)
			else
				outputChatBox("Invalid arguments.")
			end
		else
			-- otherwise, output a message to the player
			outputChatBox("Please select a vehicle.")
		end
	end
end

A jármű létrehozása

Ezen a ponton az összes szükséges client oldali kódunk már megvan, szóval nyisson meg egy szerver oldalu .lua fájlt, amivel majd dolgozni fog.

Mindenekelőtt a szerver oldalon meg kell adnunk egy egyedi event-et, amit már meghívtunk a client oldalról. Ezt megtehetjük az addEvent és az addEventHandler használatával. Végezetűl szükségünk lesz egy pici function-re, hogy létrehozzuk a járművet:

function createMyVehicle(vehicleid,x,y,z)
	-- check all the arguments exist
	if vehicleid and x and y and z then
		createVehicle(vehicleid,x,y,z)
	end
end

addEvent("createVehicleFromGUI",true)
addEventHandler("createVehicleFromGUI",root,createMyVehicle)

Vegye figyelembe a "root" változó használatát. Ez egy MTA változó, amely tartalmazza a root elemet; minden resource-nak van egy.

Ezzel be is fejeztük a tutoriál első részét. Mostanra rendelkeznie kell egy alap, működő jármű spawnoló script-el.

A második részben megnézzük a gridlist adatok kezelhetőségét, és a client oldali xml fájlok olvasását.

A kód bővítése

Ez a rész számos módon fogja részletezni a már meglévő kódunk fejlesztését.

Adatok importálása

Egy nagy előrehaladás az előző módszerhez képest, hogy külső fájlokat használunk a jármű információinak tárolásához, ez lehetővé teszi a számunkra, hogy gyorsabban és egyszerűbben kezeljünk nagy mennyiségű adatokat. Ebben a tutoriálban clinet oldali xml fájlt fogunk használni az információ tárolásához.

Mindenek előtt létre kell hoznia egy xml fájlt, szóval keresse meg a resource könyvtárát, és hozzon létre egy új vehicles.xml fájlt:

Ennek a tutoriálnak a céljából csak egy kis részét fogjuk felvenni a teljes járműkészletből, azonban a fájl könnyen bővíthető, így a későbbiekben majd az összeset hozzá fogjuk tudni adni

Ha még nem biztos az xml adatok felépítésében, akkor böngézhet a MTA xml function-ok között a további információkért.

<root>
	<group type="Bikes">
		<vehicle id="581" name="BF-400"/>
		<vehicle id="463" name="Freeway"/>
		<vehicle id="481" name="BMX"/>
	</group>
	<group type="Boats">
		<vehicle id="472" name="Coastguard"/>
		<vehicle id="452" name="Speeder"/>
	</group>
	<group type="Helicopters">
		<vehicle id="487" name="Maverick"/>
		<vehicle id="469" name="Sparrow"/>	
	</group>
	<group type="Planes">
		<vehicle id="593" name="Dodo"/>
		<vehicle id="513" name="Stuntplane"/>	
	</group>
	<group type="Sports Cars">
		<vehicle id="565" name="Flash"/>
		<vehicle id="559" name="Jester"/>
		<vehicle id="477" name="ZR-350"/>	
	</group>
	<group type="2-Door">
		<vehicle id="474" name="Hermes"/>
		<vehicle id="475" name="Sabre"/>
	</group>
	<group type="Emergency">
		<vehicle id="416" name="Ambulance"/>
		<vehicle id="599" name="Police ranger"/>
	</group>
	<group type="Industrial">
		<vehicle id="573" name="Dune"/>
		<vehicle id="552" name="Utility van"/>	
	</group>
	<group type="Misc">
		<vehicle id="457" name="Caddy"/>
		<vehicle id="583" name="Tug"/>
	</group>
</root>

Miután létrehozta a fájlt, ne felejtse el hozzáadni a resource meta.xml fájljához a megfelelő client taggal.

Vegye figyelembe a "type" tagot. Ez a groupon belüli járművek tetszőleges leírása, ami átnevezhető, vagy hozzáadható bármilyen szöveg. Hasonlóképenn a vehicle "name" tag is csak egy szöveges leírás a járműről, és nem kell, hogy a jármű valódi neve legyen.

Most, hogy rendelkezünk az adatokkal, importálni tudjuk a játékba és megjeleníteni a GUI-n. Ha követte ezt a tutoriált az első résztől kezdve, akkor ez az új kód a 'populateGridlist' function-ben lévő kódot cseréli ki. Először be kell töltenünk a fájlt:

function populateGridlist()
	-- load the file and save the root node value it returns
	local rootnode = xmlLoadFile("vehicles.xml")
	
	-- check that the file exists and has been correctly loaded
	if rootnode then		
		-- unload the xml file
		xmlUnloadFile(rootnode)
	end
end

Mindig bizonyosodjon meg arróla, hogy lezárta a fájlt, mikor már végeztél a szerkesztésével.


Most már elkezdhetjük az adatok gyűjtését, és hozzáadhatjuk a gridlist-hez. We can do this by looping through the xml data (in a similar manner to looping through the vehicle table earlier in this tutorial) and adding each entry into the list.

function populateGridlist()
	local rootnode = xmlLoadFile("vehicles.xml")
	
	if rootnode then		
		-- first, we find every "group" node (they are direct children of the root)
		for _,group in ipairs(xmlNodeGetChildren(rootnode)) do
			-- add a new row to the gridlist
			local row = guiGridListAddRow(gridlistVehicleSelection)

			-- get the group name
			local name = xmlNodeGetAttribute(group,"type")
			
			-- set the text in the first column to the group type and indicate it is a section ('true')
			-- (sections on gridlists show up in bold and cannot be clicked)
			guiGridListSetItemText(gridlistVehicleSelection,row,1,name,true,false)			
		
			-- then, for every group that we find, loop all of its children (the vehicle nodes)
			-- and add them into the gridlist
			for _,vehicle in ipairs(xmlNodeGetChildren(group)) do
				-- add a new row to the gridlist
				row = guiGridListAddRow(gridlistVehicleSelection)

				-- get the vehicle name and id
				name = xmlNodeGetAttribute(vehicle,"name")
				local id = xmlNodeGetAttribute(vehicle,"id")
				
				-- set the text in the first column to the vehicle name
				guiGridListSetItemText(gridlistVehicleSelection,row,1,name,false,false)
				-- set the text in the second column to the vehicle type
				guiGridListSetItemText(gridlistVehicleSelection,row,2,getVehicleType(tonumber(id)),false,false)		
				
				-- finally, set the vehicle id as data so we can access it later
				guiGridListSetItemData(gridlistVehicleSelection,row,1,tostring(id))
			end
		end	
	
		-- unload the xml file now that we are finished
		xmlUnloadFile(rootnode)
	end
end

Figyelje meg a for ciklus xmlNodeGetChildren függvénnyel való használatát a kódban. Ez sok időt, és energiát takarít meg nekünk, mivel nem kell manuálisan megírnunk minden egyes group-ot és járművet a listába.

Mostanra már rendelkeznie kell egy teljesen működő járműválasztási menüvel, amely minden adatot a client oldali xml fájlból olvas. Következőnek pedig megnézzük, hogy hogyan csináljuk meg a megjelenését a lenyíló részeknek a gridlistben.

A Gridlist megnyitása/összecsukása

A gridlistben lévő lenyitható menük lehetővé teszik, hogy egy sokkal átláthatóbb panelt készítsünk. Ezzel helyet takarít meg a képernyőn, és sokkal kényelmesebbé teszi az egész menüt.

Az adatok betöltése

Ennek a hatásnak az eléréshez (mivel ez nem a gridlisták természetes tulajdonsága) a járműinformációkat egy táblázatba kell betöltenünke (az xml fájlból), ahelyett, hogy közvetlenül a gridlist-be helyeznénk. Ha követte ezt a tutoriált az első résztől kezdve, akkor ez az új kód a 'populateGridlist' function-ben lévő kódot cseréli ki

Ez is ugyanúgy működik, mint az előző példában szereplő xml betöltési rész, csak ahelyett, hogy az adatokat a grlidlist-be mentenénk, helyette egy táblába mentjük el. Beállítjuk a "header" elementData-t is a gridlist cellákban, hogy meg tudjuk különböztetni, hogy melyik elem egy "group" és melyik egy jármű.

function populateGridlist()
	local rootnode = xmlLoadFile("vehicles.xml")
	
	-- create a blank global table to store our imported data
	vehicleTable = {}
	
	if rootnode then		
		for _,group in ipairs(xmlNodeGetChildren(rootnode)) do
			-- create an entry in the gridlist for every vehicle "group"
			local row = guiGridListAddRow(gridlistVehicleSelection)

			local name = xmlNodeGetAttribute(group,"type")
			
			guiGridListSetItemText(gridlistVehicleSelection,row,1,name,false,false)	

			-- add an entry containing the group name into the table
			vehicleTable[name] = {}
			
			-- we will use the custom data "header" to indicate that this entry can be expanded/collapsed
			guiGridListSetItemData(gridlistVehicleSelection,row,1,"header")	
		
			-- then, for every group that we find, loop all of its children (the vehicle nodes) and store them in a table
			for _,vehicle in ipairs(xmlNodeGetChildren(group)) do
				local vname = xmlNodeGetAttribute(vehicle,"name")
				local id = xmlNodeGetAttribute(vehicle,"id")			
			
				-- insert both the vehicle id and the vehicle description into the table
				table.insert(vehicleTable[name],{id,vname})
			end
		end	
	
		-- set element data on the gridlist so we know which group is currently showing
		setElementData(gridlistVehicleSelection,"expanded","none")
	
		-- unload the xml file now that we are finished
		xmlUnloadFile(rootnode)
	end
end

Most, hogy tároltuk az összes adatot, gyorsan kezelni is tudjuk, amikor szükséges.

Dupla kattintás kezelése

Annak engedélyezéséhez, hogy a játékos egyszerűen tudjon duplán kattintani a group nevére, hogy azt lenyissa/összecsukja az onClientGUIDoubleClick event-et kell használunk. Ha ezt a gridlist-hez csatoljuk, akkor az összes dupla kattintást a group neveken észlelni tudjuk:

-- attach the onClientGUIDoubleClick event to the gridlist and set it to call processDoubleClick
addEventHandler("onClientGUIDoubleClick",gridlistVehicleSelection,processDoubleClick,false)

Adja hozzá ezt a sort a createVehicleSelection-hoz, a létrehozott gridlist után.


Mivel a gridlist-ek nem önálló GUI elemek, ezért rögzítenünk kell az összes kattintást a gridlist-ről, majd feldolgozni, hogy kitudjuk szűrűni azt, amelyiket nem akarjuk figyelembe venni. Ezt megtehetjük egy kiválasztott elem ellenőrzésével, majd ellenőrizzük, hogy az elem az a mi egyik "group" értékünk (a korábban említett "header" adat használatával):

function processDoubleClick(button,state)
	if button == "left" and state == "up" then
		local row,col = guiGridListGetSelectedItem(gridlistVehicleSelection)
		
		-- if something in the gridlist has been selected
		if row and col and row ~= -1 and col ~= -1 then		
			-- if it is a header
			if guiGridListGetItemData(gridlistVehicleSelection,row,col) == "header" then
				local selected = guiGridListGetItemText(gridlistVehicleSelection,row,col)
				
				-- call the function to collapse or expand the menu and pass which section it is as an argument
				changeGridlistState(selected)
			end
		end
	end
end

Miután leszűkítettük a dupla kattintás, hogy csak a header-en történő kattintásra reagáljon, azután megfelelően tudjuk lenyitni/összecsuk őket. Ez könnyen megtehető úgy, hogy új szövegértékeket adunk meg a gridlistben az újonnan lenyitott/összezárt csoportot figyelembe véve, ami azt a meggyőző illúziót kelti, hogy a menüelemek lenyitothatók/összezárhatók.


Ne feledje, hogy a következő kódnak a nagy része újra felhasználásra került a tutorial előző részeiből. Bár általában ez rossz gyakorlat a kód részleteinek az ilyen módon történő másolása, ennek a példának a célja, hogy sokkal könnyebb legyen ezt megérteni.

function changeGridlistState(group)
	if group then
		-- if the group is already expanded, we want to collapse it
		if getElementData(gridlistVehicleSelection,"expanded") == group then
			-- first, we clear all previous data from the gridlist
			guiGridListClear(gridlistVehicleSelection)
			
			-- now, loop all the group entries in the vehicle table that we created earlier
			for group,_ in pairs(vehicleTable) do
				-- add each group to the list and mark them with "header"			
				local row = guiGridListAddRow(gridlistVehicleSelection)
				
				guiGridListSetItemText(gridlistVehicleSelection,row,1,group,false,false)	
				guiGridListSetItemData(gridlistVehicleSelection,row,1,"header")	
			end
			
			-- update the data to indicate that no groups are currently expanded
			setElementData(gridlistVehicleSelection,"expanded","none")
			
		-- otherwise, we want to expand it
		else
			guiGridListClear(gridlistVehicleSelection)
			
			local row = guiGridListAddRow(gridlistVehicleSelection)
			
			guiGridListSetItemText(gridlistVehicleSelection,row,1,group,false,false)	
			guiGridListSetItemData(gridlistVehicleSelection,row,1,"header")				
			
			-- loop every vehicle in the specified groups table
			for _,vehicle in ipairs(vehicleTable[group]) do
				-- add them to the gridlist and set the vehicle id as data
				row = guiGridListAddRow(gridlistVehicleSelection)
			
				-- format a "-" into the string to make it visually easier to distinguish between groups and vehicles
				guiGridListSetItemText(gridlistVehicleSelection,row,1,"- "..vehicle[2],false,false)	
				guiGridListSetItemText(gridlistVehicleSelection,row,2,getVehicleType(tonumber(vehicle[1])),false,false)	
											
				guiGridListSetItemData(gridlistVehicleSelection,row,1,tostring(vehicle[1]))
			end	

			-- update the data to indicate which group is currently expanded
			setElementData(gridlistVehicleSelection,"expanded",group)			
		end
	end
end

Ezzel be is fejeztük a tutoriál második részét.

A további GUI tutoriálokért látogassa meg a GUI készítése - Tutorial 2 (Gates and Keypads) oldalt.

Fordította

2018.11.25. Surge