Movimento Personalizado de Fast Loops - Parte 2

Parte 2: Gravidade e Pulo

Introdução:
Aula passada, entendemos a essência do Movimento Personalizado de Fast Loops. Mas para fazer-se um movimento de plataforma, precisaremos criar eventos de gravidade. E, se o programador desejar, o que normalmente deseja, eventos de pulo. Normalmente? Sim, pois devemos observar que em certos tipos de jogos, não há como pular. Se bem que, nesse caso, um pré-definido bastaria.

Preparando o Terreno:
Aqui, criemos os seguintes objetos: alguns backdrops (chão, paredes e teto); uma Máscara de Colisão (novamente usemos 32x32, e chamemos-a de MC) com o hotspot na parte inferior-central; e um Detector de Colisão, com 1px de altura e a mesma largura da Máscara de Colisão, seu Hotspot posicionado na parte central-central.

Frame montado. Um chão, duas paredes e um teto, sem falar na Máscara de Colisão. Repare também no pequeno detector logo abaixo da Máscara de Colisão.

Se prestou atenção na aula anterior, deve estar se perguntando o porquê do detector, já que as colisões são reconhecidas pela Máscara de Colisão. Respondo em uma palavra: pulo. É verdade que existem outras formas de se fazer o pulo (através de uma flag, por exemplo), mas estou adotando essa não apenas por ser mais prática, como também para tentar ser fiel ao movimento original de David.

Em princípio (e em eventos também), é bastante simples: o detector deve sempre ficar 1px abaixo do personagem. Logo, podemos dizer que quando o detector está sobrepondo um obstáculo, a Máscara de Colisão está no chão. E se o personagem estiver no chão e o jogador pressionar o botão de pulo... o personagem pula.

Mas ainda não acabamos de preparar nosso terreno: ainda precisamos nomear as variáveis, exatamente como fizemos na aula anterior.

Variáveis nomeadas.

Agora sim, aos eventos.

Programando o movimento:
Acho desnecessário repetir toda a longa explicação sobre Movimentos Horizontais, já que vocês já devem dominá-los bem a essa altura. Afinal, já a fizeram em ambos os eixos apenas neste tipo de movimento; já trabalhamos com posições X e Y faz algum tempo.

Só devo acrescentar um pequeno detalhe aos eventos desta vez, que diz respeito ao nosso detector. Em todos os eventos em que ocorre de fato uma movimentação (são aqueles em que alteramos a posição da Máscara de Colisão, no caso, a posição X), adicione a seguinte ação:

Set position at (0,1) from ("MC")

Isto é, todas as condições que causam uma movimentação na Máscara de Colisão, devem causar uma movimentação também no detector. Entretanto, o movimento do detector não precisa ser específico; basta colocar-se para que movimente-se para baixo da Máscara de Colisão.

Deve ficar desse jeito. Esses dois eventos são os que fazem a Máscara de Colisão de fato se movimentar, pois mudam sua posição X.

Vamos programar, então, a gravidade e o pulo!

A) Manipulação de Variáveis
Antes de manipular as variáveis, tenha isto em mente: a variável MovY representa a gravidade.

Vamos definir a aceleração gravitacional. Faça o seguinte evento:

MovY of ("MC") < 10
Set MovY to MovY("MC")+0.5

Tal evento significa que, enquanto a gravidade for menor que 10, adicionaremos 0.5 a ela, para que chegue, gradualmente, a 10. Quando chegar em 10, ela para; isso serve para que quando o personagem pule de determinadas altitudes, a velocidade de queda seja limitada, para que ele não caia muito rápido. Logo, a cada centésimo de segundo, a velocidade varia em 0.5px a favor da trajetória (ela é orientada para baixo). Isso significa que 0.5 é a aceleração.

Você pode fazer com que a gravidade seja menor de duas formas: a primeira, é diminuindo a aceleração (0.5). A segunda, adicionando uma condição Every.

Pois bem. Vamos, então, ao pulo.

("Jogador 1") Pressed fire 1
("Detector") is overlapping a background
Set MovY to -10

Esse evento diz que, se o detector estiver sobrepondo um obstáculo (o que significa que o personagem está no chão) e o jogador pressionar a tecla de fogo 1, a variável da gravidade será definida para -10. Neste ponto, talvez, você não entenda o que isso significa. Mas é o que fará com que a Máscara de Colisão pule. E quanto menor o valor (pois é negativo), mais alto a Máscara de Colisão pulará. Em breve, entenderemos por que.

B) Loops de Movimentação
É aqui que é feito o movimento propriamente dito. Precisamos, antes de mais nada, definir a quantidade de vezes que o loop irá acontecer, de acordo com o valor da variável, assim, causando o movimento.

MovY of ("MC") <> 0
Start loop "MovY" Abs(MovY( "MC" ))

