[pedido] Gambiarras pro GMS

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

[pedido] Gambiarras pro GMS

Mensagem por saim em Qua 27 Fev 2013, 13:14

Acabei de perceber que "screen_redraw()" está entre as "obsolete functions". Perceber esse tipo de coisa já é irritante. Quando se trata de uma função que a gente está acostumado a usar, então, me faz deixar um rastro de fogo e destruição por onde eu passo.

Eu quero criar uma pausa sem muito trabalho, mantendo as velocidades dos objetos, a situação dos alarmes, um monte de coisinhas. Minha rotinha é (ou era):
- criar uma surface
- desenhar a tela na surface
- desativar todas as instâncias, mantendo apenas a que fez os passos acima, que passa a mostrar a surface por baixo da palavra "pausa"
Pro passo em itálico, eu usava "screen_redraw()".

Agora estou mandando todos os objetos executarem o evento draw, mas isso não traz as partículas para a surface, além de me obrigar a CRIAR um evento draw pra todos os objetos (antes não precisava).

Então queria alguma gambiarra que resolvesse isso de uma forma melhor.
Na verdade, eu queria um monte de gambiarras, que refizessem as funções que foram perdidas do GM8. Se conseguirmos criar essa surface com a cara da tela, eu tenho um monte de idéias pra room_transition's, que também foram perdidas.

Quem conhece alguma idéia? Vamos fazer desse, um tópico de consulta, para referências futuras.

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: [pedido] Gambiarras pro GMS

Mensagem por PedroX em Qua 27 Fev 2013, 14:35

Segundo esse tópico, as funções screen_save() e background_add() não estão obsoletas. Será que dá pra usar?

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

Re: [pedido] Gambiarras pro GMS

Mensagem por Kabeção em Qua 27 Fev 2013, 14:39

Use view_surface_id para linkar uma surface a uma view.
A surface será atualizada automaticamente com a imagem da view, então na hora de pausar faça uma cópia dela e desenhe isso.

Dá pra considerar view_surface_id o novo screen_redraw.
Eu não testei muita essa função mas ao que parece desde que view_visible seja true não importa se a area da view esta realmente aparecendo na tela, a surface será desenhada normalmente.
Também ao fazer esse link parece que a view especificada não é mais desenhada automaticamente pois os eventos de desenhos que antes iam para a surface principal (tela do jogo propriamente dita) agora vão para essa surface separada.

Kabeção

Ranking : Sem avaliações
Número de Mensagens : 2314
Data de inscrição : 08/06/2008
Reputação : 100
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 3
   : 0
   : 1

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

Voltar ao Topo Ir em baixo

Re: [pedido] Gambiarras pro GMS

Mensagem por Rodrigo Santiago em Qua 27 Fev 2013, 14:51

Sprite_add_from_screen faz exatamente a mesama coisa so que faz em uma sprite en vez de surface(vc ja deve saber) ela e obsoleta tambem?

Rodrigo Santiago

Ranking : Nota B
Número de Mensagens : 1281
Idade : 20
Data de inscrição : 28/07/2012
Notas recebidas : C + C + B
Reputação : 73
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 3
   : 1
   : 3

Voltar ao Topo Ir em baixo

Re: [pedido] Gambiarras pro GMS

Mensagem por saim em Qua 16 Out 2013, 18:40

Desculpem a demora pra voltar a postar. Eu fiquei de olhar o assunto, fazer testes e voltar, acabou que nunca fiz teste nenhum até agora. Agora fiz e, como sempre que tento algo novo, não funcionou. Talvez eu não tenha entendido muito bem o que o manual diz... Pelo que li lá, a view usada pra view_surface_id deixa de ser desenhada na tela. Isso parece que acontece, mesmo.

Bom, usei view_surface_id, tanto no create quanto no evento "pausa". Desenhei a surface no draw e no drawGUI. Checando ou não pelo valor de "view_current".

Deixa eu ser mais específico... Na room, eu liguei as views 0 e 1. Porque quero usar a view 0 pra view_surface_id (o resultado foi igual a ter a view 0 desligada, mas deixar só a view 0 ligada deixa a tela em preto, desde o começo do teste).

Daí, no create, eu coloquei:
Código:
srf_pausa := surface_create(view_wview[0], view_hview[0]); // surface do tamanho da view
view_surface_id[0] := srf_pausa; // joga a view 0 pra surface

