[Tutorial] Um Único Script para Todos Diálogos do Jogo

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

[Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por dharrison em Sab 20 Nov 2010, 01:12

Uhul! Mais uma vez eu aqui hoje!
(realmente to sem o que fazer, o forum inteiro ta na balada essas horas e eu aqui auhssauh)

Venho apresentar um tutorial do qual eu sinto orgulho *-*
Levei muitas horas para desenvolver esse método, mas ficou bem legal e simples de editar (uma vez que esteja pronto).

Sem mais delongas, vamos ao tuto:

Um Único Script para Todos Diálogos do Jogo
Objetivo: usar um script, com os comandos keyboard_wait, io_clear e screen_refresh, combinado com variáveis globais e objetos parent. Tudo isso para armazenar, em um único script, todos diálogos e caixas de texto do jogo.
Dificuldade: Média, se feito corretamente.
Ferramenta: GM7 Pro.

Engine para Começar o Tutorial: Script de Diálogo - Base.gmk

ATENÇÃO: Estou fazendo esse Tutorial, assumindo que você ao menos já viu meu tutorial anterior: Criar um Pause Personalizado.
Portanto não vou explicar novamente as funções que já usamos, e tão pouco vou dizer como se fazer os sprites.
Por isso a engine já está semi-pronta, só faltam os códigos (que é nosso foco de estudo).


MATERIAL:
- Seu cerebro
- Seu PC
- Seu GM
- Seus Dedos
lol!


MODO DE PREPARO:

Ao abrir o projeto, você perceberá que é o meu projeto atual (que estou desenvolvendo), você poderá explorar os scripts e irá encontrar o Pause Personalizado, e o Corações Estilo Zelda que ensinei hoje como fazer.
Como o projeto é algo em que estou trabalhando agora, peço que não copiem os sprites ou qualquer outra atitude de má fé. Não é pra isso que disponibilizei.

Chega de blá-blá-blá, vamos ao tuto:

Primeiramente abra a pasta Controladores (Em Objects), abra o obj_declarador e no local indicado coloque:
Código:
global.draw = 0
global.falador = 0
Importante: eles devem ficar acima do comando room_goto(room0), senão vai bugar.
Só lembrando que o obj_declarador está sendo usado para declarar vars que sejam globais e que permanecerão durante todo o jogo. Creditos ao SIGILOSO por essa dica.

Agora crie um novo Obj, e chame-o de obj_faladorparent. Ele vai definir a global 'falador' para outros objetos.
Torne-o Visivel e Sólido.
Adicione um evento Step nele e coloque:
Código:
if distance_to_object(Hero) <= 4 //Se qualquer parent dele estiver a 4 ou menos pxl do Hero.
{
global.falador = self //a var global.falador se torna o próprio objeto. (descobri hoje esse comando self, com ele você pode declarar códigos para que sejam executados no proprio objeto, gostei)
}
else
{
global.falador = 0 http://global.falador volta a ser 0 (valor original, apenas para anular a var).
}

if Hero.falando = true and distance_to_object(Hero) <= 4 //Se a variavel Falando de Hero for True (ela é ativada ao apertar a tecla W, é como qualquer outra variavel baseada em teclas, como Direta por exemplo)
{
    if global.falador variable_local_exists(texto) //Se global.falador (que agora é o objeto) tiver a varivel local Texto.
    {
    global.draw = texto //Então a variável global.draw se torna igual a variavel Texto (1, 2, 3, 4, e assim por diante)
    }
scr_dialogos() //o Scrip Dialogos (que é o Script_em_Branco) é executado.
//IMPORTANTE: A formula acima de scr_dialogos() determina quais valores serão válidos DENTRO do script scr_dialogos. Portanto nunca deixe-o acima, sempre abaixo.
}
else
{
global.draw = 0 //Se não, global.draw volta ao seu valor padrão, que é 0
}

Pronto, agora temos o Parent para criar dialogos. Isso vai ajudar porque você determinou os códigos uma única vez, e para usá-lo é só associar o NPC, Baú, Placa, etc... Como parent desse objeto.


Agora crie 4 Objetos, da respectiva forma:
- mocinha_1 (Visible, Não Solido, NPCmask, Parent: obj_faladorparent, Evento Create: Texto = 1)
- carinha_1 (Visible, Não Solido, NPCmask, Parent: obj_faladorparent, Evento Create: Texto = 2)
- caixa_1 (Visible, Não Solido, BOXmask, Parent: obj_faladorparent, Evento Create: Texto = 3)
- mocinha_2 (Visible, Não Solido, NPCmask, Parent: obj_faladorparent, Evento Create: Texto = 4)

Os sprites para esses objetos estão prontos já, são s_carinha, s_mocinha, s_box (as duas obj_mocinha usam o mesmo sprite, você entenderá o porque).
Não se esqueça de colocar as Masks indicadas. A Caixa tem uma mask exclusiva dela.

Por ultimo, entre no Obj Hero e faça um evento Collision com o obj_faladorparent. Dentro dele arraste o Drag&Drop chamado Move Fixed (é o primeiro, um quadradinho com 8 flechas vermelhas apontando para todas as direções).
Quando a janela dele abrir, clique com o mouse no ponto no meio das flechas, coloque 0 no Speed, e marque a caixa Relative. Isso fará com que Hero não atravesse os Parentes do obj_faladorparent.

Antes de continuar, vá até a room0 e coloque os objetos como desejar.
E agora vamos a uma breve explicação do que fizemos até agora.

1º - Nós criamos as variaveis global.falador, que vai definir qual objeto é aquele que 'está falando' com o Hero.
E a variavel global.draw, que no script a seguir, vai definir o que o objeto está dizendo.
A global.falador, vai receber seus valores do obj_faladorparent, que programos para que o Objeto Parente que estiver mais próximo do Hero se torne o falador. (atravez do distance_to_object).
A global.draw, vai receber seus valores direto dos eventos Create dos Objetos Parente (mocinha_1, carinha_1, etc), por isso é ESSENCIAL que cada um carregue um numero ÚNICO para ele (Texto = 1, Texto = 2... Texto = 100).

2º - Criamos o obj_faladorparent, que é um controlador. É ele que vai definir se o Hero pode ou não ativar os dialogos dos outros objetos, e qual deles deve 'falar'. Todo objeto que vai criar uma caixa de texto deve tê-lo como parent, se não simplesmente não funciona.

3º - Criamos os Objetos Parente com os quais Hero vai interagir, todos são Não Sólidos, mas o parent é sólido. E quando Hero colidir com qualquer parente do obj_faladorparent, ele vai parar. O único objetivo desses objetos é mostrar o sprite na tela, carregar a variavel local texto = Nº no evento Create... e só.

4º - Fizemos uma Colisão de Hero com o obj_faladorparent. Dessa forma quando Hero colidir com qualquer Obj vinculado ao parent, vai parar. As masks tem um papel importante aqui também, pois se você observar bem o Eixo dos Sprites, e o Tamanho das Masks, vai ver que elas foram feitas para ficar 'sobre' o rosto dos NPCs, assim o Hero pode chegar realmente perto deles para conversar, dando mais qualidade ao jogo.

Pronto Very Happy
Agora vamos ao nosso script.
Esse é bem grande, vou explicar as coisas dentro dele e fora dele. Não vou explicar muito sobre draw, pois ja expliquei um pouco no tutorial anterior, e também não é isso que viemos estudar.
Se você não manja nadinha de draw, siga esses tutorias do fonetico:

Aulas de Draw por fonetico
Duas Engine para aprender a desenhar um quadrado e uma linha no Evento Draw - Por Fonetico


Bom, lets go.
Vão em SCRIPTS, e abram a pasta Diálogos. Renomeie o Script_em_Branco para scr_dialogos.
E vamos preenche-lo.
Código:
{
    draw_set_color(c_black) ; //Esse escolhe a cor das bordas do retângulo
    draw_rectangle(Hero.x+90,Hero.y-90,Hero.x-90,Hero.y-170,true)
    draw_set_color(c_dkgray) //Esse escolhe a cor do retangulo
    draw_rectangle(Hero.x+89,Hero.y-89,Hero.x-89,Hero.y-169,false)
    draw_set_color(c_white) //Esse aqui escolhe a cor das letras
//Daqui em diante seguem os diferentes diálogos.
////Aqui no meio você vai colocar os Dialogos.\\\\\
//Aqui terminam todos os dialogos.
  screen_refresh();
  keyboard_wait();
{
  if (keyboard_lastkey == (ord('W')))
  {
  io_clear();
  }
  else
  {
  scr_dialogos();
  }
}
}

Se vocês repararem, é a mesma estrutura usada no Pause Personalizado. Mas com a tecla W para falar (se quiser você pode substituir por qualquer outra, exceto H e K, pois ja estão sendo usadas. Substitua no Step do Hero e depois aqui).
No entando os dialogos estão vazios!! confused

Bom é porque vamos colocar um por um agora, assim você poderá entender melhor:
Código:
//Dialogo Mocinha_1
        if global.draw = 1 //Se global.draw = 1, o texto é escrito. global.draw se torna 1 porque no Obj mocinha_1 declaramos que a var texto é = 1, e declamos no obj_parente que global.draw é igual á var_local do objeto que o Hero estiver mais próximo. Se não entendeu re-leia  as explicações acima.
        {
        draw_set_font(fontettl)
        draw_text(Hero.x-80,Hero.y-162,"Mocinha:")
        draw_set_font(fontetxt)
        draw_text(Hero.x-80,Hero.y-147," Esse foi o tutorial para# ter varios diálogos em# um único script.")
          //instance_create(x,y,mocinha_2)
          //instance_destroy()
        }
Digite esse código no espaço indicado. Os comandos instance_create e instante_destroy deixem desativados por enquanto.
As duas Fontes usadas também já estão no projeto, mas quando for fazer o seu terá que criar as suas.
Como eu disse, aqui focaremos no código.

Rode o jogo e fale com a mocinha, viu? foi igual dar Pause, mas no lugar de Pause apareceu um dialogo.

Agora vamos adicionar o dialogo do carinha_1.
"P*ta m*rda! Vo ter que fazer tudo isso dinovo???!!! anh! "
Não, como eu disse é um script só por jogo todo.
Logo abaixo do End of Block (isso aki } ) do Draw da Mocinha, coloque:
Código:
        //Dialogo do Carinha
        if global.draw = 2 //Se global.draw for 2 (que é o valor da var texto do Obj carinha_1), o dialogo dele aparece.
        {
        draw_set_font(fontettl)
        draw_text(Hero.x-80,Hero.y-162,"Carinha:")
        draw_set_font(fontetxt)
        draw_text(Hero.x-80,Hero.y-147,"Espero q tenha ajudado.# Atenciosamente:# DHarrison.")
        }
       
