A incrivel lógica de tetris

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

A incrivel lógica de tetris

Mensagem por Maker em Qua 07 Set 2011, 10:21

Tenho praticamente todo o jogo feito.

Só não consegui fazer e nem entender como que quando a linha estiver completa, ela é destruida e as de cima descem..

Por que como cada sprite já tem um formato definido, se a linha for destruida ela mudaria de formato, ou seja, algum trecho dela foi destruído.

Qual é a lógica para conseguir fazer isso?

Maker

Número de Mensagens : 51
Data de inscrição : 09/06/2008
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Igor KinGamer em Qua 07 Set 2011, 11:05

Quando os blocos "pousam", você tem que transformá-los em vários blocos separados. Assim, não haverá problema nenhum em descobrir se a linha está completa e em deletá-la.


Igor KinGamer

Número de Mensagens : 890
Idade : 21
Data de inscrição : 26/09/2008
Reputação : 11
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Maker em Qua 07 Set 2011, 11:28

Igor KinGamer escreveu:Quando os blocos "pousam", você tem que transformá-los em vários blocos separados. Assim, não haverá problema nenhum em descobrir se a linha está completa e em deletá-la.

Eu fiz assim,
Quando os objetos 'pousam', um variavel booleana fica True para dar sequencia.

Então eu teria que fazer com que quando 'pousar', o objeto se torne em vários objetos?
Então também teria que ter um sprite/objeto de apenas um quadrado.

Mas como eu transformo a forma de um peça, exemplo T, em quadradinho com o formato de T?

Acho que a lógica eu entendi, pois assim seria possível destruir apenas a linha, mas não entendi como posso 'transformar'. =o

Maker

Número de Mensagens : 51
Data de inscrição : 09/06/2008
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Igor KinGamer em Qua 07 Set 2011, 11:38

Na hora em que a peça parar, é só você usar o instance_destroy() para destruí-la e instance_create() para criar os blocos nas suas posições. Só que você tem que saber quais as posições certas em que os blocos devem aparecer para colocar no instance_create().
Por exemplo, a peça em forma de L. Se ela chegasse ao chão nessa posição (um L sem rotação), você colocaria (supondo que a origem do sprite seja (0, 0) e os blocos sejam de 16x16):

Código:
instance_destroy();
instance_create(x, y, obj_Bloco);
instance_create(x, y+16, obj_Bloco);
instance_create(x, y+32, obj_Bloco);
instance_create(x+16, y+32, obj_Bloco);

Esse jeito é meio antiprático, porque você teria que fazer esses códigos para cada posição rotacionada de cada bloco, mas é o mais simples.
Eu pensei em um jeito mais prático (e um pouco mais complicado, dependendo do ponto de vista) de fazer isso, se você quiser, eu falo.

Igor KinGamer

Número de Mensagens : 890
Idade : 21
Data de inscrição : 26/09/2008
Reputação : 11
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Maker em Qua 07 Set 2011, 11:47

Igor KinGamer escreveu:Na hora em que a peça parar, é só você usar o instance_destroy() para destruí-la e instance_create() para criar os blocos nas suas posições. Só que você tem que saber quais as posições certas em que os blocos devem aparecer para colocar no instance_create().
Por exemplo, a peça em forma de L. Se ela chegasse ao chão nessa posição (um L sem rotação), você colocaria (supondo que a origem do sprite seja (0, 0) e os blocos sejam de 16x16):

Código:
instance_destroy();
instance_create(x, y, obj_Bloco);
instance_create(x, y+16, obj_Bloco);
instance_create(x, y+32, obj_Bloco);
instance_create(x+16, y+32, obj_Bloco);

Esse jeito é meio antiprático, porque você teria que fazer esses códigos para cada posição rotacionada de cada bloco, mas é o mais simples.
Eu pensei em um jeito mais prático (e um pouco mais complicado, dependendo do ponto de vista) de fazer isso, se você quiser, eu falo.
Acho que entendi o que você disse, mas realmente daria muito trabalho.

Poderia falar o outro jeito.

De qualquer forma estou tentando aqui fazer da 1º maneira.

Maker

Número de Mensagens : 51
Data de inscrição : 09/06/2008
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Igor KinGamer em Qua 07 Set 2011, 12:22

Você teria que fazer dois loops for aninhados (um dentro do outro) para verificar todas as posições em que pode haver uma parte da peça e, se houver, criar o bloco.
Não entendeu? Imagino que não, é meio complicado explicar assim... Vou mostrar numa imagem (estou quase terminando, só espere um pouco (mais)).