pausa := false; // define uma variável pra saber se é pra entrar ou sair da pausa
No evento de pausa (press space), eu coloquei o seguinte:
Código:
if (!pausa){ // se não está pausado
    instance_deactivate_all(1); // desliga todos, menos eu
    pausa := true; // fica pausado
    }
    else { // se está pausado
        instance_activate_all(); // liga todos
        pausa := false; // fica sem pausa
        }
e, no draw (tentei o drawGUI, também)
Código:
if (pausa){
    if (view_current == 1){ // tentei o valor 0 e tentei não fazer esse teste, tb
        draw_surface(srf_pausa, view_xview[0], view_yview[0]);
        }
    }
O resultado: os objetos (coloridos e agitados, feitos pra testar a pausa) somem ao ligar a pausa. Das duas, uma: ou eles não estão indo pra surface, ou a surface não está indo pra tela.
Depois, quando pausa volta a ser false, os objetos continuam do ponto em que estavam.

code dos objetos coloridos:
create:
Código:
direction := random(360);
speed := 2 + random(4);

cor := random($ffffff);
outside view 0:
Código:
x := view_xview[0] + view_wview[0] / 2;
y := view_yview[0] + view_hview[0] / 2;

x += random(60) - 30;
y += random(60) - 30;
draw:
Código:
draw_circle_color(x, y, 5, cor, c_black, 0);

Onde está meu erro? Como corrigir?

Edit: @Rodrigo: sim, sprite_create_from_screen está obsoleta. Não respondi antes porque não tinha visto a sugestão (fiquei um tempo sem me preocupar com esse tópico, daí ele sumiu e o resto é história...)

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: [pedido] Gambiarras pro GMS

Mensagem por PedroX em Qua 16 Out 2013, 19:30

Quando você desativa-os, eles param de ser desenhados na view e consequentemente na surface. A surface continua a ser atualizada em conjunto com a view, então os objetos somem mesmo. O que você pode fazer é:

Código:
srf_pausa := surface_create(view_wview[0], view_hview[0]);
Código:
   if (!pausa){ // se não está pausado
        view_surface_id[0] := srf_pausa; //faz a cópia, que acredito que seja instantânea
        view_surface_id[0] := -1; //para de desenhar na surface
        
        instance_deactivate_all(1); // desliga todos, menos eu
        pausa := true; // fica pausado
        }
        else { // se está pausado
            instance_activate_all(); // liga todos
            pausa := false; // fica sem pausa
            }
Algo assim deve resolver.

Ah, gostaria de dizer que, para cada view ativa, o Draw é executado uma vez. Ou seja, você usa view_current para saber qual view está sendo desenhada agora. Ou seja, é 1 mesmo. Não use 0 porque seria contraditório.

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

Re: [pedido] Gambiarras pro GMS

Mensagem por saim em Qui 17 Out 2013, 00:08

Quase, PedroX! Seu código não funcionou, mas seus comentários valeram ouro!

PedroX escreveu:Quando você desativa-os, eles param de ser desenhados na view e consequentemente na surface. A surface continua a ser atualizada em conjunto com a view, então os objetos somem mesmo.
Claro! Como eu não vi isso? Nada mandou a view parar de se atualizar! Onde eu estava com a cabeça?
PedroX escreveu:Ah, gostaria de dizer que, para cada view ativa, o Draw é executado uma vez. Ou seja, você usa view_current para saber qual view está sendo desenhada agora. Ou seja, é 1 mesmo. Não use 0 porque seria contraditório.
Eu testei o 0 porque poderia ter entendido mal o manual. Achei que teria que desenhar a view[0] manualmente, quando a view_current fosse zero...
Mas esse comentário foi importante pra me fazer perceber que a view usada (0, no caso) TEM que estar ativa. Agora isso está bem claro, mas na minha cabeça bagunçada, parecia lógico que, se a view vai deixar de ser desenhada na tela, mesmo, nenhum problema em deixá-la desativada...

Bom, mas o quente é que eu consegui congelar todo mundo! O view_surface_id não é instantâneo, mas e daí? Podemos jogar o que quer que esteja na view numa outra surface que NÃO vá ser atualizada e pronto.
Quer dizer... "e pronto" pra jogos que só usam uma view... Acho que minha solução não serve pra múltiplas views... mas já é alguma coisa, de qualquer forma.
A solução é assim:
create
Código:
srf_pausa := surface_create(view_wview[0], view_hview[0]); // a surface que vai pra tela
srf_view := surface_create(view_wview[0], view_hview[0]); // a surface que NÃO vai pra tela
view_surface_id[0] := srf_view; // joga a tela nessa surface