Pronto! Apenas fazendo isso você tem 2 dialogos com 2 objetos diferentes, no mesmo script!
Rode o jogo e fale com os dois NPCs. Viu que simples? *-*


O tutorial acaba aqui, mas vou adicionar um anexo, se você quiser ver mais formas de usar isso, continuemos:


ANEXO: Caixas de Texto e Falas Multiplas do Mesmo NPC.

Logo abaixo do End of Block ( isso -> } <- ) do draw do carinha_1, adicione:
Código:
//Dialogo da Caixa
        if global.draw = 3
        {
        draw_set_font(fontettl)
        draw_text(Hero.x-80,Hero.y-162,"Caixa:")
        draw_set_font(fontetxt)
        draw_text(Hero.x-80,Hero.y-147,"Nada de especial.#Apenas alguns pertences#do Carinha.")
        }
        //Dialogo Mocinha_2
        if global.draw = 4
        {
        draw_set_font(fontettl)
        draw_text(Hero.x-80,Hero.y-162,"Mocinha_2:")
        draw_set_font(fontetxt)
        draw_text(Hero.x-80,Hero.y-147,"Aqui foi um exemplo#de como fazer mais de#uma caixa de dialogo.")
            instance_create(x,y,mocinha_1)
            instance_destroy()
        }