Ou seja, se a gravidade for diferente de 0, iniciará-se um loop. Tal loop será o "motor" para movimentação em si. A quantidade de vezes que o loop será executado é expressa pelo módulo da variável MovY. Isso porque não se pode executar um loop um número negativo de vezes =P.

Agora, começa a movimentação. Faremos com que o personagem se mova a favor da trajetória. Ou seja, caia.

On loop "MovY"
MovY of ("MC") > 0
(MC) Set Y position to Y( "MC" )+1
(DP) Set position at (0, 1) from ("MC")

Ou seja, enquanto o loop estiver sendo executado, se a gravidade for maior que 0 (valores positivos equivalem ao sentido para baixo, pois esta é a orientação da trajetória), define-se a posição Y da Máscara de Colisão para sua própria posição, adicionada a 1(px). Isso significa que enquanto o loop estiver sendo executado e a gravidade for positiva, a Máscara de Colisão irá cair. E o detector será posicionado em seu devido lugar, já que ele deve se mover sempre que a Máscara de Colisão se mover.

Faremos, agora, o inverso: que a Máscara de Colisão mova-se contra a trajetória. Isso significa... subir!

On loop "MovY"
MovY of ("MC") < 0
(MC) Set Y position to Y("MC")-1
(DP) Set position at (0, 1) from ("MC")

Enquanto o loop estiver sendo executado, se a gravidade for menor que 0 (valores negativos equivalem ao sentido para cima, pois este é o sentido oposto ao da trajetória), define-se a posição Y da Máscara de Colisão para a sua própria posição, subtraída de 1(px). Isso significa que enquanto a gravidade for negativa, o personagem irá subir. Por isso que no evento do pulo, definimos a variável para um valor negativo!

Entretanto, ele não ficará para sempre no ar, pois o primeiro evento que fizemos irá tratar de fazer a Máscara de Colisão descer. Se a gravidade é negativa, é menor que 10; logo, pelo primeiro evento que fizemos, ele irá adicionando 0.5 à gravidade, fazendo com que, gradualmente, o valor vá crescendo, até que a gravidade volte a ser positiva, e a Máscara de Colisão volte a cair.

Vamos fazer as colisões. Primeiro, vamos fazer com que a Máscara de Colisão colida com o teto:

On loop "MovY"
MovY of ("MC") < 0
("MC") is overlapping a backdrop
Stop loop "MovY"
(MC) Set Y position to Y("MC")+1
Set MovY to 0
(DP) Set position at (0, 1) from ("MC")

Ou seja, se enquanto o loop estiver sendo executado e a gravidade for menor que 0 (ou seja, a Máscara de Colisão estiver pulando), a Máscara de Colisão sobrepor um obstáculo, isso significa que ele é teto. Logo, devemos fazê-la descer, para que ela não atravesse o teto. Para isso, somamos 1 à sua posição (o que anula a subida), paramos o loop, e definimos o valor da variável MovY para 0. Estes dois últimos, como já expliquei, servem para que a Máscara de Colisão não "trave" no obstáculo ao colidir. Ah, claro, e posicionamos o detector também, para que ele se ajuste novamente.

Agora, colidir com o chão:

On loop "MovY"
MovY of ("MC") > 0
("MC") is overlapping a backdrop
Stop loop "MovY"
(MC) Set Y position to Y("MC")-1
Set MovY to 0
(DP) Set position at (0, 1) from ("MC")

O princípio é o mesmo. Anulamos o movimento somando um valor oposto, definimos a variável para 0, paramos o loop e posicionamos o detector. Só o que mudou agora, foi o sentido. Já que MovY é maior que 0, o personagem logicamente estará caindo, e o obstáculo que ele encontrará será o chão. Para que ele não atravesse o chão, fazemos com que ele suba 1px, ao mesmo tempo que desce 1px. Os dois, então, se anulam, e a Máscara de Colisão entra em repouso. Ao mesmo tempo, fazemos com que o loop pare e a gravidade (MovY) seja definida para 0.

--//--

E aí está! Um movimento de plataforma perfeito, sem bug algum, e completamente customizável. Agora, tente personalizá-lo ainda mais. Cria molas, pulos duplos, plataformas móveis, tudo o que puder imaginar! Vá testando sua imaginação, vendo se consegue fazer algo sozinho. Caso não tenha entendido algo, dê uma conferida neste exemplo, para ver onde errou.

Mas calma lá, ainda não acabamos... na próxima parte, ensinarei a fazer Slope e a configurar as animações. Para quem não sabe, Slope é a capacidade de andar em terrenos irregulares, como ladeiras. As animações... bem, vocês já deveriam saber fazer, mas ensinarei assim mesmo.

Bom aprendizado ;)
Flw.