GMBR
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Entrar

Esqueci-me da senha

Últimos assuntos
» player não consegue andar
por lovn7 Qui 21 Nov 2024, 13:33

» É possível fazer istó no game maker
por William Lima Qui 21 Nov 2024, 10:56

» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por Lua Sáb 16 Nov 2024, 20:22

» (Resolvido) Cenario longo x Texture Pages
por josuedemoraes Sáb 16 Nov 2024, 15:31

» Kids' band
por Adilson Lucindo Santos Sex 15 Nov 2024, 12:23

» (RESOLVIDO) Engasgos-Troca de Sprites/animações
por josuedemoraes Ter 12 Nov 2024, 01:49

» Block Room - DEMO
por Joton Qua 06 Nov 2024, 22:58

» Game Infinito vertical (subindo)
por macmilam Sáb 26 Out 2024, 12:36

» Retorno da GMBR!!!
por Dancity Ter 22 Out 2024, 16:36

» Máquina de estados
por aminaro Qui 10 Out 2024, 13:33

» como faço pra um objeto colidir com o outro e diminuir a vida do player ?
por josuedemoraes Qui 03 Out 2024, 16:51

» RESOLVIDO: Colisão com objetos moveis
por josuedemoraes Qua 02 Out 2024, 20:28

» Crypt of the Blood Moon
por divin sphere Qua 11 Set 2024, 18:18

» como fazer um objeto seguir?
por divin sphere Dom 18 Ago 2024, 18:08

» Procuro de alguém para Modelar/Texturizar/Animar objetos 3D
por un00brn Dom 11 Ago 2024, 11:10

» Destruição de cenário (estilo DD Tank)
por CoronelZeg Sex 09 Ago 2024, 17:16

» RESOLVIDO-Como destruir uma instancia especifica de um objeto
por josuedemoraes Ter 23 Jul 2024, 00:40

» Automatizar a coleta de id
por GabrielXavier Seg 22 Jul 2024, 18:01

» Preciso de ajuda para concluir um pequeno projeto
por lmoura Qui 27 Jun 2024, 15:45

» ANGULO ACOMPANHAR O OBJETO
por Klinton Rodrigues Qui 27 Jun 2024, 08:34

» Musica reinicia quando sala reinicia
por GabrielXavier Ter 18 Jun 2024, 07:28

» como fazer uma copia de gd
por generico_cube Sex 14 Jun 2024, 15:48

» Square Adventure
por guilherme551 Ter 11 Jun 2024, 09:54

» como posso definir limite de uma variavel
por GabrielXavier Sex 07 Jun 2024, 14:14

» [Resolvido] Dúvida, colisão única de objeto
por vdm842 Sex 24 maio 2024, 09:50


Utilizando vetores nos movimentos

Ir para baixo

Utilizando vetores nos movimentos Empty Utilizando vetores nos movimentos

Mensagem por Thiago_o_programador Dom 10 Jun 2018, 21:28

Título: Utilizando vetores nos movimentos
Versão do GM: a partir do 6
Dificuldade: Fácil
Link para download da Engine

Vetores

Mas o que realmente são vetores? Bem, não é um conceito difícil. Você pode pensar em um vetor como uma seta. Algumas grandezas só precisam de um número para ser descritas, como a massa, a altura ou o seu nível de satisfação com este post, em uma escala qualquer. São as grandezas escalares. Mas outras grandezas precisam de uma intensidade (módulo, magnitude ou norma), uma direção e um sentido, por exemplo, a velocidade, aceleração ou uma força. São as grandezas vetoriais.

No Game Maker (GM) um ponto qualquer da Room pode ser definido como o par ordenado A(x, y). Se você tomar um outro ponto, digamos, B(x', y'), existe um vetor AB cuja norma é a distância entre A e B, a direção é a mesma da reta suporte desse segmento e o sentido é "de A para B". Note que A e B são pontos genéricos. Um vetor, falando de uma forma mais formal, é o conjunto de todos os segmentos de mesma norma, mesma direção e mesmo sentido. Se A(0, 5), B(0, 10), C(20, 30) e D(20, 35), então AB e CD representam o mesmíssimo vetor, porque a norma, a direção e o sentido de AB e CD são os mesmos (respectivamente, 5, perpendicular ao eixo X e de baixo para cima). Você também pode encontrar as coordenadas de um vetor fazendo a diferença entre a extremidade e a origem. P. ex.: AB = B - A = (0, 10) - (0, 5) = (0, 5) e CD = D - C = (20, 35) - (20, 30) = (0, 5). Notou como AB e CD representam o mesmo vetor?

