Введение в скриптинг GUI: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
m (Начало перевода)
(Еще немного перевода)
Line 7: Line 7:
В этом руководстве мы сделаем простое окно авторизаци с двумя полями ввода и кнопкой. Окно появляется, когда игрок подключается к игре, и после того, как нажата кнопка, игрок респаунится. Это руководство - продолжение предыдущего ([[RU/Scripting Introduction|Введение в скриптинг]]). Теперь мы познакомимся с написанием клиентских скриптов.  
В этом руководстве мы сделаем простое окно авторизаци с двумя полями ввода и кнопкой. Окно появляется, когда игрок подключается к игре, и после того, как нажата кнопка, игрок респаунится. Это руководство - продолжение предыдущего ([[RU/Scripting Introduction|Введение в скриптинг]]). Теперь мы познакомимся с написанием клиентских скриптов.  


===Draw the window===
===Отрисовка окна===
All the GUI must be made client side. It is also a good practice to keep all the client scripts in a separate folder. Browse to /Your MTA Server/mods/deathmatch/resources/myserver/ directory, and create a folder named "client". Under /client/ directory, create a text file and name it "gui.lua", and in this file we will write a funtion that draws the window:
GUI работает на стороне клиента. Хорошим решением будет поместить все клиентские скрипты в отдельный каталог. Перейдите в каталог /Ваш сервер MTA/mods/deathmatch/resources/myserver/ и создайте подкаталог "client". В нём создайте текстовый файл и назовите его "gui.lua". В этом файле мы напишем функцию, отображающую окно:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function CreateLoginWindow()
function CreateLoginWindow()
Line 18: Line 18:
end
end
</syntaxhighlight>
</syntaxhighlight>
You may click on the function's name to read its documentation. Note that the coordinates of the window is in ''percentage'' of the screen. It means that if the screen is labelled with 0 on the left end, and 1 on the right end, and if "X" is 0.5, it represents the middle of the screen. It applies to Y, window width, and window height as well (if "width" is 0.5, the window will be half as wide as the screen). Next we'll add the text labels (saying "username:" and "password:"), edit boxes and a button. Replace the function with its complete version:
Вы можете кликнуть по имени функции, чтобы прочитать её описание. Заметьте, что координаты окна задаются в ''процентах'' от размеров экрана. Это значит, что левая граница экрана по ширине принимается за 0, а правая за 1, соответственно, "X" равное 0.5 обозначает середину экрана. Аналогично и для позиции по высоте, ширины и высоты окна (если "width" равно 0.5, окно будет в половину ширины экрана). Теперь мы добавим текстовые меткм (с надписями "username:" и "password:"), поля ввода и кнопку. Замените функцию её полной версией:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
function CreateLoginWindow()
function CreateLoginWindow()
Line 54: Line 54:
end
end
</syntaxhighlight>
</syntaxhighlight>
Note that every GUI component created is a child of the window, this is done by specifying the parent element (wdwLogin, in this case) when creating the component:
Обратите внимание на то, что каждый компонент интерфейса является дочерним по отношению к окну, это достигается указанием родительского элемента (wdwLogin, в данном случае) при создании элемента:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin)
guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin)
</syntaxhighlight>
</syntaxhighlight>
This is very useful because later when you need to control the entire set of GUI, you can just refer to the parent element. For example:
Это очень удобно, т.к. в дальнейшем, при отображении окна, можно обращаться только к родительскому элементу. К примеру:
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
guiSetVisible(wdwLogin, false) --hides all the GUI we made so we can show them to the player at the appropriate moment.  
guiSetVisible(wdwLogin, false) --прячет всё окно целиком так, что мы можем показать его игроку в любой момент.  
</syntaxhighlight>
</syntaxhighlight>



Revision as of 11:11, 13 April 2009

Одна из важных особенностей MTA:DM - возможность создания собственного GUI (графический пользовательский интерфейс). Графический интерфейс состоит из окон, кнопок, текстовых полей... Проще говоря, из всех стандартных компонент графических интерфейсов. Они могут использоваться пока пользователь в игре, и использоваться для ввода/вывода вместо команд.

Admin Console GUI

Руководство по созданию интерфейса авторизации

В этом руководстве мы сделаем простое окно авторизаци с двумя полями ввода и кнопкой. Окно появляется, когда игрок подключается к игре, и после того, как нажата кнопка, игрок респаунится. Это руководство - продолжение предыдущего (Введение в скриптинг). Теперь мы познакомимся с написанием клиентских скриптов.

Отрисовка окна

GUI работает на стороне клиента. Хорошим решением будет поместить все клиентские скрипты в отдельный каталог. Перейдите в каталог /Ваш сервер MTA/mods/deathmatch/resources/myserver/ и создайте подкаталог "client". В нём создайте текстовый файл и назовите его "gui.lua". В этом файле мы напишем функцию, отображающую окно:

function CreateLoginWindow()
	local X = 0.375
	local Y = 0.375
	local Width = 0.25
	local Height = 0.25
	wdwLogin = guiCreateWindow(X, Y, Width, Height, "Please Log In", true)
end

Вы можете кликнуть по имени функции, чтобы прочитать её описание. Заметьте, что координаты окна задаются в процентах от размеров экрана. Это значит, что левая граница экрана по ширине принимается за 0, а правая за 1, соответственно, "X" равное 0.5 обозначает середину экрана. Аналогично и для позиции по высоте, ширины и высоты окна (если "width" равно 0.5, окно будет в половину ширины экрана). Теперь мы добавим текстовые меткм (с надписями "username:" и "password:"), поля ввода и кнопку. Замените функцию её полной версией:

