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


Movimentos e colisões em jogos de plataforma

2 participantes

Ir para baixo

plataforma - Movimentos e colisões em jogos de plataforma Empty Movimentos e colisões em jogos de plataforma

Mensagem por PedroX Dom 30 Ago 2020, 13:50

Movimentos e colisões em jogos de plataforma


  • Versão recomendada: GM7 ou superior
  • Anexos: Download da engine (para GM 8.1)
  • Informações adicionais: Não requer extensões nem DLLs
  • Tags: jogos de plataforma, colisões, movimentos


Preparando seu arquivo GMK:
Para acompanhar o tutorial, você pode fazer o download do arquivo .gmk anexo (clique aqui). Daí você pode pular essa etapa.

Caso você queira começar do zero, realize os seguintes passos:


  1. Sprites: Crie 3 sprites com os nomes: spr_player, spr_bloco, e spr_rampa. É opcional centralizá-las, mas deixe marcada a opção "Precise collision checking" (ou terá que criar e usar a máscara de colisão correta).
  2. Objects: Crie 3 objetos, cada um com uma das sprites criadas. Os nomes dos objetos podem ser: player, bloco, e rampa, mas são irrelevantes.
  3. Rooms: Crie uma Room, depois crie um cenário, posicionando os objetos criados. O meu cenário ficou assim:
    plataforma - Movimentos e colisões em jogos de plataforma Cenari10
  4. Códigos utilizados: Para simplificar, vamos usar poucos códigos.


    1. Abra o objeto player.
    2. Adicione o evento Create e depois insira em um bloco de código:
      Código:
      vx = 6;

    3. Adicione o evento Step -> Step e depois insira um bloco de código:
      Código:
      vspeed += 1;

      dx = keyboard_check(vk_right)-keyboard_check(vk_left);
      vl = sqrt(power(vx,2)+power(vspeed,2));

      if (dx != 0)
      {
          image_xscale = dx;
          
          if (place_meeting(x, y+1, rampa))
          {
              x += dx*vx;
              y += 5;
              move_outside_all(90, 20);
          }
          else
          {
            if (!place_empty(x+dx*(vx+1), y))
              {
                  move_contact_all((dx-1)*90, vl);
              }
              else
              {
                  x+= dx*vx;
              }
          }
      }

      if (!place_empty(x, y+vspeed+1))
      {
          if (vspeed>0)
              move_contact_all(270, vspeed);
          
          vspeed = 0;
      }


      if (keyboard_check_pressed(vk_up) && !place_empty(x, y+1))
      {
          vspeed = -18;
      }





Explicação:

A imagem mostra os principais ângulos de movimento:
plataforma - Movimentos e colisões em jogos de plataforma Main-q10


  • No código vx = 6, A variável vx define a velocidade horizontal do player. No caso, 6 pixels a cada step. Mas variáveis não fazem nada por si só. Então acompanhe onde ela vai ser usada.

  • No código vspeed += 1 a ideia é criar a aceleração pela gravidade. A cada quadro (step) do jogo, a velocidade vertical do objeto aumenta em 1.

    Curiosidade: Essa aceleração é de 1 pixel / step². Também pode ser calculada por (room_speed²) px/s². Para um valor comum de room_speed = 30, a gravidade é de 900 pixels / s². Isso quer dizer que a cada segundo de jogo a velocidade vertical do player aumenta em 900 pixels por segundo.

  • No código dx = keyboard_check(vk_right)-keyboard_check(vk_left);, a variável dx terá o valor 1 se apenas a seta direita estiver sendo pressionada, -1 se apenas a seta esquerda estiver sendo pressionada, e 0 se ambas estiverem sendo pressionadas. Ou seja, queremos: quando dx=1, mover para a direita; quando dx=-1, mover para a esquerda; quando dx=0, ficar parado. Mas por enquanto temos apenas uma variável que não causa nada por si só.

  • No código vl = sqrt(power(vx,2)+power(vspeed,2)), a variável vl guarda o valor da velocidade do player. Esse é o valor que teríamos na variável speed se estivéssemos usando hspeed e vspeed.

  • A condição if (dx != 0) determina que, quando houver intenção de movimento, o código dentro da condição deve ser processado. Vamos ao código dentro da condição:

    • O código image_xscale = dx; faz a imagem (sprite) do player inverter horizontalmente quando ele vai para a esquerda. Veja: quando image_xscale=1, a imagem fica na posição original, quando image_xscale=-1, a imagem fica invertida na horizontal. Quando image_xscale=0, a imagem some, mas a gente está dentro de uma condição (dx!=0, aliás, como já explicado, sempre teremos dx=1 ou dx=-1).

    • A condição if (place_meeting(x, y+1, rampa)) é para quando o player estiver tocando por cima qualquer instância do objeto rampa. Como já estamos dentro da condição de movimento (dx!=0), temos que o player quer mover em cima da rampa.

      Vamos ao código dentro da condição:

      • O código x += dx*vx; faz com que o player simplesmente se desloque para a esquerda ou direita, de acordo com dx. Veja o que o código vai entender: se dx=1, então x+=6; se dx=-1, temos x-=6.

      • O código y += 5; faz o player se mover para baixo e entrar dentro da rampa. Já o código move_outside_all(90, 20); faz com que o player se mova para cima até que saia da rampa. Essa combinação aparentemente maluca simplifica o processo e faz com que o player não passe por dois bugs comuns em jogos de plataforma: grudar na rampa (por isso o move_outside_all(90, 20);) e ficar pulando ao descer pela rampa (por isso o y+=5).


    • Em seguida temos a condição else, que acontece sempre que o player não estiver tocando uma rampa por cima. Vamos ao código dentro da condição:

      • No código if (!place_empty(x+dx*(vx+1), y)), a condição imposta é não ter espaço livre à esquerda ou à direita do player (depende do sentido desejado para o movimento, guardado na variável dx). Ou seja, se o player está tentando se mover na horizontal e vai dar de cara com uma parede. Dentro da condição temos o código move_contact_all((dx-1)*90, vl); que faz o player se mover na direção 0º (direita) ou na direção 180º (esquerda). Essa função faz com o objeto se mova até encontrar um objeto (independentemente de ser sólido), ou seja, ao mesmo tempo que move o objeto, move apenas o necessário, prevenindo que entre na parede. Dica: Para entender as direções, imagine o valor dx=1 e depois o valor dx=-1 na fórmula.


    • Em seguida temos a condição else, que acontece quando há espaço livre na horizontal para o player se mover. Note que estamos aninhando condições (ou seja, o player quer se mover, não está em cima de uma rampa e não vai dar de cara com uma parede na direção ao fazer seu movimento horizontal). O código x+= dx*vx; dentro da condição é dos mais simples: mudamos o valor de x para deslocar o player.


  • No código if (!place_empty(x, y+vspeed+1)), entramos numa condição que já não tem nada a ver com o player estar querendo se mover ou não. Ela acontece nos dois casos. A condição agora acontece sempre quando o player está se aproximando ou está tocando qualquer objeto por cima. Esse é bem parecido com os clássicos exemplos de plataforma. Vamos ao código dentro da condição:

    • No código if (vspeed>0), a ideia, para quando o player está caindo na tela, é verificar se está chegando no chão (estamos preparando o pouso). Se estiver chegando, não vamos querer que entre no chão (incluindo rampas e outros objetos), e isso aconteceria se a vspeed continuasse maior que zero. Perceba: o player está bem perto do chão (sendo mais exato, na condição o player não pode se deslocar para baixo no valor igual a vspeed) e a sua velocidade vertical está maior que zero, então temos que "acertar" isso. Na vida real o próprio chão se encarregaria de parar a sua queda, mas na programação o programador cria as leis da natureza. Então vamos ao código dentro da condição:

      • O código move_contact_all(270, vspeed); simplesmente força o player a ir para baixo até encontrar o chão (ou qualquer objeto, mesmo que não sólido).
      • O código vspeed = 0; faz o player parar na vertical, como o chão faria na vida real.


      Dúvidas? Poste aqui.


  • Temos finalmente o código: if (keyboard_check_pressed(vk_up) && !place_empty(x, y+1))
    , que é uma condição que detecta se a seta para cima foi pressionada e se ao mesmo tempo o player está em cima de algo (ele não pode pular quando já está no ar). O código vspeed = -18; simplesmente define uma velocidade vertical negativa (ou seja, para cima), que faz o player pular.

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : plataforma - Movimentos e colisões em jogos de plataforma Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

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

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

