Yo pessoal, hoje vim falar sobre alcance horizontal de um movimento que possui uma trajetória em forma de parábola! Primeiramente, vamos falar pra que serve isso, para que vocês não precisem ler o tutorial inteiro para só depois descobrir para que serve xD
Bom, o que esse tutorial faz é descobrir a velocidade horizontal com a qual um helper ou o char vai até o alvo tendo uma velocidade vertical inicial e com gravidade constante.
Veja o exemplo nas imagens:
Ou seja, a velocidade horizontal do meu helper está mudando de acordo com a distância entre mim e o P2, de forma que ele vai chegar na posição onde o P2 está quando o helper atingir a altura da qual ele se iniciou!
Por exemplo, esse helper aparece na posição vertical -70, a posição diminui por causa da velocidade vertical inicial e depois aumenta por causa da gravidade.
Quando a altura do helper chegar novamente em -70, ele vai estar na posição em que o P2 estava no momento do lançamento do helper.
Agora vamos aprender a fazer isso:
Primeiramente, vamos considerar a trajetória parabólica de um objeto onde a atmosfera não interfere (ou seja, não há atrito):
A equação que define o movimento horizontal é a seguinte:
Onde "x-x₀" é a distância entre o objeto (char ou helper) e o P2, "V₀" é a velocidade inicial, "a" é a aceleração e "t" é o tempo.
Como a atmosfera não está interferindo, a aceleração é 0, assim, a parte "½at" é zerada, restando:
Agora, precisamos obter os valores para preencher essa equação!
Para obtermos a distância é muito simples, basta usar o trigger "P2Dist X"
Mas nós precisamos encontrar dois outros valores, são eles:
Tempo que o objeto demora para voltar a posição vertical de início;
Velocidade inicial do objeto. Como nós estamos variando a velocidade, então temos que encontrar o tempo!
Para isso, primeiro vamos começar a bolar o state, vou estar usando o que eu fiz como exemplo:
Code
[Statedef 6201]
Type = A
MoveType = A
Physics = N ;<- Atmosfera não interfere em nada
Anim = 6200
Ctrl = 0
SprPriority = 9
[State 6201, VelSet]
Type = VelSet
Trigger1 = !Time
X = 0 ;<-- Essa velocidade encontraremos depois
Y = -6 ;<-- Velocidade vertical será sempre a mesma e é ela que determina o tempo
[State 6201, VelAdd]
Type = VelAdd
Trigger1 = 1
Y = Const(Movement.YAccel) ;<-- Aplica a gravidade
[State 6201, ChangeState]
Type = ChangeState ;<-- ChangeState da forma que você quer
Trigger1 = MoveContact
Trigger2 = Pos Y >= 0
Value = 6202
Ctrl = 0
Pronto, montei o básico do state, agora, precisamos descobrir o tempo que o objeto leva para voltar a posição de início!
Para fazermos isso, precisaremos de uma variável que irá armazenar o valor do tempo e iremos modificar o changestate para mudar de state quando o objeto voltar a posição y de origem!
Então iremos acrescentar o seguinte VarSet no state:
Code
[State 6201, VarSet]
Type = VarSet ;<- Caso você esteja fazendo isso em um helper, use ParentVarSet ao invés de VarSet
Trigger1 = 1
V = 23 ;<- Variável que você deseja usar
Value = Time ;<- Estamos armazenando o tempo
Agora, vou modificar meu ChangeState:
Code
[State 6201, ChangeState]
Type = ChangeState
Trigger1 = Pos Y >= -70 ;<- Posição Y inicial
Trigger1 = Time ;<- Garante que o helper não mude de state assim que lançado
Value = 6202
Ctrl = 0
O code inteiro agora ficou:
Code
[Statedef 6201]
Type = A
MoveType = A
Physics = N
Anim = 6200
Ctrl = 0
SprPriority = 9
[State 6201, VelSet]
Type = VelSet
Trigger1 = !Time
X = 0
Y = -6
[State 6201, VelAdd]
Type = VelAdd
Trigger1 = 1
Y = Const(Movement.YAccel)
[State 6201, VarSet]
Type = VarSet
Trigger1 = 1
V = 23
Value = Time
[State 6201, ChangeState]
Type = ChangeState
Trigger1 = Pos Y >= -70
Trigger1 = Time
Value = 6202
Ctrl = 0
Pronto, agora que temos a variável armazenando o tempo, precisamos mostrar o tempo!
Para isso, usamos um DisplayToClipboard no statedef -2, caso você não tenha o statedef -2, basta criá-lo com a seguinte linha:
O DisplayToClipboard vai ficar assim:
Code
[State -2, DisplayToClipboard]
Type = DisplayToClipboard
Trigger1 = 1
Text = "Tempo = %d"
Params = Var(23) ;<- Variável utilizada pelo objeto
Após isso, salve e teste o char...
Com o MUGEN aberto, aperte ctrl+d para entrar no modo debug e veja o valor do Tempo e anote-o
No meu caso, o tempo é 27
Com o tempo em mãos, podemos apagar o DisplayToClipboard, o VarSet e retornar o ChangeState ao original, retornando ao código:
Code
[Statedef 6201]
Type = A
MoveType = A
Physics = N
Anim = 6200
Ctrl = 0
SprPriority = 9
[State 6201, VelSet]
Type = VelSet
Trigger1 = !Time
X = 0
Y = -6
[State 6201, VelAdd]
Type = VelAdd
Trigger1 = 1
Y = Const(Movement.YAccel)
[State 6201, ChangeState]
Type = ChangeState
Trigger1 = MoveContact
Trigger2 = Pos Y >= 0
Value = 6202
Ctrl = 0
Agora que temos o tempo em mãos, vamos voltar para a fórmula:
Agora nós temos a distância e o tempo, para calcular a velocidade teremos que mexer na fórmula!
Primeiramente, trocamos os membros da equação de lado:
Agora, como o tempo está multiplicando a velocidade inicial, passaremos ele para o outro lado, mas dividindo:
Pronto, temos agora a fórmula que acha a velocidade, temos a distância e temos o tempo!
Basta então mexermos no VelSet!
Lembrando:
"x-x₀" = P2Dist X
"t" = Tempo encontrado (no meu caso, 27)
O code vai ficar:
Code
[Statedef 6201]
Type = A
MoveType = A
Physics = N
Anim = 6200
Ctrl = 0
SprPriority = 9
[State 6201, VelSet]
Type = VelSet
Trigger1 = !Time
X = (P2Dist X)/27.0 ;<- Velocidade inicial
Y = -6
[State 6201, VelAdd]
Type = VelAdd
Trigger1 = 1
Y = Const(Movement.YAccel)
[State 6201, ChangeState]
Type = ChangeState
Trigger1 = MoveContact
Trigger2 = Pos Y >= 0
Value = 6202
Ctrl = 0
Pronto!
Agora é só testar, ver o resultado e acrescentar o que quizer no code, como HitDef, AfterImage ou seja lá o que vc precisa colocar xD!
Lembrando que, caso você deseje alterar a velocidade Y ou a gravidade, terá que calcular o tempo de novo xD
Espero que esse tutorial ajude o pessoal ai ^^
Créditos:
Professor Aldo Job (meu professor de física da faculdade xD)
Gnuplot (programa para desenhar gráficos)
GIMP (editor de imagens)