PT-BR/Introdução OOP
Nota: Se você contribuiu editando e ajustando esta página do fórum, se você se beneficiou deste tutorial ou se você tem algo a dizer; por favor, me dê um feedback no link do fórum fornecido abaixo.
Este é um tutorial de script que explica o que é programação orientada a objetos e ensina como usar os recursos de OOP (Programação Orientada a Objetos) do MTA. Isso foi originalmente criado por qaisjp (discussão) às 22h48min de 8 de junho de 2014 (UTC). Post no fórum.
Introdução à OOP
OOP (ou POO) significa programação orientada a objetos. Três palavras simples e você provavelmente entenderá a última palavra mais. OOP é quando todas as funções relacionadas a uma única instância são chamadas nessa instância, sendo uma instância uma criação de uma classe - uma classe de elementos, uma classe de banco de dados, um jogador, um veículo. Originalmente, tudo era procedural, você tinha que fazer coisas como:
local veiculo = createVehicle(411, 0, 0, 3) setVehicleDamageProof(veiculo, true) setElementFrozen(veiculo, true) setElementHealth(veiculo, 1000) setElementVelocity(veiculo, 0.2, 0.2, 0.2) destroyElement(veiculo)
Muitas vezes, você sabe com o que está lidando. A variável quase sempre está ligada ao tipo, você nomearia um veículo que explodiu como veiculoExplodido, ou pelo menos no contexto você entenderia que explodido implica um veículo quando no evento onVehicleExplode. Então, você tem que escrever uma função longa e referenciar o veículo manualmente ao trabalhar de maneira procedural. Doloroso. A programação orientada a objetos é muito diferente disso e trabalha com cada "objeto" individualmente. Em vez de ter que chamar uma função e referenciá-la dentro da chamada, você na verdade chama a função DENTRO da classe.
Você provavelmente pensa que tudo o que você pode criar e passar para funções são elementos. Um veículo é um elemento. Um jogador é um elemento. Tudo o que é um elemento também é uma classe. Conexões criam uma instância de uma classe, mas "conexão" não é um elemento, é uma instância - um objeto. Ao longo do tutorial, quando eu digo objeto, não me refiro a createObject (a menos que eu realmente mencione), mas para deixar as coisas mais claras, vou evitar mencionar objetos físicos enquanto escrevo este artigo. Aqui está um diagrama de Venn elegante que criei para mostrar a organização simples de classes e elementos. 500px|esquerda|diagrama de Venn As funções à esquerda são organizadas para mostrar em qual categoria o valor retornado se encaixa. Temos Classes, Elementos e "Problemas". Problemas não são categorias reais escritas no código, apenas funções que quebram regras. Tudo com que você pode brincar são classes: recursos, veículos e equipes.
Todos os elementos são classes, você pode fazer:
destroyElement(ped)
mas você não pode fazer:
destroyElement(resource)
Problemas são coisas estranhas. Você não pode fazer todas as funções mencionadas em (na verdade, todos os elementos não permitem a gama completa de funções a serem aplicadas a eles, mas mencionei especialmente algumas delas) na seção "Funções de Elemento" da lista de funções, mas você pode usar destroyElement() neles. Existem filhos de classes, por exemplo, com jogadores, o sistema funciona assim: "Elemento -> Pedestre -> Jogador". Todos os Jogadores são Pedestres e todos os Pedestres são Elementos. Nem todos os Pedestres são Jogadores, e certamente nem todos os Elementos são Jogadores. O ponto principal aqui é que quase tudo o que você pode criar ou recuperar e reutilizar posteriormente usa uma classe.
Em vez do código anterior, o código poderia ser substituído por este:
local veiculo = createVehicle(411, 0, 0, 3) veiculo:setDamageProof(true) veiculo:setFrozen(true) veiculo:setHealth(1000) veiculo:setVelocity(0.2, 0.2, 0.2) veiculo:destroy()
Funciona de maneira bastante similar a como uma tabela funciona, é como customTable.setAlgo(), exceto que o uso de : faz o Lua converter customTable.setAlgo() para customTable.setAlgo(customTable). Isso é uma coisa interna sobre açúcar sintático e você não precisa se preocupar muito com isso.
Essas funções são bastante úteis, mas há mais mudanças com OOP, explicarei isso abaixo.
Instanciação, variáveis
OOP remove a necessidade de dizer a parte "criar" da função, então em vez de dizer createVehicle, você apenas diz Veiculo. Funciona exatamente da mesma maneira, é quase como fazer Veiculo = createVehicle. Legal, não é? A única diferença aqui é que você perde as coisas extras oferecidas, Veiculo não tem essas coisas extras, mas Jogador definitivamente tem. Por exemplo, em vez de fazer getPlayerFromName(), você faria Player.getFromName(). É uma maneira agradável e simples de organizar funções.
Dica: Vehicle() funciona porque na verdade acessa a função createVehicle, isso permite omitir o .criar quando se está simplesmente "criando um objeto" |
Como a OOP se baseia na programação procedural, muitas coisas foram herdadas do estilo procedural, mas para facilitar as coisas, temos variáveis para todas as funções que exigem uma única entrada. Encurtamos getElementDimension() para elemento:getDimension(), mas também podemos ir um nível mais profundo: elemento.dimension. Sim, como uma variável normal. Você pode definir essa variável como uma variável normal e ler dela como uma variável normal. Ei, vocêpoderia até fazer isso:
function incrementarDimensao() local jogador = Player.getRandom() -- pega um jogador aleatório jogador.dimension = jogador.dimension + 1 -- incrementa a dimensão end setTimer(incrementarDimensao, 60*1000, 10) -- define um temporizador para sessenta mil milissegundos, sessenta segundos, um minuto
Esse código pegaria um jogador aleatório e o moveria para a próxima dimensão a cada minuto pelos próximos dez minutos.
Vetores
player.position também funciona! Mas como você muda três argumentos... usando uma variável? Vetores. Vetores são classes muito poderosas e vêm em várias formas, para este introdução, vou abordar um vetor tridimensional em termos de elementos. Usar um vetor é muito simples e, é claro, opcional. Onde você pode usar posições atualmente, você pode usar um vetor.
Portanto, este é um exemplo simples de criar um veículo e movê-lo para o centro do mapa usando vetores:
-- Primeiro, crie um vetor tridimensional local posicao = Vector3(300, -200, 2) -- algum lugar distante local veiculo = Vehicle(411, posicao) -- crie um veículo na posição veiculo.posicao = centreOfMap - Vetor3(300, -200, 0) -- mova o veículo duas unidades acima do centro do mapa
Sim, usei o sinal negativo. Vetores não são apenas maneiras elegantes de lidar com posições ou rotações 3D ou qualquer coisa assim, você pode fazer cálculos matemáticos com eles. A matemática especial ainda não foi documentada, mas vou tentar trabalhar nisso. Portanto, como você pode ver na linha um, criei um vetor 3D em 300, -200, 2 e na linha dois criei o veículo nessa posição.
veiculo.position retornou um vetor e também aceita um vetor - é praticamente setElementPosition() sem o "()". Apenas uma variável simples; então, na linha três, eu mudei o valor do vetor da posição do veículo. É aqui que a matemática aconteceu, em termos simples é isso que está acontecendo:
x = 300 - 300 y = -200 - -200 z = 2 - 0
A matemática de vetores é um pouco complicada, mas definitivamente permite uma grande variedade de mágicas matemáticas. Confira os links úteis abaixo relacionados a Vetores e Matrizes (Matrizes = forma plural de Matriz) para entender mais sobre como isso funciona.
Entendendo a documentação
A documentação para a sintaxe de OOP tem a intenção de ser muito simples e é suportada pela sintaxe procedural. Para simplificar as coisas, tudo é formatado de maneira consistente de certa forma.
OOP Syntax Help! I don't understand this!
- Note: Defina a variável como nula para executar removePedFromVehicle
- Method: ped:warpIntoVehicle(...)
- Variable: .vehicle
- Counterpart: getPedOccupiedVehicle
Às vezes, uma nota é adicionada à página. Isso explicará quaisquer diferenças especiais no uso de OOP para essa função. Os métodos podem começar com player: ou Player. - o primeiro é apenas para uma função em uma instância (setElementHealth) e o último é um método estático (getRandomPlayer). A seção de contraparte permite ver rapidamente como a variável pode ser usada. Na maioria dos casos, isso pode ser inferido a partir da página da função. Se você é um contribuidor do wiki, considere também ler o modelo de OOP.
Links úteis
Outras páginas relacionadas úteis sobre OOP:
OOP Vetor Matriz Categoria:OOP Categoria:Incompleto Categoria:Tutoriais
Translated by: Sousateew (Original)