Caso você não saiba, bbox_left/top/right/down são variáveis que armazenam, normalmente (a não ser que você tenha mudado nas propriedades do sprite) a posição das bordas do sprite.



1 - O retângulo vermelho representa todo o espaço que a peça pode estar ocupando. Ele é determinado pelas bordas do sprite. O ponto inicial é (bbox_left, bbox_top) e o final é (bbox_right, bbox_down).

2 - Como o tamanho dos blocos é de 16x16 pixels, existem, neste caso, seis posições em que pode haver blocos. Nós estamos vendo claramente onde há, mas o computador não sabe. Então, ele tem que testar posição por posição, para descobrir isso.

3 - Uma vez que o computador descobre onde devem existir os blocos, ele os coloca e deleta a peça.

4 - Esse método funcionará com qualquer peça, com qualquer formato, sem precisar de nenhuma alteração.

Transformando isso em códigos (na peça que chegou ao chão), ficaria assim:

for (a = bbox_top; a < bbox_down; a += 16)
for (l = bbox_left; l < bbox_right; l += 16)
if (instance_position(l, a, self))
instance_create(l, a, obj_Bloco);
instance_destroy();


a e l representam altura e largura.
A imagem toda é percorrida em blocos de 16x16. Em cada ponto, se a própria peça estiver ali (é o que o instance_position() dirá), é criado um obj_Bloco.
Obs.: O Precise collision checking dos sprites deve estar ativado.

Igor KinGamer

Número de Mensagens : 890
Idade : 21
Data de inscrição : 26/09/2008
Reputação : 11
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Maker em Qua 07 Set 2011, 13:11

Não deu.. agora a peça desaparece.

Vou postar meu projeto aqui pra vc dar uma olhada.

Coloquei tudo no script scr_stop.
E rodei este script para testar na peça "lr" quando se colidir com o "obj_wallstop".
Fico no aguardo.

http://www.megaupload.com/?d=RJ9CS4JR

Maker

Número de Mensagens : 51
Data de inscrição : 09/06/2008
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Igor KinGamer em Qua 07 Set 2011, 13:30

Foi um erro meu. Em vez de
if (instance_position(l, a, self))
o certo é:
if (instance_position(l, a, object_index) == id)
Fazendo isso, já dá certo.

Vendo seu projeto, vi que tem alguns bugs, por exemplo, aquela peça que são quatro blocos numa linha só vem horizontalmente desalinhado.
Como todos os blocos terão absolutamente a mesma atitude, eu sugiro que você, em vez de colocar todos os códigos em todos os objetos das peças, crie um objeto "peça pai", o coloque como parent de todas as peças e coloque nele todos os códigos. Assim, todos agirão conforme os códigos dele. Se não sabe como usar o parent, eu posso te mostrar como se faz.

Igor KinGamer

Número de Mensagens : 890
Idade : 21
Data de inscrição : 26/09/2008
Reputação : 11
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Maker em Qua 07 Set 2011, 13:37

Igor KinGamer escreveu:Foi um erro meu. Em vez de
if (instance_position(l, a, self))
o certo é:
if (instance_position(l, a, object_index) == id)
Fazendo isso, já dá certo.

Vendo seu projeto, vi que tem alguns bugs, por exemplo, aquela peça que são quatro blocos numa linha só vem horizontalmente desalinhado.
Como todos os blocos terão absolutamente a mesma atitude, eu sugiro que você, em vez de colocar todos os códigos em todos os objetos das peças, crie um objeto "peça pai", o coloque como parent de todas as peças e coloque nele todos os códigos. Assim, todos agirão conforme os códigos dele. Se não sabe como usar o parent, eu posso te mostrar como se faz.

Ae agora deu certo!!

Muito obrigado..
Realmente a lógica do meu jogo está certa, mas feita de uma maneira errada (?).

Não sabe dessa de parent, eu sei programar e talz, mas não entendo muito sobre as coisas do Game Maker, inclusive da biblioteca dela.

Só mais duas coisinhas para eu parar de encher o saco...
1º - Como fazer então para todas as peças (incluindo a I) estarem todas certinhas ao descer e ao rodar, ou seja, sem estarem desalinhadas.
2º - Como usar parent? qualquer coisa eu procuro no Google depois para não te atrapalhar muito.

Maker

Número de Mensagens : 51
Data de inscrição : 09/06/2008
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Igor KinGamer em Qua 07 Set 2011, 13:55

