Obrigado por visitar a The Game Makers Brasil 😁 Use o fórum de Dúvidas para fazer perguntas. Se está em busca de aprender dê uma olhada nos tutoriais.

[FIS] Usando física no GM:S - Parte 3 (Oficial)

Tutoriais, videoaulas, guias e downloads para te ajudar nos estudos.
Avatar do usuário
All-x
Administrador
Administrador
Reações: 8
Mensagens: 621
Localização: Dourados-MS

Contato:

[FIS] Usando física no GM:S - Parte 3 (Oficial)

Mensagem por All-x » Qui Mai 26, 2016 5:24 pm

USANDO FÍSICA NO GAMEMAKER: STUDIO - PARTE 3
Autor original: Mark Alexander
Nesta última parte da série sobre a física no GameMaker: Studio, vamos explorar os Joints (articulações), funções avançadas de física e como desenhar o debug (depuração) do sistema de física. Se você ainda não viu as partes anteriores desta série, você pode encontrá-las clicando nos seguintes links:

Usando Fisica no GMS Parte 1

Usando Fisica no GMS Parte 2

CONFIGURANDO O PHYSICS WORLD

Neste artigo, nós vamos começar tudo do zero, então crie um novo projeto chamado "physics_joints" ou algo similar. Agora adicione uma room, e deixe a cor de fundo como cinza escuro ou preto (você verá o porque mais tarde), em seguida, feche o editor de rooms. Nós não vamos usar a aba "Physics" no editor para configurar a física da room neste momento, mas em vez disso, vamos fazê-lo via código.

Crie um novo objeto agora e chame de " obj_Control ", em seguida, adicione o evento Create com o seguinte código:

Código: Selecionar todos

// Conversão - Pixels para metros
physics_world_create (0.1); 

//Nenhuma gravidade
physics_world_gravity (0, 0); 

// iterações por step
physics_world_update_iterations (20); 

// Velocidade de atualização
physics_world_update_speed (60); 
As duas primeiras linhas são as mesmas opções que temos no editor de rooms para fixar quantos metros equivalem a 1 pixel e o vector de gravidade (que, neste caso é definido como 0 para tornar as coisas mais simples), mas as duas últimas são ligeiramente mais complexas e não aparecem no editor de rooms.

A primeira lida com as  iterações de atualização. Este valor é o número de vezes que a física irá percorrer as colisões e movimento etc a cada step. Então, aqui estamos afirmando que a simulação de física deve percorrer tudo 20 vezes por step. Esta é uma função muito poderosa, pois significa que você pode fazer a simulação mais ou menos precisa, definindo isso para um valor maior ou menor.

O segundo é a velocidade de atualização. Este é o número de steps de atualização por segundo que a simulação física irá rodar. Normalmente, este valor é igual ao da velocidade da room, mas você pode configurá-lo para um valor superior ou inferior para aumentar ou diminuir a precisão da física. Por exemplo, uma room tem velocidade de trinta steps por segundo e uma atualização de física sendo de 60 forçará a simulação de física para executar uma atualização  duas vezes para cada etapa do jogo. Note que isto é independente da velocidade de iteração, e irá ser acumulado com ele, ou seja, uma velocidade iteração de 20 e uma velocidade de atualização de 60 em uma sala de 30 fps vai dar 40 iterações por etapa.

Em geral, você não vai querer usar essas funções (e elas estão aqui apenas para mostrar como funcionam, mas elas não são estritamente necessárias para esta demonstração), mas se você tiver um jogo que requer movimento muito rápido, então você pode querer mais iterações, ou se você tiver um jogo que tem um vários corpos físicos, não vai requerer tanta precisão, você pode diminuir a velocidade de atualização e reduzir a sobrecarga na CPU.

Nossa próxima tarefa é criar limites na nossa room (Criar uma reação ao sair da room), ou seja, vamos fazer com que os objetos rebatam caso saiam dos limites da room, para isso adicione o código:

Código: Selecionar todos

var edge_fix physics_fixture_create = ();
physics_fixture_set_chain_shape (edge_fix, true);
physics_fixture_add_point (edge_fix, 0, 0);
physics_fixture_add_point (edge_fix, room_width, 0);
physics_fixture_add_point (edge_fix, room_width, room_height);
physics_fixture_add_point (edge_fix, 0, room_height);
physics_fixture_set_density (edge_fix, 0);
physics_fixture_set_restitution (edge_fix, 0.5);
physics_fixture_bind (edge_fix, id);
physics_fixture_delete (edge_fix);
Se você seguiu estes tutoriais desde o inicio, você deve reconhecer este código como sendo semelhante ao que foi utilizado para a definição de um fixture poligonal. A diferença desta vez é que estamos usando ele para criar um fixture estático, que é especialmente feita a partir de uma série de fixtures para representar as beiradas da room. Note que isso só vai funcionar porque a instância do "obj_Controlador" é posicionada em (0,0) na room. Se você colocá-lo em outro lugar, então não vai funcionar bem.