pausa := false; // se está em pausa
evento-pausa (no caso, apertar espaço)
Código:
if (!pausa){ // se não está pausado
    instance_deactivate_all(1); // desliga todos, menos eu
    pausa := true; // fica pausado
    
    surface_set_target(srf_pausa); // abre a surface-pausa
    draw_clear_alpha($000000, 0); // passa um paninho
    draw_surface(srf_view, 0, 0); // joga a tela nela
    surface_reset_target(); // volta pra tela
    
    }
    else { // se está pausado
        instance_activate_all(); // liga todos
        pausa := false; // fica sem pausa
        }
no draw, claro:
Código:
if (pausa){ // se está em pausa
    draw_surface(srf_pausa, view_xview[0], view_yview[0]); // desenha a surface
    }
Como eu só tenho duas views, a surface só pode ser desenhada na view 1. Então não me preocupei com o que acontece se houverem mais views.

Alguém disposto a melhorar o código, deixando ele funcional pra múltiplas views, como jogos com split-screen? Parece que dá pra fazer usando uma view de pausa pra cada view na tela, então Kudos se conseguir isso "gastando" apenas uma view.

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: [pedido] Gambiarras pro GMS

Mensagem por saim em Qui 17 Out 2013, 09:32

Não saquei... Isso foi testado e funcionou? Eu ainda estou raciocinando como no seu code "fail".
Meu problema, aqui, está em jogar as demais views pra dentro da view 0. Como isso é feito? A forma que eu conhecia de fazer isso era usando screen_redraw, que caducou.

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: [pedido] Gambiarras pro GMS

Mensagem por fredcobain em Qui 17 Out 2013, 10:21

Bom, no intuito de tentar ajudar, fiz uma pesquisa no fórum do GMC.

Algumas respostas foram:

Solução 1) Baixe o tutorial de surfaces do GMStudio que lá isso foi resolvido de outro jeito.

"Honestly, the new way to use surfaces is explained there and there is also a detailed tutorial included with Studio that shows how to do all sorts of effects quickly and easily." (muito vago)

Solução 2) Falaram que dá pra fazer uma gambiarra com a função view_surface. (muito vago).

Solução 3) CreateEvent

Código:
do_draw=0;
Step Event

Código:
   do_draw=(do_draw+1)&7;
    if( do_draw!=0 ) draw_enable_drawevent(false); else draw_enable_drawevent(true);
"This will draw once out of every 8 frames. You can obviously reduce the time if required."

Solução 4) Draw Event
Código:

var _selfid;
_selfid = id;
with (all) {
   if id != _selfid {
      event_perform(ev_draw,0);
   }
}

fredcobain

Ranking : Sem avaliações
Número de Mensagens : 691
Idade : 35
Data de inscrição : 14/04/2011
Reputação : 162
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: [pedido] Gambiarras pro GMS

Mensagem por PedroX em Qui 17 Out 2013, 13:10

Supondo que no seu jogo você use 4 views, seria mais ou menos como abaixo.
Código:
view_visible[0] := false; //não vamos desenhá-la agora

//Vamos criar surfaces para desenhar nelas o conteúdo das views (cada surface tem o tamanho da sua view)
srf_view1 := surface_create(view_wview[1], view_hview[1]);
srf_view2 := surface_create(view_wview[2], view_hview[2]);
srf_view3 := surface_create(view_wview[3], view_hview[3]);
srf_view1 := surface_create(view_wview[4], view_hview[4]);

//Criamos uma surface onde desenharemos as outras 4, só durante a pausa
srf_final := surface_create(display_get_width(), display_get_height()); // alta conferir se é essa a função que pega o tamanho da janela

pausa := false;
Draw
Código:
if (pausa) // se estiver pausado
{
if (view_current > 0) exit; //não precisamos desenhar as outras views quando em pausa

draw_surface(srf_final, 0, 0); //desenha a surface que contém todas as outras
}
Alarm[0]:
Código:
//Vamos desenhar as surfaces parciais na surface final
    surface_set_target(srf_final);
    draw_clear_alpha($000000, 0);
    draw_surface(srf_view1, 0, 0);
    draw_surface(srf_view2, 320, 0);
    draw_surface(srf_view3, 0, 240);
    draw_surface(srf_view4, 320, 240);
    surface_reset_target();

  //Views voltam ao normal mas ficam invisíveis até a pausa terminar
  view_surface_id[1] = -1;
  view_surface_id[2] = -1;
  view_surface_id[3] = -1;
  view_surface_id[4] = -1;
  view_visible[1]=0;
  view_visible[2]=0;
  view_visible[3]=0;
  view_visible[4]=0;
}
Evento que pausa:
Código:
if (!pausa){
    alarm[0] = 2;
  //Fazemos as views desenharem nas surfaces até que o alarm normalize as views
  view_surface_id[1] = srf_view1;
  view_surface_id[2] = srf_view2;
  view_surface_id[3] = srf_view3;
  view_surface_id[4] = srf_view4;

    view_visible[0] = true; //ativa a view0, onde iremos desenhar a srf_final
    instance_deactivate_all(1); // desliga todos, menos eu
    pausa := true; // fica pausado
    }
    else { // se está pausado
        view_visible[0] := false; //paramos de usar essa view
        // Agora as outras views podem voltar a ser visíveis
        view_visible[1] = true;
        view_visible[2] = true;
        view_visible[3] = true;
        view_visible[4] = true;
        instance_activate_all(); // liga todos
        pausa := false; // fica sem pausa
        }
Editado: agora usa um alarm, para facilitar.


Última edição por PedroX em Sex 18 Out 2013, 17:53, editado 1 vez(es)

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

Re: [pedido] Gambiarras pro GMS

Mensagem por saim em Sex 18 Out 2013, 17:13

@ Fred: 1) rola de mandar o link? Se for só essa frase que tem lá, realmente é muito vago, mas pode ter alguma coisa a mais. Nem que seja pra pedir pro cara explicar melhor, eu gostaria de ver ao vivo.
2) Não seria view_surface_id? É onde estamos tentando chegar. Com apenas uma view, já está resolvido.
3 e 4) não vi o instance_activate/deactivate. Sem isso, não acontece a pausa, a menos que você coloque um codigozinho diferente em cada objeto (alguns jogos requerem isso pra efeitos especiais, mas estamos procurando uma solução mais universal). Ou tem alguma coisa que eu deixei escapar?

@ PedroX: Cara, não saquei o que você está tentando fazer. nervoso Não rola de comentar o código? Parece que você quer colocar todo mundo em view_surface_id's e jogar essas surfaces numa outra, que passa a ser desenhada. Mas o passo-a-passo é bem-vindo.
Deixa eu enumerar as dúvidas...
- Pra que eu precisaria mudar a view_surface_id a cada step? Se for só o caso de esperar um step, dá pra fazer um alarm, não?
- Aqueles valores em draw_surface seriam as view_x/yport? Se forem, já vou mudar pras variáveis de uma vez.
- Os dois últimos códigos vão no draw event? E no evento de pausa, vai só "pausa := !pausa"?

Perguntinha besta: "display", no windows, é o tamanho da janela do jogo ou do monitor?

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: [pedido] Gambiarras pro GMS

Mensagem por PedroX em Sex 18 Out 2013, 17:57

Pronto, saim. Modifiquei para alarm e comentei um pouco.

Mesmo assim, essas dúvidas precisam ser explicadas isoladamente:
- Aqueles valores em draw_surface seriam as view_x/yport? Se forem, já vou mudar pras variáveis de uma vez.
Na verdade, você coloca para a sua view ficar numa posição na room (esqueci se é port), é essa que você coloca no código. É um valor constante.

Perguntinha besta: "display", no windows, é o tamanho da janela do jogo ou do monitor?
Não me lembro.

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

Re: [pedido] Gambiarras pro GMS

Mensagem por fredcobain em Sex 18 Out 2013, 21:59

Saim, sobre o tutorial de surfaces, vc faz o download pelo próprio GMS.

fredcobain

Ranking : Sem avaliações
Número de Mensagens : 691
Idade : 35
Data de inscrição : 14/04/2011
Reputação : 162
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Re: [pedido] Gambiarras pro GMS

Mensagem por Conteúdo patrocinado Hoje à(s) 15:47


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