1 - O x e y da origem de todas as peças deve ser múltiplo de 16. Como você centralizou a do I, ficou em (8, 32). Você só deve tomar cuidado na rotação, para que o bloco não possa entrar na parede (não sei se você já fez isso, porque não tenho o GM 8 Pro, e image_angle só fuciona no Pro).

2 - Basicamente, é isso:
> Quando você coloca um obj_Pai como parent de outros objetos, obj_Filho1, obj_Filho2 e obj_Filho3, por exemplo, estes três herdam os eventos do obj_Pai. Como acontece isso:
Eles só herdarão os eventos se não tiverem próprios. Ou seja, se o obj_Filho1 tiver códigos no create e o obj_Filho2 não, o obj_Filho1 ficará com os seus próprios códigos, já o obj_Filho2 pegará os do pai.
> Tudo o que você faz com o obj_Pai acontece com os filhos.
Se você testa uma colisão com o obj_Pai, ela será realizada normalmente se ocorrer com algum dos filhos.
Em diversas situações, se você usar obj_Pai, funcionará como se estivesse usando também obj_Filho1/2/3, por exemplo:
Código:
if (instance_position(mouse_x, mouse_y, obj_Pai))
show_message("HA!");
A mensagem será mostrada se você colocar o mouse em cima do obj_Pai, mas também se colocar em cima de qualquer um dos filhos.
Código:
with (obj_Pai)
instance_destroy();
Destruirá todas as instâncias do obj_Pai e também dos obj_Filho1/2/3.

Em outras palavras, você tem que deixar os filhos com os eventos vazios, apenas com os seus sprites e o obj_Pai como parent, e colocar todos os códigos nesse obj_Pai.
Vê aí se você consegue fazer. Smile

Igor KinGamer

Número de Mensagens : 890
Idade : 21
Data de inscrição : 26/09/2008
Reputação : 11
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Maker em Qua 07 Set 2011, 14:02

Igor KinGamer escreveu:1 - O x e y da origem de todas as peças deve ser múltiplo de 16. Como você centralizou a do I, ficou em (8, 32). Você só deve tomar cuidado na rotação, para que o bloco não possa entrar na parede (não sei se você já fez isso, porque não tenho o GM 8 Pro, e image_angle só fuciona no Pro).

2 - Basicamente, é isso:
> Quando você coloca um obj_Pai como parent de outros objetos, obj_Filho1, obj_Filho2 e obj_Filho3, por exemplo, estes três herdam os eventos do obj_Pai. Como acontece isso:
Eles só herdarão os eventos se não tiverem próprios. Ou seja, se o obj_Filho1 tiver códigos no create e o obj_Filho2 não, o obj_Filho1 ficará com os seus próprios códigos, já o obj_Filho2 pegará os do pai.
> Tudo o que você faz com o obj_Pai acontece com os filhos.
Se você testa uma colisão com o obj_Pai, ela será realizada normalmente se ocorrer com algum dos filhos.
Em diversas situações, se você usar obj_Pai, funcionará como se estivesse usando também obj_Filho1/2/3, por exemplo:
Código:
if (instance_position(mouse_x, mouse_y, obj_Pai))
show_message("HA!");
A mensagem será mostrada se você colocar o mouse em cima do obj_Pai, mas também se colocar em cima de qualquer um dos filhos.
Código:
with (obj_Pai)
instance_destroy();
Destruirá todas as instâncias do obj_Pai e também dos obj_Filho1/2/3.

Em outras palavras, você tem que deixar os filhos com os eventos vazios, apenas com os seus sprites e o obj_Pai como parent, e colocar todos os códigos nesse obj_Pai.
Vê aí se você consegue fazer. Smile
1 - Quando a peça gira ela entra na parede, não faço idéia de como arruma já que o center da imagem é bem no centro mesmo.. faz com que as pontas se tornem'imagens'.

2 - Tentarei.

Obrigado.
=D

Maker

Número de Mensagens : 51
Data de inscrição : 09/06/2008
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

Mensagem por Igor KinGamer em Qua 07 Set 2011, 14:06

Maker escreveu:1 - Quando a peça gira ela entra na parede, não faço idéia de como arruma já que o center da imagem é bem no centro mesmo.. faz com que as pontas se tornem'imagens'.
Após girar, você pode testar se entrou na parede e, se entrou, girar de volta.

Código:
image_angle -= 90;
if (!place_free(x, y))
image_angle += 90;

Igor KinGamer

Número de Mensagens : 890
Idade : 21
Data de inscrição : 26/09/2008
Reputação : 11
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   :
   :
   :

Voltar ao Topo Ir em baixo

Re: A incrivel lógica de tetris

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


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