USANDO O MODO DE DEPURAÇÃO

Outra coisa que vamos usar neste exemplo é a depuração (debug mode) do nosso sistema de física. Você pode chamar a função physics_world_draw_debug () para fazer o GM:S desenhar valores físicos, como o shape do fixture os ângulos de rotação, joints, etc ... e nesta demonstração vamos usar esta função para desenhar os shapes dos fixtures em vez usar sprites sprites (Tecnicamente, você pode codificar um jogo inteiro sem sprites e desenhá-la usando esta função! No entanto, isso não vai ficar tão bonito xD ...).

Esta função tem um argumento único que é uma máscara de bits. Coisas diferentes podem ser processadas, definindo o sinalizador apropriado para mascarar ou desmascará-los, por isso precisamos definir esse valor no Evento Create do objeto de controlador (DICA: Veja o tutorial sobre algebra boolena do Carlos L):

Código: Selecionar todos

render_flags = phy_debug_render_shapes | phy_debug_render_joints | phy_debug_render_coms | phy_debug_render_obb;
Você pode encontrar uma lista completa das constantes disponíveis a partir do manual

Para desenhar o debug da física precisamos adicionar agora um evento Draw com este código:

Código: Selecionar todos

physics_world_draw_debug (render_flags);
Agora, quando adicionarmos instâncias com fixtures para a nossa room, eles serão desenhados por esta função.

CRIAÇÃO DE INSTÂNCIAS

Estamos quase prontos para começar a adicionar instâncias com fixtures na nossa room, mas antes disso, temos de fazer um objeto "base". Nós vamos criar todas as instâncias e fixtures usando códigos, mas precisamos de um objeto para criar instâncias já anexadas com os fixtures, então crie um novo objeto agora e chame de "obj_Base". Você precisará adicionar um  evento de colisão com ele mesmo contendo um único comentário para garantir que as colisões vão acontecer.

Imagem

Podemos agora volte ao nosso objeto controlador e atribua o "obj_Base" como seu parent (Aquele evento de colisão será herdado e as instâncias irão interagir com aquele fixture que limita a saida da room), em seguida, abra o  evento Create . Nós precisamos criar duas instâncias de nosso objeto de base e vincular um fixture a eles antes que possamos criar um joint, então vamos fazer isso adicionando o seguinte código:

Código: Selecionar todos

var instA = instance_create (100, 100, obj_Base);
var instB = instance_create (100, 300, obj_Base);
var fixA = physics_fixture_create ();

physics_fixture_set_circle_shape (fixA, 20);
physics_fixture_set_density (fixA, 0.5);
physics_fixture_set_restitution (fixA, 0.8); 
physics_fixture_bind (fixA, instA);
physics_fixture_bind (fixA, instB); 
physics_fixture_delete (fixA);
Nós também precisamos adicionar o evento Mouse -> Global Mouse -> Left Mouse Pressed para criar um impulso e assim mover as instâncias, caso contrário você não será capaz de ver como os joints funcionam, portanto, acrescente este código:

Código: Selecionar todos

with(obj_Base)
{
   var dist = point_distance (x, y, mouse_x, mouse_y);
   if dist <100
   {
      var pd = point_direction (x, y, mouse_x, mouse_y) - 180;
      physics_apply_impulse (mouse_x, mouse_y, lengthdir_x (100, pd), lengthdir_y (100, pd));
   }
}
Agora você pode adicionar uma instância de "obj_Control" na room e testar o seu jogo. Se tudo tiver corrido bem, você pode ricochetear algumas "bolas" clicando perto delas com o mouse.

ADICIONANDO UM DISTANCE JOINT

Vamos ligar esses dois fixtures de círculo com um joint. Joints são definidos no  espaço da room e não no espaço local, assim que você deve criar as instâncias e colocar os joints com base nas coordenadas da sua room. Neste caso (ainda no evento Create do "obj_Control") vamos fazer assim, e colocar o código abaixo logo após a crição das instancias e fixtures:

Código: Selecionar todos

physics_joint_distance_create (instA, instB, instA.x, instA.y, instB.x, instB.y, true);

Você fornece as duas instâncias que irão se "juntar", onde na room isso vai acontecer, e, em seguida, se eles podem colidir entre (true ou false). Tudo muito simples! Execute novamente agora e veja como você tem uma "barra" como fixture que rebate em torno da room.