Agora volte no global.draw = 1 (fala da mocinha_1) e retire as barras // dos comandos instance_create e instance_destroy.
Rode o jogo, fale com os dois personagens, e interaja com a Caixa. Viu?
Para fazer mais dialogos, basta criar novos Objetos, declarar no Nº de seus textos, e criar suas falas nesse único script.

uma ultima e breve explicação:
Como funcionou as duas caixas de Texto da mocinha.
Como você percebeu criamos 2 Obj Mocinha, cada um com um valor 'texto' diferente.
E depois criamos suas falas, e depois de suas falas, mas antes de fecha o código, um instance_create para a outra mocinha, e um instance_destroy para a atual.
Isso faz um 'looping' eterno, sempre que você falar com a 1, ela vai se autodestruir e criar a 2. E vice-versa.

Voce pode fazer isso com até 10 caixas de texto, basta criar um looping perfeito e deixar a primeira caixa (1) pelo menos á um numero de distancia das outras. por exemplo:
texto = 1; texto = 3; texto = 4; texto = 5.
"Por que?"
Sei lá, precentimento de bug eu acho ashuasuasuh
porque pela lógica do GM, se elas formarem um loop continuo, você pode acabar não podendo sair dos dialogos.
Aqui funcionou separado, pode ser bobeira minha ter dito isso, mas melhor previnir que remediar né? formado

