Plataforma fantasma

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

Plataforma fantasma

Mensagem por Zero. em Dom 03 Mar 2013, 21:31

Enfim consegui fazer um sistema de movimento com rampa e colisão sem que o obj seja solido, mas agr falta a plataforma fantasma.

Aqui está a engine de movimento e rampa >https://www.dropbox.com/s/mkhifo5vxa1ki6w/Eng%20Movimento.gmk?m< , mas oque falta a plataforma fantasma, queria que o personagem pulasse debaixo da plataforma e caísse em cima, sem afetar os outros objs na room que poderão fazer a msm coisa ( no caso inimigos ) , alguem pode ajudar ?

thx

obs: essa engine naum é toda minha, só fiz umas modificações. Não sei quem foi o outro de quem peguei a base *---*


Última edição por FlyAway em Dom 03 Mar 2013, 21:37, editado 1 vez(es)

Zero.

Número de Mensagens : 1295
Idade : 20
Data de inscrição : 19/08/2010
Reputação : 47
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por saim em Seg 04 Mar 2013, 14:26

Eu tenho quase certeza de já ter entrado nesse assunto contigo, antes...
Parei um pouco pra pensar nas plataformas fantasmas. Elas devem permitir passagem quando a velocidade vertical for negativa e negar passagem quando for positiva. O bug é quando o sentido da velocidade muda e o objeto está em contato com a plataforma... Aí, o objeto fica preso e isso provavelmente permite outro pulo, no ar.

O que eu faria é colocar uma variável na plataforma, tipo "passando" ou coisa do tipo. Daí, no step da plataforma, eu mando um
Código:
if (place_meeting(x, y, objPlayer)){
   passando = true;
   }
   else {
      passando = false;
      }
Dá pra notar que é possível substituir essa variável pela função place_meeting, né? Mas eu me organizo melhor assim.
Aí, se a velocidade for negativa, o objPlayer passa pela plataforma normalmente. Se for ">= 0", só passa se o "passando" for true. Isso pode ser usado pra saltos de cima pra baixo, (agachando e apertando pulo, por exemplo). Ou simplesmente permitir passagem enquanto o jogador estiver apertando pra baixo, independente do sinal da velocidade (em geral, acho meio ruim, desse jeito, mas pode ser que funcione no seu jogo).
Pode parecer que a ordem em que as instâcias são criadas vai influenciar, mas acho que não. Se você permitir ao objPlayer entrar em contato no último step em que a velocidade é negativa, no step seguinte em que ele rodar o teste a plataforma já vai estar com "passando = true", quer ela rode o step antes ou depois do objPlayer.

É meio lento, porque vai um pedacinho de código no STEP de cada plataforma, mas não acho que vá causar lag. De qualquer forma, você poderia colocar o teste no begin step do objPlayer, mas aí teria que usar o "with (objPlataformaFantasma)", o que dá no mesmo. Não consigo pensar numa forma de fazer o "passando" voltar pra "false" se não rodar o teste a cada step.

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por Zero. em Seg 04 Mar 2013, 20:14

saim, eu já tinha pensando numa variavel local nas plataformas, inclusive ja fiz até o teste. O problema é que pondo esta variavel local, ela acaba virando "global" porque outros objs que esteja em cima da msm plataforma vão identificar que passando está true por causa do jogador. Eu ja pensei em muitas formas, mas não consigo concluir. Você baixou a engine ? '-'

Zero.

Número de Mensagens : 1295
Idade : 20
Data de inscrição : 19/08/2010
Reputação : 47
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por saim em Ter 05 Mar 2013, 10:41

Baixei não... Se bem que eu devia baixar, até hoje não tenho uma engine com rampas...
Mas não entendo porque os outros objetos deveriam checar pelo valor da variável. Note que, embora a variável esteja nas plataformas, quem verifica o valor dela é o objPlayer. Pras IAs, simplesmente não cheque o valor da variável

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por Zero. em Ter 05 Mar 2013, 13:31

KKKKKKKKKKKK, Verdade. simplesmente não checo que é pra descer certo ?
Se puder baixar e tentar fazer, eu vou fazer aq da minha forma, mas queria ver como vc faria tb.

Zero.

Número de Mensagens : 1295
Idade : 20
Data de inscrição : 19/08/2010
Reputação : 47
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por saim em Ter 05 Mar 2013, 15:20

Baixar, agora, não dá... Aquele velho motivo de sempre: estou longe de casa.
Agora, eu pesquisei nas minhas engine aqui e encontrei uma que NÃO usa a tal variável e funciona bem! Permite até empilhar plataformas e deixar o jogador descer através de algumas delas (ou todas, mas o legal é que podem ser só algumas). Veja só:
Spoiler:
>create<
Código:
//define variáveis da movimentação
spdX = 0; maxSpdX = 4;
spdY = 0; maxSpdy = 10; Grav = 0.5; jumpSpeed = -10;
//verifica se deve entrar na room caindo ou não
if (place_meeting(x, y + 1, objPlataforma)){
   noAr = false;
   }
   else {
      noAr = true;
      }
>step<
Código:
//movimentação horizontal (simplezinha mesmo)
//define a velocidade
spdX = (keyboard_check(vk_right) - keyboard_check(vk_left)) * maxSpdX;
//movimenta
if (!place_meeting(x + spdX, y, objPlataforma)){ //se não vai colidir
   x += spdX; //movimenta
   }
   else { //se VAI colidir
      while(!place_meeting(x + sign(spdX), y, objPlataforma)){ //enquanto não colide
         x += sign(spdX); //anda um pixel na direção pedida
         }
      }