NOTA: Você só pode ver as juntas quando depurar desenho! Em um jogo normal eles não devem aparecer, portanto, você precisará desenhar alguns gráficos a si mesmo se você quer mostra-los.

ADICIONANDO UM REVOLUTE JOINT

Agora que você já viu como é fácil 'juntar' fixtures, vamos adicionar mais um par, mas com um tipo diferente de joint ... revolute joint  (Articulação de revolução, algo assim). Este é um conjunto que é criado numa posição na room e que se junta a instâncias em torno desse ponto. Pense em um pino que segura duas argolas. então você pode girar as duas argolas ao redor do pino. Bem, nossa joint revolute vai fazer a mesma coisa.

Ainda no evento Create do "obj_Control", adicione o seguinte:

Código: Selecionar todos

var instA = instance_create (room_width - 300, 200, obj_Base);
var instB = instance_create (room_width - 300, 400, obj_Base);
var fixA = physics_fixture_create ();
var fixB physics_fixture_create = ();
physics_fixture_set_circle_shape (fixA, 100);
physics_fixture_set_density (fixA, 0);
physics_fixture_bind (fixA, instA);
physics_fixture_set_box_shape (fixB, 25, 100);
physics_fixture_set_density (fixB, 0.5);
physics_fixture_bind (fixB, instB);
physics_fixture_delete (fixA);
physics_fixture_delete (fixB);

physics_joint_revolute_create (instA, instB, room_width - 300, 300, 0, 0, falsa, 100, 50, true, false);
Como antes, nós criamos duas fixtures (um círculo e uma caixa) e queremos juntar a caixa com a borda externa do círculo. Fazemos isso com a revolute joint, e nós também definimos um motor (isto é parte da função), para que ele comece a rodar.

A maioria das joints tem alguns parâmetros extras, como este que lhe permite limitar o ângulo de rotação e adicionar um motor, por isso certifique-se de ler a referência de cada função no manual para ter certeza do que cada argumento faz.

ADICIONANDO UM PULLEY JOINT

O último joint que vamos adicionar é um polley joint (Articulação de polia). Isto irá ligar duas instâncias em duas posições no espaço da room, mas permitindo que aja moviemnto dentro dos limites da polia, ou seja: se alguém se move para a direita, então ele vai "puxar" sobre a polley joint e fazer a outra instância se mover bastante. Isto pode parecer um pouco complicado, mas como você verá, é semelhante aos joints anteriores:

Código: Selecionar todos

var instA = instance_create (300, room_height - 100, obj_Base);
var instB = instance_create (room_width - 300, room_height - 100, obj_Base);
var fixA = physics_fixture_create ();
physics_fixture_set_circle_shape (fixA, 20);
physics_fixture_set_density (fixA, 0.5);
physics_fixture_set_restitution (fixA, 0.8);
physics_fixture_bind (fixA, instA);
physics_fixture_bind (fixA, instB);
physics_fixture_delete (fixA); 

physics_joint_pulley_create (instA, instB, 300, room_height - 180, room_width - 300, room_height - 180, 0, -2, 0, -2, 1, false);
Mais uma vez, duas instâncias, cada uma com seus fixtures e posicionadas na room. Em seguida, é adicionado o polley joint, selecionando os fixtures, em seguida, definindo o primeiro e segundo pontos de ancoragem para a polia. Estes pontos de ancoragem podem estar em qualquer lugar no ambiente, e a distância entre o exemplo e cada ponto de ancoragem é a quantidade de "ganho" que cada uma das extremidades da polia terá. Você também pode definir um deslocamento local para x e y nesse conjunto, e isso vai fazer a ligação entre a polia e o deslocamento do fixture ancorado.

Finalmente é possível adicionar uma proporção (neste caso, 1: 1), o que fará com que uma extremidade da polia tenha uma proporção de comprimento maior ou menor em comparação com a outra extremidade da polia.

RESUMO

Esta é a parte final dos nossos tutoriais sobre física e espero que eu tenha te ajudado a colocar a peça final desse quebra-cabeça. Com a capacidade de criar joints, e as técnicas mostradas para depuração, você deve agora ser capaz de fazer algum jogo de física simples, e tem uma base firme para a criação de jogos mais complexos, com uma pequena ajuda do manual!

Você pode baixar um arquivo de exemplo com o código deste tutorial:

Baixe o exemplo
Começando com o Game Maker? Olhou para assinatura certa!

Imagem

Tutoriais e vídeo aulas de programação! Clique no Banner e confira!

Responder

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante