Jump to content


Photo

Objetos Que Se Batem


  • Faça o login para participar
3 replies to this topic

#1 Gilthans

Gilthans

    Turista

  • Usuários
  • 34 posts
  • Sexo:Não informado
  • Localidade:Curitiba PR

Posted 30/07/2005, 17:59

Eu estava tentando fazer um joguino "Breakout" simples. Aqueles bem velho, de uma bolinha que bate no pauzinho e vai pra cima e quebra os "bricks" até que não tem mais deles. Eu fiz tudo certinho, a bola pula, mas eu queria saber como que faço pra quando a bola bater os bricks eles destruirem. Eu pensei fazer a bola achar os "bricks" pelo _x e _y deles, mas isso significa que eu tenho que fazer a função verificar cada vez se a bola está numa posição que bate nos "bricks"... Como o flash é orientada de objetos, eu entendo que deve ter uma maneira de só verificar se bateu sem ter if(brick1._y == ball._y) pra cada brick no jogo...

Como que seria feito isso?


Obrigado,

Gilthans
(novato em flash)
...and may the grand !MooXooM! above enlighten your path.

<?php
function sex($cromo1, $cromo2){ //É talvez a função mais triste que eu já fiz.
...
}
?>

#2 Patrique

Patrique

    Super Veterano

  • Usuários
  • 1859 posts
  • Sexo:Não informado

Posted 30/07/2005, 20:18

E ai cara acho que isso serve para ti

Autor: Gary Fixler

Qualquer um que tenha tentado descobrir quando dois objetos colidem em Flash sabe que existem duas coisas que você pode detectar: quando a caixa delimitadora de um movieclip toca a caixa de outro, ou quando o conteúdo de um movieclip (não sua caixa delimitadora) toca um ponto definido no palco, ou em outro clipe que está no palco. O primeiro mencionado é feito com este tipo de código, para dois movieclips no palco, mcShape1 e mcShape2:

Descubra quando uma caixa delimitadora de um movieclip atinge outra

mcShape1.onPress = mcShape2.onPress = function() {
   this.startDrag();
}
mcShape1.onRelease = mcShape2.onRelease = function() {
   this.stopDrag();
}

function basicHitTest() {
   if (mcShape1.hitTest(mcShape2)) {
      trace("hit " + i++);
   }
}
this.onEnterFrame = basicHitTest;

Isto funciona muito bem se o mcShape1 e o mcShape2 forem ambos de uma forma perfeitamente retangular (enchendo, assim, suas respectivas caixas delimitadoras). Caso elas não sejam de forma retangular, e você queira checar quando qualquer parte do conteúdo de uma delas (digamos, mcShape1) toque um ponto em particular da outra (digamos, um ponto colocado 5 pixels para a direita e 7 abaixo do ponto de registro no mcShape2), você pode também fazer assim:

Descubra quando o conteúdo de um movieclip atinge um ponto no palco

mcShape1.onPress = mcShape2.onPress = function() {
   this.startDrag();
}
mcShape1.onRelease = mcShape2.onRelease = function() {
   this.stopDrag();
}

function shapeHitTest() {
   if (mcShape1.hitTest(mcShape2._x+5, mcShape2._y+7, true)) {
      trace("shape hit " + i++);
   }
}
this.onEnterFrame = shapeHitTest;


Mas, se você quer saber quando qualquer parte do conteúdo (não a caixa delimitadora) do mcShape1 colide com qualquer parte do conteúdo (não a caixa delimitadora) do mcShape2, você precisará fazer alguma coisa como o que o Gary fez na sua amostra: use múltiplos clipes em branco para definir a borda.

Detecção precisa

Se você olhar para os símbolos de movieclip azuis e verdes na biblioteca do fla acima, você verá que cada um contém um movieclip chamado perim. Perim contém séries de movieclips em branco, dispostos lado a lado (quanto mais clipes, mais precisão, mas também maior poder de processamento é requerido para detectar uma colisão, claro!) à volta da borda da forma do clipe. Então, ao invés de checar se o clipe a colidiu com o clipe b, checamos se o clipe a colidiu com qualquer dos guardas (tratados como pontos únicos) no clipe b:

Descubra quando o conteúdo de um movieclip atinge outro clipe em qualquer lugar ao longo da borda de sua forma