//depois de movimentar, verifica se é pra cair
if (!place_meeting(x, y + 1, objPlatFantasma) && !place_meeting(x, y + 1, objPlataforma)){
   noAr = true; //permite a queda
   }

//movimentação vertical
//entrada de comandos
if (noAr == false){ //se está no solo
   if (keyboard_check_pressed(vk_up) || keyboard_check_pressed(vk_space)){ //se apertou o pulo
      if (!keyboard_check(vk_down)){ //se não está tentando descer
         spdY += jumpSpeed; noAr = true; //pula
         }
         else if (!place_meeting(x, y + 1, objPlataforma)){ //se ESTÁ tentando descer e PODE descer
            noAr = true;
            }
      }
   }

if (noAr == true){ //se está no ar (poderia ser um "else")
   //define a velocidade
   spdY = min(spdY + Grav, maxSpdy); //limita a velocidade terminal
   
   //verifica colisões
   if (place_meeting(x, y + spdY, objPlatFantasma) && !keyboard_check(vk_down) && spdY > 0){ //se vai colidir com uma plataforma fantasma
      event_perform(ev_trigger, 0);
      }
   
   if (place_meeting(x, y + spdY, objPlataforma)){ //se vai colidir com uma plataforma comum
      event_perform(ev_trigger, 1);
      }
   
   y += spdY;
   }
>trigger0<
Código:
//colisão com plataforma fantasma
var platAtual, platNova;
platNova  = collision_line(bbox_left, bbox_bottom + spdY, bbox_right, bbox_bottom + spdY, objPlatFantasma, 1, 1); //a plataforma de baixo
platAtual = collision_line(bbox_left, bbox_bottom      , bbox_right, bbox_bottom      , objPlatFantasma, 1, 1); //a plataforma daqui
if (platAtual != platNova && platNova != noone){ //se não colide atualmente com a próxima E existe uma próxima
   while (!place_meeting(x, y + Grav, platNova)){ //enquanto não colide (já que vai acabar colidindo, mesmo)
      y += min(Grav, 1); //anda tantos pixels quanto a gravidade mandar (ou só 1, se a gravidade for muito alta)
      }
   //ao final do while, os objetos estarão se tocando
   spdY = 0; noAr = false; //zera a velocidade e não deixa ela ser atualizada no próximo step
   }
>trigger1<
Código:
//colisão com plataforma normal
while (!place_meeting(x, y + sign(spdY), objPlataforma)){ //enquanto não colide (já que vai acabar colidindo, mesmo)
   y += sign(spdY); //usei o sign, aqui, porque tem que funcionar também enquanto sobe
   }
if (spdY > 0){ //se estava caindo
   noAr = false;
   }
spdY = 0; //a velocidade deve ser zerada independente de estar caindo ou não

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por Zero. em Qua 06 Mar 2013, 14:01

Naum entendi a parte do bbox, min e sign *---*

Zero.

Número de Mensagens : 1295
Idade : 20
Data de inscrição : 19/08/2010
Reputação : 47
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por saim em Qua 06 Mar 2013, 16:11

sign e min são funções que eu usei pra economizar if-else. Os bboxes eu usei pra generalizar um pouco a engine.

sign = sinal.
A função te retorna um desses 3 valores: +1, -1 ou 0. Como eu estou SOMANDO uma unidade, ela tem que estar com o sinal da velocidade. Aí, se a velocidade for negativa, eu somo "pra trás", efetivamente diminuindo o valor da posição.
"Enquanto não colide, avança um pixel na direção (sign) da velocidade - e, quando for colidir, sai do while"
Esse while é minha gambiarra pra substituir o move_contact.

bbox = limites da caixa de colisão.
Como eu fiz essa engine pensando numa plataforma em que a origem da sprite pode estar em qualquer lugar (eu não queria atrelar o funcionamento da engine à origem), então resolvi usar os bboxes. Se a origem for no ponto (0,0), então temos
bbox_left = 0, bbox_top = 0, bbox_right = sprite_width, bbox_bottom = sprite_height
e se a origem for no ponto (a, b), temos
bbox_left = -a, bbox_top = -b, bbox_right = sprite_width - a, bbox_bottom = sprite_height - b

min = menor.
A função te retorna o menor dos argumentos
Então quando eu escrevo
Código:
spdY = min(spdY + Grav, maxSpdy);
é o mesmo que estar escrevendo
Código:
spdY = spdY + Grav;
if (spdY > maxSpdy){
   spdY = maxSpdy;
   }
e quando eu escrevo
Código:
y += min(Grav, 1)
é como querer dizer "anda só o valor de 'Grav' (que pode ser alterado no create, depende do estilo do jogo), mas se 'Grav' for muito alta, anda só 1"

saim

Ranking : Nota B
Número de Mensagens : 2964
Idade : 38
Data de inscrição : 14/01/2011
Notas recebidas : C-D-A-B
Reputação : 121
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 3

Voltar ao Topo Ir em baixo

Re: Plataforma fantasma

Mensagem por Conteúdo patrocinado Hoje à(s) 08:34


Conteúdo patrocinado


Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum