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
» Servidor de Discord do fórum?
por Super Games Sáb 18 maio 2024, 01:27

» Problemas com a caixa de diálogo, ela é pequena e as letras não cabem dentro
por Rukasu777 Qui 16 maio 2024, 18:10

» Problemas com particulas
por RastaMaan Dom 12 maio 2024, 17:03

» Problema ao entrar por uma porta e voltar por ela
por aminaro Seg 06 maio 2024, 10:08

» Alguém aqui já ganha dinheiro com seus games?
por theguitarmester Ter 30 Abr 2024, 11:43

» Colisões não funcionando
por theguitarmester Ter 30 Abr 2024, 10:16

» Como ajustar velocidade de cada frame da animação no game maker
por pequetux Sex 26 Abr 2024, 16:45

» Preciso de ajuda
por AftonDuGrau Dom 21 Abr 2024, 20:18

» Como faz o evento drawn GUI, não se repetir?
por aminaro Sex 19 Abr 2024, 20:30

» PROBLEMAS COM FÍSICAS DE ÁGUA
por aminaro Ter 16 Abr 2024, 10:07

» Retorno da GMBR!!!
por Ralphed Sex 12 Abr 2024, 22:45

» JOGADOR PARANDO NO AR QUANDO ATACA
por aminaro Qua 10 Abr 2024, 13:51

» Problemas com texto interativo
por Kaaru72 Dom 07 Abr 2024, 11:31

» Erro escondido e indecifrável
por dev_gabize.azv Qui 04 Abr 2024, 10:11

» Mudar cor de apenas uma palavra
por Ralphed Sáb 30 Mar 2024, 00:39

» Procuro Programador de game maker
por Wou Sex 15 Mar 2024, 10:27

» Mod APK
por gamerainha Qua 13 Mar 2024, 06:30

» Aceito pedidos de sprites (Com exemplos meus)
por Sevilha Qua 28 Fev 2024, 12:17

» Inventário simples
por Isquilo_Roedor Qui 22 Fev 2024, 15:18

» Problemas na programaçnao de inimigo [jogo DOOM LIKE]
por Black Mirror Dom 11 Fev 2024, 13:34

» ANDROID MULTI TOUCH
por DiegoBr Dom 04 Fev 2024, 12:13

» Save e Load Json
por Klinton Rodrigues Qui 25 Jan 2024, 11:12

» Colisão com mais de um objeto
por aminaro Seg 22 Jan 2024, 15:02

» Oi sou novo aqui
por Thiago Silveira Alexandre Sáb 20 Jan 2024, 20:55

» Como acessar conteudo comprado no marketplace
por macmilam Sex 19 Jan 2024, 07:42


solitaire

2 participantes

Ir para baixo

solitaire Empty solitaire

Mensagem por saim Qui 04 Out 2012, 15:54

Como exercício, estou fazendo um solitaire. Sempre achei que a programação desse tipo de jogo era mais complicada do que parece, agora estou sentindo na pele. Meu problema está em selecionar apenas a carta em que cliquei. As que estão abaixo dela serão arrastadas junto e as que estão acima dela DEVERIAM ser ignoradas. Por enquanto, eu ainda não tomei nenhuma providência pra verificar se as cartas abaixo daquela clicada estão em ordem, eu apenas verifico isso na hora de soltar uma carta sobre a outra.

Estou ciente que uma carta estar por cima da outra não elimina o evento do clique da carta abaixo dela. Pra contornar isso, eu verifico se existe alguma carta sobre aquela clicada. Se não houver, o evento pode acontecer normalmente. Se houver, o evento só acontece se o mouse estiver na área visível da carta. No código, a variável "borda" é o espaçamento-padrão do jogo, também usado pra separar uma carta da outra.

A título de organização, eu uso um monte de triggers pra arrastar a carta clicada, pra arrastar as cartas acima dela, pra soltar as cartas, etc.

Quando as cartas estão fora de ordem, a coisa funciona direitinho. Eu consigo arrastar todas as cartas acima da clicada e nenhuma carta abaixo dela.

Quando eu já organizei umas 3 cartas, o caldo entorna. Eu clico na carta de cima de todas e mesmo assim arrasto as que estão abaixo dela. Tenho certeza que é alguma coisa no evento do clique, porque se o mouse está na parte de baixo da sprite, numa parte que NÃO toca a mask da carta de baixo, ela não é arrastada. Mas, bom, eu vim aqui porque não sei o que diabos está acontecendo.

Estou usando os seguintes códigos:
left_press_event
Código:
// só rodar o evento se o mouse estiver no espaço visível da carta,
// evitando arrastar cartas que estejam sob o mouse, mas abaixo da escolhida
var rodaEvento; rodaEvento = false;
if (cartaSobre == noone){ // a carta toda é visível
   rodaEvento = true;
   }
   else { // só um espaço da carta é visível
      if (mouse_y == median(y, y + borda, mouse_y)){ // se o mouse está entre o topo e o começo da próxima carta
         rodaEvento = true;
         }
      }

if (rodaEvento == false){
   exit;
   }
   else {
      if (keyboard_check(vk_enter)){
         show_message(id);
         }
      }

if (noMonte == false){ // se não é a carta no topo da coluna
   var cartaUnder;
   with(objCarta){
      if (cartaSobre == other . id){ // se eu estou por cima da outra
         cartaUnder = id; // a outra está abaixo de mim
         }
      }
   ultimaPos = cartaUnder; // pra poder voltar em caso de movimento inválido
   cartaUnder . cartaSobre = noone; // pra carta abaixo de mim saber que não estou mais lá
   }
   else { // noMonte == true
      ultimaPos = instance_place(x, y, objMonteJogo);
      noMonte = false;
      with (ultimaPos){
         primeiraCarta = noone;
         }
      }
event_perform(ev_trigger, 0); // define dx e dy e passa a arrastar a carta
trigger 0:
Código:
// evento de tirar a carta do lugar
drag1 = true;
dx = x - mouse_x; dy = y - mouse_y;
if (depth > -100) {
   depth = -100;
   }
event_perform(ev_trigger, 2); // manda as cartas acima serem arrastadas também
trigger 2:
Código:
if (cartaSobre != noone){
   with(cartaSobre){
      drag2 = true;
      dx = x - mouse_x; dy = y - mouse_y;
      depth = other . depth - 1;
      event_perform(ev_trigger, 2); // é esse mesmo evento, na próxima carta
      }
   }
Talvez seja alguma coisa definida em outros eventos. A seguir, mais alguns eventos que podem ser considerados importantes:
create:
Código:
// algumas variáveis são declaradas por outros objetos, ao criar da carta.
// valor, drag, sprite_index
drag1 = false; //drag pra carta arrastada
drag2 = false; //drag pras cartas acima dela
cartaSobre = noone;
noMonte = false;
global_left_release:
Código:
if (drag1 == true){ // evita de rodar o código em muitas cartas
   // deixa de arrastar
   drag1 = false;

   var jogadaPermitida; jogadaPermitida = false;

   var cartaUnder, monteUnder; cartaUnder = noone; monteUnder = noone;
   with(objCarta){
      if place_meeting(x, y, other){ // se está em contato
         if (cartaSobre == noone){ // se é a última da coluna
            if (valor[valor52] == valor[other . valor52] + 1 && cor[valor52] != cor[other . valor52]){ // se o valor é 1 acima da carta solta e a cor é diferente
               cartaUnder = id;
               }
            }
         }
      }
   with(objMonteJogo){
      if (primeiraCarta == noone && place_meeting(x, y, other)){
         monteUnder = id;
         }
      }

   if (cartaUnder != noone){ // se é permitido soltar numa carta
      jogadaPermitida = true;
      x = cartaUnder . x; y = cartaUnder . y + borda;
      depth = cartaUnder . depth - 1;
      cartaUnder . cartaSobre = id;
      // noMonte = false;
      }
      else if (monteUnder != noone){ // se não tem carta, mas tem coluna vazia
         jogadaPermitida = true;
         x = monteUnder . x; y = monteUnder . y;
         depth = monteUnder . depth - 1;
         monteUnder . primeiraCarta = id;
         noMonte = true;
         }

   if (jogadaPermitida == false){
      switch (ultimaPos . object_index){ // ultimaPos = id da última posição
         case objMonteCompra: {
            with(objMonteCompra){
               ds_list_add(ds_cartasMonteCompra, other . valor52);
               nCartasTela = min(nCartasTela + 1, 3);
               }
               instance_destroy();
            }; break;
         case objCarta: {
            x = ultimaPos . x; y = ultimaPos . y + borda;
            depth = ultimaPos . depth - 1;
            ultimaPos . cartaSobre = id;
            }; break;
         case objMonteJogo: {
            x = ultimaPos . x; y = ultimaPos . y;
            depth = ultimaPos . depth - 1;
            noMonte = true;
            ultimaPos . primeiraCarta = id;
            }; break;
         }
      }

   event_perform(ev_trigger, 1); // traz todo mundo pro lugar e para de arrastar

   }
trigger 1:
Código:
// junta todo mundo no mesmo lugar
with (cartaSobre){
   x = other . x; y = other . y + borda; drag2 = false; depth = other . depth - 1;
   event_perform(ev_trigger, 1);
   }
e, não acho importante, mas já que estamos aqui, tem o step também...
Código:
if (drag1 == true || drag2 == true){
   x = mouse_x + dx; y = mouse_y + dy;
   }
Se precisar de alguma explicação quanto ao significado de variáveis ou coisas assim, podem perguntar. Eu não verifiquei se está tudo comentado.
saim
saim

Games Ranking : Nota B

Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios : solitaire Empty

Medalhas x 1 Tutoriais x 6 Moedas x 0

Ouro x 1 Prata x 0 Bronze x 3

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

Ir para o topo Ir para baixo

solitaire Empty Re: solitaire

Mensagem por Kabeção Qui 04 Out 2012, 18:57

É do tipo Paciência Spider?

Me parece que você está deixando a coisa mais complicada do que precisa ser. Happy

A começar pelo fato das próprias cartas controlarem suas ações. Isso da em confusão na certa.
Elas precisam apenas saber seu valor, sua coluna e o id da carta que está abaixo pois as de cima não interferem em nada, todo o resto pode ser controlado por outro objeto.
Com um controlador você tem mais precisam no debug já que não vai precisar monitorar um deck que pode até dezenas de cartas.

Na hora de checar a carta embaixo do mouse:
Código:
// objControle
if mouse_check_button_pressed(mb_left) {
    carta_id = noone;
    var yy;
    yy = 0;
   
    with (objCarta) {
        if (mouse_y > bbox_top && mouse_x > bbox_left && mouse_x < bbox_right) && y > yy {
            if instance_exists(carta_abaixo) {
                if (carta_abaixo.valor = valor-1) {
                    yy = y;
                    other.carta_id = id;
                }
            } else {
                yy = y;
                other.carta_id = id;
            }
        }
    }
}

if mouse_check_button(mb_left) && carta_id != noone {
    with (carta_id) {
        // ações
    }
}

O with torna essa tarefa mais fácil e precisa já que posso executar um código em todas as instancias do objCarta de uma vez e como eu trabalho apenas a variável carta_id do controlador eu removo qualquer possibilidade de duas ou mais cartas executarem suas ações ao mesmo tempo ou uma interferir com a outra.
Kabeção
Kabeção

Games Ranking : Sem avaliações

Data de inscrição : 08/06/2008
Reputação : 100
Número de Mensagens : 2314
Prêmios : solitaire Empty

Medalhas x 0 Tutoriais x 7 Moedas x 0

Ouro x 3 Prata x 0 Bronze x 1

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

http://blackcapapps.blogspot.com.br/

Ir para o topo Ir para baixo

solitaire Empty Re: solitaire

Mensagem por saim Qui 04 Out 2012, 19:49

Por alto é como o spider, mas é diferente. É o solitaire mesmo, do windows. Ah, agora entendi, ele agora vem traduzido! É o paciência.

Eu pensei nessa possibilidade mesmo, de usar um controlador, mas concluí que daria na mesma. Veja bem, o problema de usar o evento na própria carta é que pode selecionar mais de uma carta, certo? Isso foi contornado (em teoria) com a primeira parte do evento do clique. O problema é que tem uma diacha de uma situação em que isso não acontece.

Eu tenho outros objetos (os montes de onde comprar as cartas, os montes onde dispô-las no final) que também respondem aos cliques, por isso resolvi evitar o global_click.
Ah, e eu PRECISO interferir nas cartas que estão sobre a carta clicada, pra permitir arrastar uma coluna inteira de cartas que estão alinhadas. Portanto, preciso acompanhar quais cartas estão acima de quais. Eu posso fazer isso de um objeto externo, também, mas só se eu usar um "with(carta_id)", o que é o mesmo que rodar o código direto na carta.

Aparentemente, meu problema é isolar a carta clicada, mas estou com a impressão que não é isso... Eu tenho um debug_code que mostra a id da carta, repete o teste da posição do mouse, além de outras coisas e mostra em uma show_message. Quando eu testo isso, tudo acontece conforme esperado. Mas ao clicar na carta de cima que está em ordem, a de baixo ainda é arrastada...
saim
saim

Games Ranking : Nota B

Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios : solitaire Empty

Medalhas x 1 Tutoriais x 6 Moedas x 0

Ouro x 1 Prata x 0 Bronze x 3

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

Ir para o topo Ir para baixo

solitaire Empty Re: solitaire

Mensagem por Kabeção Sex 05 Out 2012, 12:51

Também não consigo ver o erro pelo código.
Talvez com um exemplo executável...

Porque não tenta reprogramar?
As vezes corrigir isso vai ser mais demorado ou mais trabalhoso do que refazer.
Kabeção
Kabeção

Games Ranking : Sem avaliações

Data de inscrição : 08/06/2008
Reputação : 100
Número de Mensagens : 2314
Prêmios : solitaire Empty

Medalhas x 0 Tutoriais x 7 Moedas x 0

Ouro x 3 Prata x 0 Bronze x 1

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

http://blackcapapps.blogspot.com.br/

Ir para o topo Ir para baixo

solitaire Empty Re: solitaire

Mensagem por saim Sex 05 Out 2012, 13:41

Hehehe... eu demorei pra enviar a edição da minha postagem anterior, você postou antes. Eis o que eu ia colocar:

Não, kabeção, você tem razão. Tem outros aspectos do jogo que podem ser agilizados ao usar mais ativamente o controle (eu posso abandonar códigos recursivos e usar loops simples). Vou refazer os códigos.
Na prática, esse tópico perdeu o sentido, já que os códigos serão bem diferentes. Se alguém conseguir identificar o erro, a título de curiosidade, me mande uma MP. No mais, podem trancar o tópico.

Ou seja, concordo plenamente. Acho que recomeçar, nesse caso, tem mais vantagens que desvantagens.

Obrigado!
saim
saim

Games Ranking : Nota B

Notas recebidas : C-D-A-B
Data de inscrição : 14/01/2011
Reputação : 136
Número de Mensagens : 3033
Prêmios : solitaire Empty

Medalhas x 1 Tutoriais x 6 Moedas x 0

Ouro x 1 Prata x 0 Bronze x 3

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

Ir para o topo Ir para baixo

solitaire Empty Re: solitaire

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