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
» Procuro Programador de game maker
por Wou Sex 15 Mar 2024, 10:27

» Retorno da GMBR!!!
por vinians Qui 14 Mar 2024, 19:07

» Mod APK
por gamerainha Qua 13 Mar 2024, 06:30

» Mudar cor de apenas uma palavra
por lunalol Sex 01 Mar 2024, 13:42

» Aceito pedidos de sprites (Com exemplos meus)
por Sevilha Qua 28 Fev 2024, 12:17

» Inventário simples
por Isquilo_Roedor Qui 22 Fev 2024, 15:18

» Problemas na programaçnao de inimigo [jogo DOOM LIKE]
por Black Mirror Dom 11 Fev 2024, 13:34

» ANDROID MULTI TOUCH
por DiegoBr Dom 04 Fev 2024, 12:13

» Servidor de Discord do fórum?
por Lighter Sáb 27 Jan 2024, 17:18

» Save e Load Json
por Klinton Rodrigues Qui 25 Jan 2024, 11:12

» Colisão com mais de um objeto
por aminaro Seg 22 Jan 2024, 15:02

» Oi sou novo aqui
por Thiago Silveira Alexandre Sáb 20 Jan 2024, 20:55

» Como acessar conteudo comprado no marketplace
por macmilam Sex 19 Jan 2024, 07:42

» Devlogs em vídeos do Block Room
por Joton Seg 15 Jan 2024, 16:56

» Alguém aqui já ganha dinheiro com seus games?
por Joton Seg 15 Jan 2024, 16:49

» ACERVO GMBR MAGAZINE
por Joton Qui 11 Jan 2024, 19:21

» como aumentar o obj sem aumentar a colisão??
por GabrielXavier Qua 10 Jan 2024, 07:21

» Asteroid Core - Early Acesse Update [0.2.0.0]
por JOZ. Seg 08 Jan 2024, 14:39

» Versionamento de código com GitHub
por GabrielXavier Seg 08 Jan 2024, 07:32

» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por kolesovsup Sex 29 Dez 2023, 07:16

» a funçao approach ainda existe?
por PEDRINDEV Ter 26 Dez 2023, 20:05

» Inimigo ataca até por trás! >:(
por saim Sex 22 Dez 2023, 08:55

» [RESOLVIDO]Spawn após morte
por Deception_1999 Dom 17 Dez 2023, 16:39

» Remunerado $$$ - Procuro programador para ajudar a "montar" um jogo
por theguitarmester Sáb 02 Dez 2023, 16:28

» Game maker nao abre
por Cerf Dom 26 Nov 2023, 12:01


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


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