Aqui a Engine da aula finalizada: Conclusão do Tuto: Dialogo em um Script+Pause Personalizado+HUD Zelda
Comandos:
W - Interagir
Setas - Andar
Enter - Pausar
(Esse é o arquivo atual do meu jogo, não PLAGIE!)

Mais uma vez obrigado a todos que me acompanharam até aqui, esse foi bem grande! Comentem sobre suas dúvidas/críticas/elogios.
Qualquer erro nos códigos me avisem.
E nos vemos no próximo ;)

Abração!
DHarrison


EDIT: Agora que lembrei, assim como no Pause Personalizado, nesse script vocês poderão usar um Fundo Personalizado para suas caixas de texto. tudo que vocês tem que fazer é:

Código:
{
    draw_sprite("nomedosprite",0, Hero.x+90,Hero.y-90) //As medidas de Hero.x e Hero.y vão variar de acordo com o sprite claro, mas é só ajustar ;D
    draw_set_color(c_white) //Esse escolhe a cor da fonte
//Daqui em diante seguem os diferentes diálogos.
////Aqui no meio você vai colocar os Dialogos.\\\\\
//Aqui terminam todos os dialogos.
  screen_refresh();
  keyboard_wait();
{
  if (keyboard_lastkey == (ord('W')))
  {
  io_clear();
  }
  else
  {
  scr_dialogos();
  }
}
}

E para que as caixas de texto sejam todas num determinado local da Tela. Usem view_xview e view_yview no lugar de TODOS Hero.x e Hero.y, respectivamente.


Última edição por dharrison em Sab 20 Nov 2010, 13:29, editado 3 vez(es) (Razão : Lembrei umas coisas que faltaram no tuto.)

dharrison

Ranking : Nota B
Número de Mensagens : 1243
Idade : 25
Data de inscrição : 04/02/2009
Notas recebidas : A - B
Reputação : 89
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Prêmios
   : 0
   : 1
   : 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por Markituh em Sab 20 Nov 2010, 11:54

Shocked Estou passado... xD

Parabéns,Dharrison, mais um ótimo tutorial para nós. Creio que, com este script, dê para fazer aquelas caixa de texto tipo Pokemon

O tutorial é tããão grande mais tããão grande que nem consegui ler Mad Percebi que desta vez, você não colocou qual vai ser o próximo tutorial... nervoso

Abraços!

___________

"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

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por camila.aparecida.5492 em Sab 31 Maio 2014, 20:25

