[Resolvido] Ponto de colisão em uma collision_line()

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

Resolvido [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 18:40

Beleza pessoa? Então, quebrei a cabeça aqui de todo jeito, tentei várias alternativas e não consegui um jeito eficaz!

Minha dúvida é o seguinte... Quando eu uso a função collision_line() ela testa se há colisão com algum objeto no segmento de dois pontos que fazem a linha, certo? Até aí tudo bem, mas será que tem como pegar o exato ponto de colisão dessa linha? Eu até consegui fazer usando loop e ir conferindo as coordenadas pelo ângulo com lengthdir_x e lengthdir_y... mas dependendo da quantidade de loops fica lento!

Dá uma olhada nessa imagem:


Última edição por Ninja8086 em Sex 08 Jul 2011, 11:02, editado 2 vez(es)

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por MatheusReis em Qui 07 Jul 2011, 18:43

Bem, a perfeição custa processamento(por consequência a velocidade), mas basta quebrar a perfeição com intervalos. Ao invés de mover a pixel a pixel o ponto de checagem, mova de 5 em 5 por exemplo(usando uma linha, para cobrir a extensão dos 5 pixels).

MatheusReis

Ranking : Nota A
Número de Mensagens : 1087
Idade : 23
Data de inscrição : 13/01/2010
Notas recebidas : B-A-A
Reputação : 30
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 2
   : 1
   : 0

http://www.mathaeuz.deviantart.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 18:45

Eu também tentei isso, na verdade o problema maior não é o valor do salto, mas a quantidade de loops em um todo, na abertura do ângulo, dá uma olhada na imagem que eu postei que vc vai perceber o que eu digo Smile

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por MatheusReis em Qui 07 Jul 2011, 18:50

Então, o que eu quiz dizer foi aumentar o salto para reduzir o numero de loops e acelerar o jogo. Ou ainda não entendi o problema?

MatheusReis

Ranking : Nota A
Número de Mensagens : 1087
Idade : 23
Data de inscrição : 13/01/2010
Notas recebidas : B-A-A
Reputação : 30
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 2
   : 1
   : 0

http://www.mathaeuz.deviantart.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 18:56

Sei... Então, eu tentei isso, mas nesse caso, não seria o ponto de colisão exato, entende?

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por MatheusReis em Qui 07 Jul 2011, 18:59

Entendo, mas ai entra o que eu disse: a precisão custa memória de processamento. Eu ainda acho que vale a pena. Algo com em média 5 pixels de imprecisão não seria tão ruim.

MatheusReis

Ranking : Nota A
Número de Mensagens : 1087
Idade : 23
Data de inscrição : 13/01/2010
Notas recebidas : B-A-A
Reputação : 30
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 2
   : 1
   : 0

http://www.mathaeuz.deviantart.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 19:05

É acho que vou tentar ter que fazer assim mesmo. A menos que apareça alguém com uma solução mirabolante... Bem que poderia ser possível, achava que a própria collision_line funcionava mais ou menos por aí.. mas tudo bem Smile

O jeito vai ser tentar otimizar o código. Muito obrigado! Smile

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por MatheusReis em Qui 07 Jul 2011, 19:06

Concerteza. Você está usando qual dos loops(while,repeat,for)?

MatheusReis

Ranking : Nota A
Número de Mensagens : 1087
Idade : 23
Data de inscrição : 13/01/2010
Notas recebidas : B-A-A
Reputação : 30
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 2
   : 1
   : 0

http://www.mathaeuz.deviantart.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 19:10

mais ou menos assim:
Código:

for (ponto = 0; ponto <= distancia/salto; ponto += 1)
{
        confere = ponto * salto;
        if tal tal tal
}

daí quando ele acha o ponto tem um break pra sair do loop

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por MatheusReis em Qui 07 Jul 2011, 19:11

Hmm...
for para mim já é o limite de aceleração de um loop, então só optimizando o resto mesmo. =/
Bem, boa sorte com seu jogo, e que a força esteja contigo.

MatheusReis

Ranking : Nota A
Número de Mensagens : 1087
Idade : 23
Data de inscrição : 13/01/2010
Notas recebidas : B-A-A
Reputação : 30
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 2
   : 1
   : 0

http://www.mathaeuz.deviantart.com

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 19:13

Valeu! Obrigado pela ajuda! Smile

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por Markituh em Qui 07 Jul 2011, 19:14

Talvez um loop não seja necessário. O que você pode fazer é um lengthdir que aumente o argumento len a cada Step se não encontrar uma colisão com o objeto em questão.
Código:
var sight;
if !colision_line(x,y,x+lengthdir_x(sight,direction),y+lengthdir_y(sight,direction),obj_parede,1,1)
{
sight+=1
}
else
{
show_message("Encontrou colisão")
}
Tenta isso e vê se dá certo.

___________

"Não deixe para amanhã o que se pode fazer hoje"

Links úteis:
Índice de Tutoriais
Manual online do GMS

Markituh

Ranking : Sem avaliações
Número de Mensagens : 2183
Data de inscrição : 11/10/2009
Reputação : 106
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 19:19


Boa dica!! blz blz blz blz
Vou tentar aqui, já que a collision_line é mais rápida que a instance_position, ou place_meeting!

Valeu Markituh!

---- Edit ----

Sua dica foi ótima, eu não usei exatamente isso mas me levou a mudar o raciocínio para uma coisa: vou basear o loop diminuindo ou aumentando de acordo com a distância. Se eu usar uma linha de 500 pontos e houver colisão eu uso a distance_to_point pra ter uma base, e se for próxima de 500 , não há por que fazer um loop do 0 à 500 e sim de 500 a zero e sair do loop quando achar!

Valeu de novo! Podem trancar o tópico!

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por PedroX em Qui 07 Jul 2011, 19:51

Cara você pode tentar isso:
Código:

if collision_line(x, y, x2, y2, objeto, 1, 1)
{
distancia=point_distance(x1, y1, objeto.x, objeto.y)
}
O problema seria a origem do sprite.
Se não der certo, vou adicionar um pequeno código.

Até mais!

PedroX

Ranking : Nota C
Número de Mensagens : 6034
Idade : 21
Data de inscrição : 26/07/2008
Notas recebidas : C+B
Reputação : 286
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por Jiraya em Qui 07 Jul 2011, 20:04

Código:

direction=point_direction(x,y,mouse_x,mouse_y);
for (i=0;i<400 && !collision_line(x,y,x+lengthdir_x(i,direction),y+lengthdir_y(i,direction),OBJETO,0,0);i+=1;)
draw_line(x,y,x+lengthdir_x(i,direction),y+lengthdir_y(i,direction));

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 20:25

@Pedro Henrique

Então Pedro, o problema é esse mesmo, no caso o ponto de colisão não é o pivô do sprite, mas obrigado por postar!

@Jiraya

Legal esse esquema de condicionar a collision_line dentro do for... nunca tinha tentado isso! Eu entendi seu código, vou dar uma adaptada em todas as dicas, ver o que é possível incorporar aqui e posto pra vocês o resultado.

Muito obrigado!

Código:

direction=point_direction(x,y,mouse_x,mouse_y);
for (i=0;i<400 && !collision_line(x,y,x+lengthdir_x(i,direction),y+lengthdir_y(i,direction),OBJETO,0,0);i+=1;)
draw_line(x,y,x+lengthdir_x(i,direction),y+lengthdir_y(i,direction));

De antemão, mesmo que não funcione, obrigado aí moçada! Com esse esquema e a ajuda de vocês desenvolvi um raciocínio novo aqui, acho que vai dar certo! Depois eu posto aí pra vcs verem!

Flws!!!

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por Jiraya em Qui 07 Jul 2011, 20:32

s, ainda da para melhorar.
Código:

direction=point_direction(x,y,mouse_x,mouse_y);
for (i=0;i<400 && !collision_line(x,y,x+lengthdir_x(i,direction),y+lengthdir_y(i,direction),OBJETO,0,0);i+=1;){/*nenhuma função é executada, apenas a checagem*/};
draw_line(x,y,x+lengthdir_x(i,direction),y+lengthdir_y(i,direction));
fazendo assim o desempenho fica maior, pq com a função dentro do bloco for, o gm desenha por exemplo 220 linhas, isso sem duvidas usa muito mais processo.

Jiraya

Ranking : Nota A
Número de Mensagens : 1134
Data de inscrição : 20/03/2010
Notas recebidas : A+A
Reputação : 108
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 1
   : 0
   : 1

https://www.facebook.com/seito.washiro.7

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 20:36

Sensacional!! *-*


Última edição por brendan640 em Sab 08 Jun 2013, 20:24, editado 1 vez(es)

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por ricaun em Qui 07 Jul 2011, 21:18

O grande problema de um code deste tipo é se a distancia for muito grande vai lerdear tudo...

Assim trago algo muito melhor...

Crie um Script e bote isso... Eu usei esse nome 'collision_line2', ele retorna a distância entre o ponto(x1,x2) até colidir...
Código:
//
// dis = collision_line2(x1,y1,x2,y2,obj,prec,notme)
//

__dir = point_direction(argument0,argument1,argument2,argument3);

__dis = point_distance(argument0,argument1,argument2,argument3);

__dislast = __dis;

repeat(20)
{
    __dislast = __dislast/2;
    if collision_line(argument0,argument1,argument0+lengthdir_x(__dis,__dir),argument1+lengthdir_y(__dis,__dir),argument4,argument5,argument6)
        __dis -= __dislast
    else
        __dis += __dislast
}
   
return min(__dis,point_distance(argument0,argument1,argument2,argument3))


Belezinha agora tente isso pra testar...
Código:

dis = collision_line2(x,y,mouse_x,mouse_y,objeto,0,0)
dir = point_direction(x,y,mouse_x,mouse_y)
draw_line(x,y,x+lengthdir_x(dis,dir),y+lengthdir_y(dis,dir))


Achei o efeito tão legal... Agora quero fazer algo com isso...

Té...

PS: Eu usei um repeat de 20 mas acho que pode ser menor...
PS2: Foi feito usando o método da bissecção...



ricaun

Número de Mensagens : 169
Idade : 27
Data de inscrição : 23/09/2008
Reputação : 9
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Qui 07 Jul 2011, 21:55

Boa dica ricaum!

Então, eu to usando esse raciocínio também, igual eu comentei com o Markituh... ele tinha dado a dica de incrementar o lenght da collision_line até achar o ponto, dai eu dividi pela metade e comparei como vc fez!

Realmente é um ganho significativo dentro de loops

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por saim em Sex 08 Jul 2011, 00:06

Foi o gifah que te encucou com essa, né? A idéia é essa mesmo, vai dividindo a distância ao meio e checando pela collision_line, daí soma ou subtrai essa distância, dependendo do resultado. Mesma coisa que fazer um laser. Eu tenho um script aqui no bolso, mas não sei se é muito diferente (ou mesmo se não é pior) que o do ricaun.
Código:
//name the arguments
var X, Y, _dire, _dist;
X=argument0        //starting point of laser (x)
Y=argument1        //starting point of laser (y)
_dire=argument2    //direction of laser
_dist=argument3    //maximum distance of laser
//define some other useful variables
var _last;
_x0=X+lengthdir_x(_dist,_dire) //end point (x)
_y0=Y+lengthdir_y(_dist,_dire) //end point (y)
_last=_dist                    //the last size taken off of _dist
victim=noone                  //the last destroyable met

//end lazer at first blocking obj or as big as it gets, if can't find any
if collision_line(X, Y, _x0, _y0, obj_wall, 1, 1){
 while _last>1{  //esse "1" é a precisão, em pixels
  _last*=0.5
  if collision_line(X, Y, _x0, _y0, obj_wall, 1, 1){ //it is still colliding
  _dist-=_last  //shorten the distance
  }
  else{        //the laser STOPPED colliding after previous iteraction
    _dist+=_last //increases the distance
    }
  _x0=X+lengthdir_x(_dist, _dire) //updates the final point (x)
  _y0=Y+lengthdir_y(_dist, _dire) //updates the final point (y)
  }
 }
Ele não retorna nada, mas declara _x0, _y0 como o ponto de colisão. Fácil de adaptar pra retornar a distância.

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

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Sex 08 Jul 2011, 00:30

Hmmm... interessante! Dá uma olhada ele multiplica por 0.5 pra ir dividindo até chegar a um valor mínimo possível! Por isso que é ótimo pegar exemplos novos pra aprender "novas técnicas"

Eu ainda não implementei no projeto, mas já da pra dizer que isso vai acelerá-lo em pelo menos 30 vezes! Mas seguindo a linha de racicínio que a gente tava comentando, eu consegui fazer. Vou postar ele aqui pra vcs verem, o legal é que dá pra controlar a qualidade da luz pra deixar o jogo mais rapido se precisar

Esse exemplo é bem legal Saim, obrigado pela dica! Vou optar pela sua de saltos por divisão e mesclar com a do Jiraya, em fazer a condição dentro do laço for.


Última edição por Ninja8086 em Sex 08 Jul 2011, 10:24, editado 1 vez(es)

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por saim em Sex 08 Jul 2011, 08:59

Ninja8086 escreveu:Eu ainda não implementei no projeto, mas já da pra dizer que isso vai acelerá-lo em pelo menos 30 vezes!
Depende da distância inicial, e a aproximação é exponencial. Pra saber exatamente quantas iterações serão necessárias, basta fazer o caminho inverso: pegue a precisão (no caso, 1) e vá multiplicando por 2 até chegar à distância máxima. Tentei usar outras formas de aproximação (diminuir 2/3 em caso de colisão e aumentar 1/3 em casos de não-colisão, entre outros), mas essas outras tentativas davam um número variável de iterações, dependia demais das condições no momento.
TALVEZ seja interessante pegar, na primeira iteração, a distância até a instância colidida, pois isso pode diminuir consideravelmente a distância inicial. Em alguns casos, é só uma iteração A MAIS.

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

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por GameMakerTutoriais em Sex 08 Jul 2011, 10:21

Resultado final: FPS do jogo em 30 pontos, sem cair!

Usei o esquema do ricaum e do script de lazer (é o mesmo esquema)! Fiz o esquema de divisão com essa base e to desenhando um vetor, perfeito, em tempo real, com 900 vértices dinâmicos sem cair nenhum pontinho no fps!

900 vértices dinâmicos.

Tópico resolvido! Pra quem tiver a mesma dúvida, a melhor saída pra achar o ponto de uma collision_line com certeza é essa mesmo: divindo o valor pela metade, dentro de um loop e ir somando ou subtraindo pra dividir de novo até chegar a um valor menor ou igual a 1

Muito obrigado pessoal pela ajuda! sorrindo2

GameMakerTutoriais

Número de Mensagens : 800
Data de inscrição : 29/01/2011
Reputação : 26
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Resolvido Re: [Resolvido] Ponto de colisão em uma collision_line()

Mensagem por Conteúdo patrocinado Hoje à(s) 02:10


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