// for each sentry in this clip ("clip b")
for (i in this.perim) {
   // get the sentry's point on the stage
   this.perim.localToGlobal(p={x:this.perim[i]._x,y:this.perim[i]._y});
   // see if it's touching o ("clip a")
   if(o.hitTest(p.x, p.y, true)){
      o._alpha=50;
   }
}


O método localToGlobal nos permite encontrar o local da guarda relativa ao palco (ao invés do perim, que está dentro dele). Aquela instrução diz: tome os valores x e y correntes da guarda (por exemplo, this.perim[i]._x) e faça um objeto p fora daqueles valores. Determine o valor p.x da guarda dentro do perim, e atribua a p.y seus valores y. Então utilize localToGlobal para convertê-lo em um novo objeto p, cujo valor x é o ponto no palco onde está a guarda, e cujo valor y é o valor y da guarda no palco.

Para imitar as leis físicas do movimento

Se você vem dando uma olhada no fla, viu que outras coisas estão acontecendo dentro do método do movieclip de detecção de colisão (col) além da detecção de uma colisão e do ajuste do alfa para 50. Dentro do loop, a localização de cada guarda no palco (p.x, p.y) é calculado para propósitos de detecção de colisão e também usado para descobrir quando um objeto salta ou é lançado para fora do palco (por exemplo, p.x > gcStageWidth), e como parte de uma soma que mostra quão distante um clipe está quando vai para fora do palco, que é então usado para calcular o número de rotações que ele dará quando saltar de volta.

Efeitos físicos, como a aceleração e desaceleração, são aplicados pela simples adição de uma quantidade crescente ou decrescente de x e y na passagem de tempo do objeto (cada quadro). Por exemplo, aceleração (gravidade) é aplicada pela adição de uma quantidade constante y (constante gcGravity) para o objeto em cada quadro quanto ele se move para baixo. De modo semelhante, a desaceleração é conseguida pela adição de uma quantidade decrescente (multiplicando o montante a ser adicionado por um fator menor que 1, ou dividindo-o por um fator > 1) em cada quadro para desacelerar o objeto (por exemplo, fricção, amortecimento).

Para uma melhor visão sobre como cada efeito foi conseguido, sugerimos começar com o fla (todos os códigos estão no quadro 1 da linha de tempo principal, e possuem comentários nas linhas para explicar o que está sendo feito em cada segmento) e então mudar os números e/ou os comentários fora das linhas para ver que efeito será produzido.

Um abraço,
Patrique André

#3 Gilthans

Gilthans

    Turista

  • Usuários
  • 34 posts
  • Sexo:Não informado
  • Localidade:Curitiba PR

Posted 01/08/2005, 16:53

Só uma coisa não ficou clara na sua explicação - esse ponto guarda, que é? É o centro do clipe de filme? Você fala dele como um ponto constante, mas se temos um objeto irregular podem haver vários pontos em que ele pode colidir com qualquer outra coisa.

E mais uma pergunta, de um novato-flash - tem como relacionar a clipes como um array? Por exemplo, ter um array chamado bricks[] e cada clipe de um brick tera esse nome, e em cada ciclo eu poderia dar um for(i=0;i<count(bricks);i++) pra ver se ele vai ou não colidir com um brick? Ou, talvez, chamar todos pelo mesmo nome e fazer só uma verificação de colisão? Alguma maneira diferente de ter um nome para cada brick e verificar em cada ciclo se ele foi colidido?...
...and may the grand !MooXooM! above enlighten your path.

<?php
function sex($cromo1, $cromo2){ //É talvez a função mais triste que eu já fiz.
...
}
?>

#4 Patrique

Patrique

    Super Veterano

  • Usuários
  • 1859 posts
  • Sexo:Não informado

Posted 01/08/2005, 19:43

E ai Gilthans beleza mano

Cara quem fez este tuto foi o Gary Fixler como eu coloquei lá.

Entaum eu naum sei te dizer o que ele quis dizer com ponto guarda... na verdade eu nunca tentei fazer este tuto, apenas pensei que era isso que tu queria... mais é o seguinte eu tenho um fla igual ao que vc quer vou tentar colocar aqui... mas caso de erro me mande uma MP com seu e-mail que eu te envio ok (y)

Um abraço,
Patrique André

Attached Files

  • Attached File  bolas   5.38KB   13 downloads





1 user(s) are reading this topic

0 membro(s), 1 visitante(s) e 0 membros anônimo(s)

IPB Skin By Virteq