quarta-feira, 21 de dezembro de 2011

[saim] Um olhar sobre as variáveis

Qualidade
Nome: Um olhar sobre as variáveis
Blogueiro: saim
Descrissao: Notei que alguns usuários estão com dificuldades com relação ao endereçamento de variáveis. Existem aulas para iniciantes que tocam no assunto, mas não vão a fundo. Minha intenção com esse tutorial é dirimir qualquer dúvida que possa vir a existir nesse assunto. Apesar do nível do tutorial ser bem básico, recomendo a usuários intermediários que também dêm uma olhada, pois algumas nuances podem ficar despercebidas por toda uma vida. Obviamente, eu também posso deixar passar alguns detalhes ou errar em alguma informação, portanto se você notar alguma falha, peço que informe, para que o tutorial fique completo.
Versao: Lite e Pro
Foto(s): (desnecessario por ser uma explicaçao)


Tutorial:

Introdução:
Variáveis são a base da programação. Tudo é baseado em variáveis. A posição de um objeto na tela é definido pelas variáveis "x" e "y". A forma como ele é desenhado é definida pelas variáveis "sprite_index" e "image_index". O Game Maker tem uma série de variáveis nativas (ou seja, já vêm definidas pelo programa) e você pode definir uma infinidade de variáveis próprias. Pra fazer um objeto se mexer, você usa variáveis. Pra testar uma colisão, outras variáveis são computadas. Para disparar um raio lazer enquanto estiver deslizando na parede e fazer com que ele reflita em um espelho posicionado no ângulo tal que atinja a cabeça (e não o torso) de um inimigo... você provavelmente precisará de dezenas ou até centenas de variáveis.
É impossível fazer um jogo sem usar nenhuma variável. O game maker está aberto? Se sim, então já existem diversas variáveis definidas.

O que são variáveis:
Variáveis são valores que, ao contrário das constantes, podem variar. Sim, é uma explicação idiota, mas a mais precisa possível. Mas tem mais.
Algumas variáveis podem ser alteradas pelo programador, ao passo que outras, uma vez definidas, ficam estáticas. Sim, algumas variáveis não variam, mas ainda assim são chamadas de variáveis. Alguns exemplos são aquelas definidas para se referir a algum recurso, seja ele uma instância de objeto, índice do objeto, som, script, room, etc. Elas têm valores gerados sequencial e automaticamente que podem ser usados como referência, mas não alterados.
Não sei ao certo, mas provavelmente são assim chamadas por adquirirem valores diferentes para cada recurso.

Tipos de variáveis:
Existem dois tipos de variáveis: texto e número real (string e real). No game maker, não é necessário declarar o tipo de variável que você está usando, apenas declare a variável e o programa saberá de que tipo se trata. Lembre-se, apenas, de usar aspas ao declarar variáveis de texto. Por exemplo "20", com aspas, é um texto e 20, sem aspas, é um valor numérico.

Booleanas:
Variáveis booleanas (que têm esse nome por causa de seu criador, George Boole - Valeu, Markituh) recebem apenas dois tipos de valores: true (verdadeiro) e false (falso). Na prática, esses valores são 1 (true, verdadeiro) e 0 (false, falso). Você pode usar 1 e 0 para se referir às booleanas. Você pode até esquecer que 1 significa verdadeiro e 0 significa falso, se quiser (embora essa informação seja muito útil na hora de raciocinar seus códigos). Isso faz das booleanas um sub-tipo do tipo "número real".

[dicas]
- Booleanas também podem ser usadas como números. Algumas funções retornam valores booleanos. Esses valores podem ser usados como 0 e 1.
- usar "!" antes da booleana inverte seu valor. "0" passa a ser "1" e "1" passa a ser "0".
corolário: você pode usar essas informações para economizar muitas linhas de código, em alguns casos.
gravity=!place_meeting(x,y+1,obj_chão)*0.5
// "gravity" (gravidade) é uma variável nativa que altera outra variável nativa, a "speed" (velocidade),
// que, por sua vez, altera ainda outra variável nativa, a posição do objeto
x+=(keyboard_check(vk_right)-keyboard_check(vk_left))*2
// "keyboard_check" é uma função que verifica se a tecla está apertada
// "vk_right" significa "seta para a direita" e "vk_left" significa "seta para a esquerda"
// ambas são constantes nativas e seus valores são, respectivamente, 39 e 37
[/dicas]

Declaração e escopo de uma variável:
Não existe mistério algum em declarar uma variável, no game maker. Basta digitar seu nome, um sinal de igual (=) e o valor, logo em seguida.
variavel=valor
O mistério todo reside em definir seu escopo.
A resposta para muitos erros de programação reside em compreender o escopo de uma variável. Basicamente, uma variável pode ser local ou global. Uma variável local existirá somente nas instâncias em que ela for declarada. Uma variável global existirá em todos os locais do jogo, a partir do momento em que ela for declarada.
Existem duas formas de declarar uma variável global. O primeiro, mais popular, consiste em digitar "global.", antes do nome da variável. Para usar esse método, é imprescindível que sempre seja usado o texto "global." antes do nome da variável, seja para declará-la, alterar seu valor ou referir-se a ele. Esse método tem a vantagem de deixar bem claro quais variáveis são globais e quais são locais. A desvantagem é que é muito chato digitar "global." toda vez que quiser se referir a uma variável.
global.variável=valor
O outro método requer que, antes de declarar a variável, você a apresente ao programa como global. Você digita, numa linha, "globalvar", o nome da variável, um ";". Na linha seguinte, a variável já será global, bastando declarar seu valor. Muito parecida com as variáveis "var", a serem apresentadas a seguir.
globalvar variável;
variável=valor

Existem, ainda, as variáveis "var". Variáveis "var" são as únicas que precisam ser apresentadas ao programa antes de serem declaradas. Para declarar uma variável "var", usamos a seguinte sintaxe:
var variável;
variável=valor

Elas têm a particularidade de serem apagadas da memória ao fim do código. Pra que serve uma variável que será apagada ao final do código, ou seja, não será usada em outros eventos? Pra muita coisa.
- pra ser usada como um contador
- pra armazenar resultados de equações complexas, que poderá ser usado repetidas vezes no mesmo código (como o delta da equação de báskara).
- pra armazenar o retorno de alguma função (como a id de uma instância, por exemplo), que poderá ser usado para se referir àquele resultado.
A vantagem de usar uma variável var é que ao final do código, você pode esquecer da existência dela sem prejuízos à programação. Esquecendo que ela existe, você pode usar o mesmo nome de variável para fins completamente distintos. Por exemplo, a mesma variável var pode ser usada como valor numérico no create event e como valor de texto no draw event. Quer dizer, o mesmo nome de variável. A variável será outra, porque sendo uma var, ela será apagada da memória, no final de cada evento.


Variáveis em outras instâncias:
[pausa]
Lembra que para usar uma variável global, podemos usar "global." antes da variável? Deixa eu te contar um segredo: "global" é um objeto persistente especial do game maker. "persistente" significa que ele existe em todas as rooms, ainda que você não o coloque lá.
Sério, global é um objeto especial. A id dele é "-5". Você pode substituir "global" por "-5" e testar. Funciona.
Os objetos especiais que eu conheço e suas id's são:
self: -1
other: -2
all: -3
noone: -4
global: -5
local: -7
Cada um deles tem características próprias. Legal, né? Qualquer dia a gente toma uma cerveja e fala mais sobre isso.
[/pausa]
Suponhamos que você tenha um personagem que corra contra o tempo em cada fase. Cada fase tem um tempo diferente pra ser cumprida e o personagem deve morrer se esse tempo chegar a zero. O mais sensato é definir esse tempo em um objeto controlador e, no personagem, checar se esse tempo chegou a zero e, em caso positivo, iniciar a sequência de morrer. Mas "tempo" não é uma variável global nem está dentro do personagem, então como fazer para o personagem saber se "tempo" chegou a zero ou não? Você indica, no lugar em que for se endereçar à variável, qual o objeto em que ela está. Como, no caso, seria o obj_controle, o código do personagem seria mais ou menos assim:
if obj_controle.tempo==0
tem_que_morrer=true

Suponha, agora, que exista mais de um obj_controle na fase, cada um com uma variável "tempo" de valor diferente. Difícil adivinhar qual valor será retornado pelo código acima, certo? A princípio pode ser qualquer um (na verdade, será o do primeiro objeto criado, mas isso foge do assunto). Então precisamos definir a INSTANCIA que controlará o tempo do objeto. Suponha que você precise considerar apenas a variável do último obj_controle que o personagem tocou.
Você irá armazenar a instância do último objeto tocado numa variável e usar essa variável como forma de endereçamento.
//no evento de colisão com obj_controle:
meu_controle=other //other, num evento de colisão, é o outro objeto
//no evento step:
if meu_controle.tempo==0
tem_que_morrer=true

Claro que, se "meu_controle" não estiver definido logo que o objeto for criado, o jogo retornará um erro do primeiro step até aquele em que houver a primeira colisão, onde a variável será definida. Existem várias formas de se contornar esse problema, que não são o assunto em questão.

Se você quiser testar, pode colocar, no create event:
tem_que_morrer=false //essa variável também será usada, então tem que ser inicializada
meu_controle=obj_controle //isso escolhe uma instância do objeto (a primeira criada) e evita a ocorrência de erros.
// na primeira colisão, a variável será atualizada

Lembre-se de colocar, no draw_event:
draw_sprite(sprite_index,image_index,x,y)
draw_text(x,y,string(tem_que_morrer))
draw_text(x,y,string(meu_controle.tempo))

Senão você não verá nenhum resultado

Bom, acho que consegui extenuar o assunto. Caso exista algum aspecto do assunto que não foi abordado ou que não tenha ficado claro, por favor, comente. Fiz o tutorial na intenção de eliminar qualquer dúvida a respeito de variáveis. Se ainda houver alguma, após a leitura do mesmo, ele está incompleto e precisa ser atualizado.

Abraços

saim.

Creditos: saim

Nenhum comentário:

Postar um comentário