Não estou conseguindo baixar a engine, pode consertar por favor!
estou precisando urgente  surpreso2  

camila.aparecida.5492

Número de Mensagens : 1
Data de inscrição : 24/10/2013
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por dharrison em Dom 01 Jun 2014, 13:02

Esse tutorial é antigo e percebi que não tenho mais a engine aki, mas basta vc criar os objetos usando sprites comuns (até quadrados) que os códigos irão funcionar normalmente

desculpe o incoveniente

dharrison

Ranking : Nota B
Número de Mensagens : 1243
Idade : 25
Data de inscrição : 04/02/2009
Notas recebidas : A - B
Reputação : 89
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Prêmios
   : 0
   : 1
   : 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por spritex8 em Seg 17 Ago 2015, 22:07

Desculpa esta revivendo algo aqui Sad, mas como o vosso querido amigo nao tem mais a engine, ficou um pouco complicado saber onde estou errando...
Quando coloco pra rodar o meu jogo, ele da erro nessa linha if global.falador variable_local_exists(texto)(o erro ocorro pq nao reconhece onde deixei em negrito.

Sem mais SpritE X Donati

edit = pelo que andei lendo, esse código esta ultrapassado no lite Sad, se alguém tiver a solução fico muito grato

spritex8

Ranking : Sem avaliações
Número de Mensagens : 3
Data de inscrição : 06/04/2015
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por dharrison em Seg 17 Ago 2015, 22:40

Cara que eu saiba ele não vai funcionar no Lite, e acredito que também não funcione no GMS.

Tente aprender sobre Arrays. Esse script usava arrays um uma variável para "chamar" o texto, sendo que text=0 eram mensagens em branco.

Sakou? Very Happy

EDIT:

Código que muda o texto (step ou draw event):
Código:
//Define Frases, Backgrounds e Personagens.
switch (global.text)
{
case 0: argument[0]=global.frase[0]; break;
case 1: argument[0]=global.frase[1]; break;
case 2: argument[0]=global.frase[2]; break;
case 3: argument[0]=global.frase[3]; break;
case 4: argument[0]=global.frase[4]; break;
//e assim por diante
}

//Desenha Frases
draw_text(32,32,argument[0]) //Escreve a Frase

Código que Guarda os Textos (create event):
Código:
global.frase[0]="" //isso equivale a "em branco"
global.frase[1]="ESTÁGIO 1#X PARA ATIRAR!#Z PARA BOMBAS!"
global.frase[2]="ESTÁGIO 2#INIMIGOS ÁGEIS"
global.frase[3]="ESTÁGIO 3#PREPARE-SE PARA O COMBATE!"
global.frase[4]='ESTÁGIO 4#MAIS INIMIGOS'

dharrison

Ranking : Nota B
Número de Mensagens : 1243
Idade : 25
Data de inscrição : 04/02/2009
Notas recebidas : A - B
Reputação : 89
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Prêmios
   : 0
   : 1
   : 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por spritex8 em Ter 18 Ago 2015, 18:24

muito obrigado, vou da uma melhor estudada nos arrays, meu projeto nao é la grande coisa como muito o de d v6, estou fazendo para uso academico no curso de programaçao jogos digitais

spritex8

Ranking : Sem avaliações
Número de Mensagens : 3
Data de inscrição : 06/04/2015
Reputação : 0
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por dharrison em Ter 18 Ago 2015, 22:12

ok cara, precisa pede um help ae pra mim ou pra galera, eu ando ausente então posso demorar a responder, mesmo assim tamos ae :C:

dharrison

Ranking : Nota B
Número de Mensagens : 1243
Idade : 25
Data de inscrição : 04/02/2009
Notas recebidas : A - B
Reputação : 89
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Prêmios
   : 0
   : 1
   : 0

Voltar ao Topo Ir em baixo

Re: [Tutorial] Um Único Script para Todos Diálogos do Jogo

Mensagem por Conteúdo patrocinado Hoje à(s) 18:41


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