PT-BR/Sistema de eventos: Difference between revisions
(Created page with "__NOTOC__ O sistema de eventos é essencial quando se desenvolve scripts para MTA. Os eventos trabalham juntamente com a árvore de elementos. O conceito de evento está pres...") |
mNo edit summary |
||
(2 intermediate revisions by one other user not shown) | |||
Line 38: | Line 38: | ||
===Propagação dos eventos=== | ===Propagação dos eventos=== | ||
Os eventos, quando emitidos, se propagam pelo que chamamos de [[Element_tree|árvore de elementos]]. Isso quer dizer que quando um evento é emitido para um determinado elemento, o mesmo evento é emitido para os elementos pais e os elementos filhos. Sendo assim, se você emite um evento no elemento | Os eventos, quando emitidos, se propagam pelo que chamamos de [[Element_tree|árvore de elementos]]. Isso quer dizer que quando um evento é emitido para um determinado elemento, o mesmo evento é emitido para os elementos pais e os elementos filhos. Sendo assim, se você emite um evento no elemento raíz da árvore de elementos, este evento será emitido para qualquer outro elemento existente (já que todos os elementos são filhos de root). | ||
Alguns exemplos podem explicar melhor. | Alguns exemplos podem explicar melhor. | ||
No exemplo abaixo, perceba que usamos '''getRootElement()''' no #addEventHandler. A função #getRootElement retorna o elemento | No exemplo abaixo, perceba que usamos '''getRootElement()''' no #addEventHandler. A função #getRootElement retorna o elemento raíz, que é pai de todos os outros. Sendo assim, o Event Handler será chamado sempre que '''qualquer''' carro no mapa explodir, já que todos os carros são filhos de root. | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
addEventHandler("onVehicleExplode", getRootElement(), function() | addEventHandler("onVehicleExplode", getRootElement(), function() | ||
Line 55: | Line 55: | ||
local vehicle = createVehicle(455, 0, 0, 0) | local vehicle = createVehicle(455, 0, 0, 0) | ||
addEventHandler("onVehicleExplode", vehicle, function() | addEventHandler("onVehicleExplode", vehicle, function() | ||
outputChatBox("Um veículo | outputChatBox("Um veículo específico acaba de explodir.") | ||
end) | end) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
===As variáveis ocultas do Event Handler=== | |||
Mais uma vez, para fixar: o Event Handler é aquela função que é chamada sempre que o evento é emitido. | |||
Todo Event Handler possui três "variáveis ocultas": | |||
* '''source''': é o elemento que originou o evento. | |||
* '''this''': é o elemento o qual o Event Handler é aplicado (por exemplo, o elemento que você usou no segundo parâmetro do addEventHandler). | |||
* '''eventName''': é uma string contendo o nome do evento que foi emitido (por exemplo, o nome que você usou no primeiro parâmetro do addEventHandler). | |||
<syntaxhighlight lang="lua"> | |||
-- Função chamada quando um jogador entra no veículo | |||
function onEnter(thePlayer, seat, jacked) | |||
-- Temos, além dos parâmetros, três variáveis ocultas: | |||
-- source: o veículo no qual o jogador entrou | |||
-- this: o elemento raíz (já que getRootElement() retorna isso) | |||
-- eventName: a string "onVehicleEnter", nome do evento | |||
end | |||
addEventHandler("onVehicleEnter", getRootElement(), onEnter) | |||
</syntaxhighlight> | |||
Adicionalmente, temos mais uma variável oculta quando o evento está no lado do servidor: | |||
* '''client''': é o cliente que emitiu o evento, quando o evento é acionado usando '''#triggerServerEvent()'''. Quando o evento não é chamado no cliente, a variável não é definida. | |||
A variável ''source'' é a mais importante na maioria das situações. Quase sempre que você quiser saber qual elemento originou o evento, vai precisar o valor da variável ''source''. | |||
É importante observar que os eventos seguem a hierarquia dos elementos (árvore de elementos). Isso quer dizer que todos os eventos são inicialmente emitidos no elemento de origem (source), e, em seguida, emitido por todos os elementos pais ou filhos. Esse comportamento tem algumas implicações importantes: | |||
* Um evento acionado no elemento raíz (por exemplo, quando se usa #getRootElement()) será acionado em todos os elementos da árvore. Portanto, o uso do elemento raíz deve ser evitado sempre que possível. | |||
* Todos os eventos em qualquer elemento da árvore será, no fim das contas, emitido no elemento raíz também. Portanto, se você precisar ouvir um evento para qualquer elemento de um determinado tipo, pode facilmente usar o elemento raíz. | |||
* Você pode atribuir um ''Event Handler'' no elemento raíz do seu ''resource'' para pegar todos os eventos emitidos pelos elementos do ''resource''. | |||
{{Note|Esta página ainda está em processo de tradução}} | |||
* You can create 'dummy' elements to catch events from a group of child elements | * You can create 'dummy' elements to catch events from a group of child elements | ||
* You can use dummy elements specified in a .map file (e.g. <flag>) and create 'real' representations for them (e.g. objects) and make these real elements children of the dummy element. Event handlers can then be attached to the dummy element and it will receive all the events of the real elements. This is useful for when one resource manages the representation of the element (creating the objects, for example), while another wants to handle special events. This could be a map resource that wants to handle a flag being captured in a specific way - the map resource would (generally) not be aware of the way the flag is represented. This doesn't matter as it can just attach handlers to it's dummy flag element while the other gamemode resource can handle the representation. | * You can use dummy elements specified in a .map file (e.g. <flag>) and create 'real' representations for them (e.g. objects) and make these real elements children of the dummy element. Event handlers can then be attached to the dummy element and it will receive all the events of the real elements. This is useful for when one resource manages the representation of the element (creating the objects, for example), while another wants to handle special events. This could be a map resource that wants to handle a flag being captured in a specific way - the map resource would (generally) not be aware of the way the flag is represented. This doesn't matter as it can just attach handlers to it's dummy flag element while the other gamemode resource can handle the representation. | ||
Line 94: | Line 110: | ||
Events can be canceled with [[cancelEvent]]. This can have a variety of effects, but in general this means that the server will not perform whatever action it would usually do. For example, canceling [[onPickupUse]] would prevent a player being given what they tried to pick up, canceling [[onVehicleStartEnter]] would prevent the player entering the vehicle. You can check if the currently active event has been canceled using [[wasEventCanceled]]. It's important to note that canceling event ''does not'' prevent other event handlers being triggered. | Events can be canceled with [[cancelEvent]]. This can have a variety of effects, but in general this means that the server will not perform whatever action it would usually do. For example, canceling [[onPickupUse]] would prevent a player being given what they tried to pick up, canceling [[onVehicleStartEnter]] would prevent the player entering the vehicle. You can check if the currently active event has been canceled using [[wasEventCanceled]]. It's important to note that canceling event ''does not'' prevent other event handlers being triggered. | ||
[[Category:Scripting Concepts]] | [[Category:Translated/Scripting Concepts]] | ||
[[es:Sistema de eventos]] | [[es:Sistema de eventos]] | ||
[[pt-br:Sistema de eventos]] | [[pt-br:Sistema de eventos]] |
Latest revision as of 20:33, 21 February 2021
O sistema de eventos é essencial quando se desenvolve scripts para MTA. Os eventos trabalham juntamente com a árvore de elementos.
O conceito de evento está presente não apenas no MTA, mas em vários lugares quando o assunto é programação. Um evento é chamado sempre que algo acontece - um jogador entra em um marcador, um jogador entra em um veículo, um elemento é clicado, um veículo explode e etc.
Sempre que, ao desenvolver um script, você pensar: "quando X acontecer, eu devo fazer Y", significa que você está pensando em eventos. "X" é um evento. "Quando o jogador morrer, eu devo mostrar uma mensagem no chat" significa que você precisa do evento que é emitido sempre que um jogador morre.
O MTA já possui vários eventos nativos que podem ser consultados em Eventos do Servidor e Eventos do Cliente. Mas você também pode criar os seus próprios eventos, se necessário.
Todo evento tem um source. O source (origem) é o elemento que originou o evento. O source pode ser um jogador, um marcador, um pedestre, um veículo e etc. Todo evento tem um source diferente, portanto, você consegue ver qual o source de um evento na página específica daquele evento.
Os manipuladores de eventos
Manipuladores de eventos são funções. Simples assim.
Sempre que um evento é emitido, o MTA percorre todos os recursos (resources) que estiverem rodando no seu servidor procurando pelos "manipuladores de eventos".
Os manipuladores de eventos (também conhecidos como Event Handlers) são funções simples que são chamadas sempre que aquele evento é emitido. Como os manipuladores de eventos são escritos por você, programador, você pode fazer o que quiser nestas funções.
Você liga um manipulador de evento a um evento usando o addEventHandler.
function myFunction() -- Aqui, dentro de #myFunction, podemos fazer o que quisermos. -- Podemos escrever mensagens, podemos criar um veículo, podemos spawnar o jogador em algum lugar... outputChatBox("Um novo player acabou de se conectar.") end -- Usando addEventHandler, nós dizemos que sempre que o evento "onPlayerConnect" for emitido, a função #myFunction() deve ser executada addEventHandler("onPlayerConnect", getRootElement(), myFunction)
-- Também podemos declarar uma função direto no #addEventHandler, que é chamada quando "onVehicleExplode" for emitido addEventHandler("onVehicleExplode", getRootElement(), function() outputChatBox("Socorro! Um veículo acaba de explodir! \o/") end)
Propagação dos eventos
Os eventos, quando emitidos, se propagam pelo que chamamos de árvore de elementos. Isso quer dizer que quando um evento é emitido para um determinado elemento, o mesmo evento é emitido para os elementos pais e os elementos filhos. Sendo assim, se você emite um evento no elemento raíz da árvore de elementos, este evento será emitido para qualquer outro elemento existente (já que todos os elementos são filhos de root).
Alguns exemplos podem explicar melhor.
No exemplo abaixo, perceba que usamos getRootElement() no #addEventHandler. A função #getRootElement retorna o elemento raíz, que é pai de todos os outros. Sendo assim, o Event Handler será chamado sempre que qualquer carro no mapa explodir, já que todos os carros são filhos de root.
addEventHandler("onVehicleExplode", getRootElement(), function() outputChatBox("Um veículo qualquer acaba de explodir.") end)
Já no exemplo abaixo, temos uma pequena modificação: agora, no #addEventHandler, nós não usamos mais o #getRootElement. Ao invés disso, nós usamos a variável vehicle que, por sua vez, possui como valor um veículo específico que nós criamos.
Sendo assim, o Event Handler só será chamado quando esse nosso veículo específico explodir. Diferente do exemplo anterior, que chamava o Event Handler sempre que qualquer veículo explodisse.
local vehicle = createVehicle(455, 0, 0, 0) addEventHandler("onVehicleExplode", vehicle, function() outputChatBox("Um veículo específico acaba de explodir.") end)
As variáveis ocultas do Event Handler
Mais uma vez, para fixar: o Event Handler é aquela função que é chamada sempre que o evento é emitido.
Todo Event Handler possui três "variáveis ocultas":
- source: é o elemento que originou o evento.
- this: é o elemento o qual o Event Handler é aplicado (por exemplo, o elemento que você usou no segundo parâmetro do addEventHandler).
- eventName: é uma string contendo o nome do evento que foi emitido (por exemplo, o nome que você usou no primeiro parâmetro do addEventHandler).
-- Função chamada quando um jogador entra no veículo function onEnter(thePlayer, seat, jacked) -- Temos, além dos parâmetros, três variáveis ocultas: -- source: o veículo no qual o jogador entrou -- this: o elemento raíz (já que getRootElement() retorna isso) -- eventName: a string "onVehicleEnter", nome do evento end addEventHandler("onVehicleEnter", getRootElement(), onEnter)
Adicionalmente, temos mais uma variável oculta quando o evento está no lado do servidor:
- client: é o cliente que emitiu o evento, quando o evento é acionado usando #triggerServerEvent(). Quando o evento não é chamado no cliente, a variável não é definida.
A variável source é a mais importante na maioria das situações. Quase sempre que você quiser saber qual elemento originou o evento, vai precisar o valor da variável source.
É importante observar que os eventos seguem a hierarquia dos elementos (árvore de elementos). Isso quer dizer que todos os eventos são inicialmente emitidos no elemento de origem (source), e, em seguida, emitido por todos os elementos pais ou filhos. Esse comportamento tem algumas implicações importantes:
- Um evento acionado no elemento raíz (por exemplo, quando se usa #getRootElement()) será acionado em todos os elementos da árvore. Portanto, o uso do elemento raíz deve ser evitado sempre que possível.
- Todos os eventos em qualquer elemento da árvore será, no fim das contas, emitido no elemento raíz também. Portanto, se você precisar ouvir um evento para qualquer elemento de um determinado tipo, pode facilmente usar o elemento raíz.
- Você pode atribuir um Event Handler no elemento raíz do seu resource para pegar todos os eventos emitidos pelos elementos do resource.
- You can create 'dummy' elements to catch events from a group of child elements
- You can use dummy elements specified in a .map file (e.g. <flag>) and create 'real' representations for them (e.g. objects) and make these real elements children of the dummy element. Event handlers can then be attached to the dummy element and it will receive all the events of the real elements. This is useful for when one resource manages the representation of the element (creating the objects, for example), while another wants to handle special events. This could be a map resource that wants to handle a flag being captured in a specific way - the map resource would (generally) not be aware of the way the flag is represented. This doesn't matter as it can just attach handlers to it's dummy flag element while the other gamemode resource can handle the representation.
The function you attached to an event gets called and passed a bunch of arguments. These arguments are event-specific. Each event has specific parameters, for instance onClientGUIClick has 4 parameters, which are:
string button, string state, int absoluteX, int absoluteY
The function you attached to this event will be passed these parameters as arguments. You must remember that each event has different parameters.
Built in events
MTA has a number of built in events. These are listed on the pages Client Scripting Events and Scripting Events.
Custom events
You can create your own events that can be triggered across all resources. This is an important way to communicate with other resources and allow them to hook into your code. To add your own custom event, just call the addEvent function. You can then use the triggerEvent function to trigger that event any time you want - either using a timer, or based on a more general event.
For example, you could be making a Capture the Flag game mode and want to trigger an event when a player captures the flag. You could do this by attaching a event handler to the standard MTA onMarkerHit event and checking that the player entering the marker has the flag. if they do, you can then trigger your more specific onFlagCaptured event and other resources could handle this as they please.
Canceling
Events can be canceled with cancelEvent. This can have a variety of effects, but in general this means that the server will not perform whatever action it would usually do. For example, canceling onPickupUse would prevent a player being given what they tried to pick up, canceling onVehicleStartEnter would prevent the player entering the vehicle. You can check if the currently active event has been canceled using wasEventCanceled. It's important to note that canceling event does not prevent other event handlers being triggered.