function CreateLoginWindow()
	local X = 0.375
	local Y = 0.375
	local Width = 0.25
	local Height = 0.25
	wdwLogin = guiCreateWindow(X, Y, Width, Height, "Please Log In", true)
	
	X = 0.0825
	Y = 0.2
	Width = 0.25
	Height = 0.25
	guiCreateLabel(X, Y, Width, Height, "Username", true, wdwLogin)
	Y = 0.5
	guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin)
	
	X = 0.415
	Y = 0.2
	Width = 0.5
	Height = 0.15
	edtUser = guiCreateEdit(X, Y, Width, Height, "", true, wdwLogin)
	Y = 0.5
	edtPass = guiCreateEdit(X, Y, Width, Height, "", true, wdwLogin)
	guiEditSetMaxLength(edtUser, 50)
	guiEditSetMaxLength(edtPass, 50)
	
	X = 0.415
	Y = 0.7
	Width = 0.25
	Height = 0.2
	btnLogin = guiCreateButton(X, Y, Width, Height, "Log In", true, wdwLogin)
	
	guiSetVisible(wdwLogin, false)
end

Обратите внимание на то, что каждый компонент интерфейса является дочерним по отношению к окну, это достигается указанием родительского элемента (wdwLogin, в данном случае) при создании элемента:

guiCreateLabel(X, Y, Width, Height, "Password", true, wdwLogin)

Это очень удобно, т.к. в дальнейшем, при отображении окна, можно обращаться только к родительскому элементу. К примеру:

guiSetVisible(wdwLogin, false) --прячет всё окно целиком так, что мы можем показать его игроку в любой момент. 

Using the function we wrote

The CreateLoginWindow function is done, but it won't do anything until we call it. It is recommended to create all GUI when the client resource starts, hide them, and show them to player later when needed. Therefore, we'll write an event handler for "onClientResourceStart" to create the window:

addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), 
	function ()
		CreateLoginWindow()
	end
)	

We would like to show the window when the client joins the game, using the same event "onClientResourceStart". Now the event handler looks like:

addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), 
	function ()
		CreateLoginWindow()

                outputChatBox("Welcome to My MTA DM Server, please log in.  ")

	        if (wdwLogin ~= nil) then
		         guiSetVisible(wdwLogin, true)
	        end 

	        showCursor(true)
	        guiSetInputEnabled(true)
	end
)	

Note that we have a security check before making the window visible, so that in case the window had not been created, in which case wdwLogin is not a valid element, we don't get an error. The showCursor function gives control to your mouse, and guiSetInputEnabled makes sure when you type in the GUI, certain letters like "A", "S", "D", "W", "T" don't move your character or bring out the chatbox input. In the next step, we'll make the button work as desired.

Scripting the button

When the player clicks on any part of the GUI, the event "onClientGUIClick" will be triggered for the GUI component you clicked on. For instance, if you click on the button, you can add the event handler attached to the button:

addEventHandler("onClientGUIClick", theButtonElement, theHandlerFunction, false)

In our script, we only need the event handler attached to the button. When it's clicked, the client will tell the server to spawn the player. Find the event handler code for "onClientResourceStart" from the previous section, and add the following line right AFTER CreateLoginWindow() is called:

addEventHandler("onClientGUIClick", btnLogin, clientSubmitLogin, false)

The event handler must be added here because it makes sure variable btnLogin contains the actual button. You cannot attach an event to an non-existant element. You should have noticed that we need the "clientSubmitLogin" function, as stated in the line above.

function clientSubmitLogin(button)
	if button == "left" then
		
		triggerServerEvent("SubmitLogin", getRootElement(), guiGetText(edtUser), guiGetText(edtPass))
		guiSetInputEnabled(false)
		guiSetVisible(wdwLogin, false)
		showCursor(false)
	end
end

The variable "button" is passed by the event handler, and it's a string with the name of the button (either "left" or "right"). Here we also hit a new concept, which is custom events. Custom events can be triggered by script from the same side (server to server, or client to client), or from the other side (server to client, or vice versa). Here we use the triggerServerEvent function to trigger a custom event on the server, "SubmitLogin".

At this point we have all the code needed on the client side. On the server side, recall that we are spawning the player as soon as they join, as shown below:

function joinHandler()
	local x,y,z
	x = 1959.55
	y = -1714.46
	z = 10
	spawnPlayer(source, x, y, z)
	fadeCamera(source, true)
	outputChatBox("Welcome to My Server", source)
end
addEventHandler("onPlayerJoin", getRootElement(), joinHandler)

However, since we are going to spawn the player when the button is clicked, we must replace the "onPlayerJoin" event with the custom event triggered by the client script. Replace the above code with the following:

function joinHandler(username, password)
	local x,y,z
	x = 1959.55
	y = -1714.46
	z = 10
        if (client) then
	      spawnPlayer(client, x, y, z)
	      fadeCamera(client, true)
	      outputChatBox("Welcome to My Server", client)
        end
end

addEvent("SubmitLogin", true)
addEventHandler("SubmitLogin", getRootElement(), joinHandler)

Note that the second arguement of addEvent function (the one with value "true") specifies whether the event can be triggered by the other side, therefore we need to turn it on since the client is triggering it. Also note the variable "client", it's an internal variable used by MTA to identify the player who triggered the event.

Finally, do not forget to include the new gui.lua file in the meta.xml of the main resource, and label it as a client script:

<script src="client/gui.lua" type="client" />

As to this point, we have a basic login window that spawns the player when the "login" button is clicked. You can also use the username and password submitted by the triggerServerEvent function to verify the player's identify before spawning him.