Super Games, Ralphed, polosam, Diemorth, angelgui12 e Vaziu gostam desta mensagem

Ir para o topo Ir para baixo

plataforma - Movimentos e colisões em jogos de plataforma Empty como resolvo esse erro?

Mensagem por Vaziu Seg 31 Ago 2020, 09:30

mano quando eu coloco um evento de colisão com outros objetos o evento só funciona se o obj_player colidir com a parte de baixo do obj exemplo: eu pego esse seu tutorial e faço um novo objeto chamado obj_next e ponho um evento de colisão no obj do player para que quando o obj do player colidir com o obj_next ele ir parar outra room mais ele só funciona se o obj do player colidir com a parte de baixo do obj_next, como arrumo isso para que se o player colidir com qualquer parte do "obj_next" ele ir para a outra room?agradeço desde já.
Vaziu
Vaziu

Games Ranking : Sem avaliações

Data de inscrição : 13/08/2020
Reputação : 1
Número de Mensagens : 34
Prêmios : plataforma - Movimentos e colisões em jogos de plataforma Empty

Medalhas x 0 Tutoriais x 1 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1
  • Game Maker Studio 1.4
  • Game Maker Studio 2.0
  • Outros


Ir para o topo Ir para baixo

plataforma - Movimentos e colisões em jogos de plataforma Empty Re: Movimentos e colisões em jogos de plataforma

Mensagem por PedroX Seg 31 Ago 2020, 10:39

Faça duas mudanças:

1. Troque todos os place_empty por place_free, troque os move_contact_all por move_contact_solid.
2. Marque os objetos que sejam chão ou paredes como sólidos (ou seja, os que você nunca poderá atravessar).

_________________


Leia o Manual do Iniciante e a Lista de Tutoriais, para aprender bastante sobre o GM.
Recomendo o Manual completo das colisões, bem útil.
O exemplo Criar um chat (banir, kickar, etc) é interessante.

Para seu jogo ficar rápido e legal, aprenda a Aumentar o desempenho do seu jogo.

Aprenda a calcular a velocidade de suas animações


Entre para o Clube do Inglês:
PedroX
PedroX

Games Ranking : Nota B

Notas recebidas : C+B
Data de inscrição : 26/07/2008
Reputação : 311
Número de Mensagens : 6087
Prêmios : plataforma - Movimentos e colisões em jogos de plataforma Empty

Medalhas x 0 Tutoriais x 17 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

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

https://web.whatsapp.com/send?phone=5519995935953&text=Pedro

gilomania3d, Super Games, polosam e Vaziu gostam desta mensagem

Ir para o topo Ir para baixo

plataforma - Movimentos e colisões em jogos de plataforma Empty Re: Movimentos e colisões em jogos de plataforma

Mensagem por Conteúdo patrocinado


Conteúdo patrocinado


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