Você pode somar vetores simplesmente somando suas coordenadas. P. ex.: considere os vetores v (2, 5) e u(4, 8). Então v + u = (2 + 4, 5 + 8) = (6, 13). Não existe subtração entre vetores. Mas a notação v - u é utilizada para somar v com o oposto do vetor u, que tem a mesma norma e direção, mas o sentido contrário. O procedimento é análogo. (Note que se AB = v e BC = u, então AB + BC = AC).

Existem muitas outras operações interessantes envolvendo vetores, mas essa noção já basta para o que irei apresentar aqui.

Entendi. E daí?

Na física, em especial, na Mecânica clássica, os vetores são fundamentais no estudo do movimento. Isso porque eles não definem dois pontos, mas um conjunto de pontos que variam com o tempo. Isso quer dizer que se tivermos um objeto, digamos, uma bola, e aplicarmos um vetor horizontal, da esquerda para a direita, com intensidade 5, então a cada instante (step) sua posição irá variar 5 pixels, criando um movimento lateral. Se adicionarmos um segundo vetor perpendicular ao primeiro com intensidade inicial igual a 10, de baixo para cima, os vetores irão se somar e o resultado será um movimento em linha reta 5 pixels para a esquerda e 10 pixels para cima a cada instante. Adicionando ainda um terceiro vetor de intensidade .5, também vertical, mas de cima para baixo, a resultante será um vetor oblíquo que descreve um movimento de salto com movimento lateral em um arco perfeito.

Quer ver como isso funciona na prática? Vamos colocar a mão na massa!

Plataforma

Crie um objeto qualquer. Eu criei um com sprite de bola, daquelas que já vêm nos sources do GM. Agora, no evento Create, declare as variáveis:

Código:
vet[1] = 0;
vet[2] = 0;
vet[3] = .5;

lim = room_height - sprite_height*.5;

Os três vet significam os módulos dos vetores que usaremos. O "lim" é o limite inferior da room, para impedir que a nossa pseudo-gravidade atue indefinidamente. Naturalmente, você pode criar um objeto para ser o chão e adicionar uma colisão clássica.

Agora, no evento Step, as definições de movimento:

Código:
/*Adicionando uma magnitude ao vetor v[1]. Note que isso implica na criação
de um vetor-aceleração paralelo a v[1], cuja atuação se limita a |v[1]| < 6*/
if keyboard_check(vk_right) {
    if vet[1]<6 then vet[1] += 2;
};
if keyboard_check(vk_left) {
    if vet[1]>-6 then vet[1] -= 2;
};
//Adicionando uma magnitude ao vetor v[2]
if keyboard_check_pressed(vk_up) {
    if y = lim then vet[2] = 10;
};

//Aplicando uma desaceleração quando nenhuma tecla de movimento for pressionada
if !(keyboard_check(vk_right)||keyboard_check(vk_left))&&y = lim {
    if abs(vet[1]) > 0 {//previnindo uma divisão por zero
        vet[1] -= 2*vet[1]/abs(vet[1]);
        /*Abs(x) é uma função muito útil que retorna um valor positivo para qualquer
        variável. E.: abs(10) = 10 e abs(-30) = 30. É o módulo matemático.*/
    };
};
image_angle -= vet[1];
//Note que v[3] altera o módulo de v[2] para menos, logo:
vet[2] -= vet[3];
//Já o v[2] altera a posição vertical, no eixo y, até o limite inferior
y -= vet[2];
if y > lim {
    y = lim;
    vet[2] = 0;
};
//Enquando o vet[1] altera a posição horizontal, no eixo x
x += vet[1];

Observe que o módulo dos vetores às vezes vão ficar negativos, o que, do ponto de vista matemático é absurdo, mas aqui o GM interpreta como uma mudança de sentido. Por exemplo, se o vetor AB tem módulo -5, então o GM interpreta como o vetor BA de módulo 5. Em via de regra, o módulo de um vetor partindo da origem é a raiz da soma dos quadrados de suas coordenadas, por este motivo ele não pode ser negativo.

Pois bem, se você ainda não conseguiu enxergar os vetores nessa brincadeira, vamos desenhá-los no evento Draw:

Código:
//Vetor horizontal
draw_arrow(x,y,x + vet[1]*6,y,10);
//Vetor vertical
draw_arrow(x,y,x,y - vet[2]*6,10);
//Vetor resultante, v[1] + v[2]
draw_arrow(x,y,x + vet[1]*6,y - vet[2]*6,10);
//onde x e y são a origem do sistema

draw_sprite_ext(sprite_index,image_index,x,y,image_xscale,image_yscale,image_angle,noone,image_alpha);
Eu tomei a liberdade de aumentar o comprimento das setas 6x em relação aos vetores reais, isso para facilitar a vizualização.
Utilizando vetores nos movimentos Screen11

Você, como um bom observador, sem dúvida notou que os vetores v[1] e v[2] fazem exatamente a mesma coisa que as variáveis canônicas hspeed e vspeed, respectivamente. Elas são perfeitamente coincidentes. O que nós fizemos aqui foi recriar essas variáveis para que você conseguisse enxergar o tratamento vetorial nelas.

Naturalmente, os vetores não se limitam a isso. Qualquer movimento ou projeção exige um tratamente vetorial. Vamos a outro exemplo.

Movimento Circular

Eu peguei um sprite de meteoro - chamado spr_meteoro - e criei um objeto. Vamos fazer um sistema binário com centro de gravidade mútuo. Parece difícil, mas com vetores fica bem fácil, veja só.

Utilizaremos o tempo todo conceitos do Movimento Circular Uniforme (você lembra das aulas de Física, não lembra?). E adivinha qual é a principal descrição desse tipo de movimento? Vetorial.
No Create, declare as variáveis:
Código:
//O vetor que representa a velocidade linear
vet[1] = 10;
dir[1] = pi/2;
//O vetor da aceleração centrípeta
vet[2] = .4;
dir[2] = pi;
//A origem do sistema, que também será o nosso centro de gravidade
Ox = room_width*.5;
Oy = room_height*.5;

Antes de prosseguirmos, é bom ter em mente o que é Aceleração Centrípeta. No exemplo anterior, a gravidade alterava a magnitude do nosso vetor que descrevia o movimento vertical. Mas a aceleração centrípeta não altera o módulo do vetor velocidade linear aqui, em vez disso, ele altera a direção desse vetor. Dessa forma, a velocidade é constante e a variação da direção provoca o movimento circular.

No Draw, adicione:
Código:
var w,R;
//determinando o Raio do círculo descrito pelo movimento
R = sqr(vet[1])/vet[2]
//determinando a velocidade angular pela relação Act = w^2 * R
w = sqrt(vet[2]/R);
//Alterando a direção do vetor V[1]
dir[1] += w;
dir[2] = dir[1] + pi/2
//Aplicando um efeito bacana
image_angle = radtodeg(dir[1]*3)

//Primeiro meteoro
x = Ox + cos(dir[1])*R;
y = Oy - sin(dir[1])*R;
draw_sprite_ext(spr_meteoro,0,x,y,image_xscale,image_yscale,image_angle,noone,image_alpha);
//Vetor velocidade linear
draw_arrow(x,y,x + cos(dir[1]+pi/2)*vet[1]*6,y - sin(dir[1]+pi/2)*vet[1]*6,10);
//Vetor A. Centrípeta (Muito provavelmente não será desenhado)
draw_arrow(x,y,x + cos(dir[2]+pi/2)*vet[2]*6,y - sin(dir[2]+pi/2)*vet[2]*6,10);

//Definindo um reflexo (basta trocar os sinais)
var x1, y1;
x1 = Ox - cos(dir[1])*R;
y1 = Oy + sin(dir[1])*R;
draw_sprite_ext(spr_meteoro,0,x1,y1,image_xscale,image_yscale,-image_angle,noone,image_alpha);
draw_arrow(x1,y1,x1 + cos(dir[1]+3*pi/2)*vet[1]*6,y1 - sin(dir[1]+3*pi/2)*vet[1]*6,10);
draw_arrow(x1,y1,x1 + cos(dir[2]+3*pi/2)*vet[2]*6,y1 - sin(dir[2]+3*pi/2)*vet[2]*6,10);

Você pode ser um cara mais organizado do que eu e colocar os cálculos no evento Step.
Note que para vetores paralelos aos eixos x e y, as transformações são mais simples. Mas quando o ângulo muda, precisa pedir ajuda à Trigonometria. Lembrando que as funções trigonométricas do GM trabalham com radianos, por isso achei legal já declarar tudo nessa unidade. Para mais informações sobre Trigonometria, veja este post.

O resultado é um sistema binário entre dois cometas que dividem um centro de gravidade.
Utilizando vetores nos movimentos Screen10

Em resumo, vetores são poderosas ferramentas matemáticas que, bem usadas, podem descrever movimentos suaves de uma forma simples e, o melhor, sem bugs.
Thiago_o_programador
Thiago_o_programador

Games Ranking : Nota D

Notas recebidas : D - C - D - C
Data de inscrição : 14/05/2009
Reputação : 7
Número de Mensagens : 713
Prêmios : Utilizando vetores nos movimentos Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 1

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos