Aula 6: Cenas e Janelas Selecionáveis
www.mundorpgmaker.com This work is licensed under a Creative Commons Atribuição-Uso não-comercial-Compartilhamento pela mesma licença 3.0 Unported License .
Índice de todas as aulas aqui
Índice
6.0 - O que são scenes?
6.1 - O que são windows selectables?
6.2 - Nossa primeira scene
6.3 - Fazendo nossa window que exibirá os nomes
6.4 - Fazendo nossa window selectable
6.5 - Finalizando nossa scene
6.6 - Conclusão
6.7 - Deveres de casa
6.0 - O que são scenes?
Scene são objetos especiais. Eles servem para manipular windows, sprites e muitas outras coisas para que funcionem coordenadamente.No jogo feito pelo RPG Maker, sempre há uma scene ativa, manipulando as coisas do jogo.Por exemplo, temos a Scene_Map, que manipula os gráficos, interpretador, etc do mapa.Temos o Scene_Title, que manipula a tela de título. A variável $scene guarda a scene que está atualmente rodando.Observe que é uma variável global, e pode ser mudada em qualquer lugar de qualquer script. Nós scripters podemos criar uma scene quando quisermos. É isso que iremos fazer nessa aula.
Assim como as windows, as scenes também têm métodos importantes. São esses dois:
main
Esse método é executado geralmente apenas uma vez, e ele continuará executando através de um loop até que a scene atual do jogo mude.O código a seguir é normalmente fix, e quase todos os métodos main de todas as scenes tem:
Graphics . transition loop do Graphics . update Input . update update if $scene != self break end end Graphics . freeze
Graphics.transition e Graphics.freeeze se encarregam de executar efeitos gráficos na hora que uma scene inicia(Graphics.transition) e quando termina(Graphics.freeze). No main temos um loop que executa o método update repetidamente, assim como atualizar o Input de teclado e os gráficos. Quando a scene muda dentro do update, o break do loop executa.Veremos melhor como funciona mais na frente.
update
Como podem ver no código passado, o método main chama o método update repetidamente.O método update encarrega-se de atualizar tudo o que deve ser atualizado na nossa scene.
6.1 - O que são windows selectables?
Como o nome diz, são windows selecionáveis.São aquelas em que há a opção de selecionar várias opções(oh não me diga).Um grande exemplo é a window da tela de título, que contém as opções Novo Jogo, Continuar e Sair. Toda window selectable herda a classe Window_Selectable(assim como uma window normal herda uma Window_Base).A diferença entre uma window selectable e uma window normal é bem sutil, e são poucas as diferenças entre as duas na hora da declaração.
[lohan]
Você deve estar se perguntando: mas thiago, você disse que toda window tem de ser uma Window_Base! Isso é sim verdade, e porque uma window que é uma Window_Selectable é indiretamente uma Window_Base, porque a Window_Selectable herda a Window_Base. Se um selectable é uma base, algo que é uma selectable também é uma base.Bem simples, eu acho.
[/lohan]
6.2 - Nossa primeira scene
Iremos fazer aqui nossa primeira scene. Nela, haverá uma window selectable e uma window normal. Na window selectable haverá 4 opções: Ator 1, Ator 2, Ator 3 e Ator 4 e, dependendo da escolha na window, exibiremos o nome de cada respectivo personagem do grupo.Confesso que as coisas irão complicar um pouco a partir daqui.No final, nossa scene ficará assim(desculpem pela imagem de VX):
Usando o que eu havia falado antes, nossa scene já fica dessa forma, logo de cara:
class Scene_Exemplo def main #=================== Graphics . transition loop do Graphics . update Input . update update if $scene != self break end end Graphics . freeze #=================== end end
6.3 - Fazendo nossa window que exibirá os nomes
Nossa window que exibirá o nome de cada actor será uma window normal, uma Window_Base, pois exibirá apenas um nome.Ela só te, algo de diferente:ela terá de ser atualizada mais de uma vez, e cada vez ela imprimirá um texto diferente, dependendo da opção selecionada na nossa window selectable.Logo de cara, usando os conceitos da aula passada, nossa window fica assim:
class Window_ShowName < Window_Base def initialize super ( 192 , 0 , 192 , 160 ) self . contents = Bitmap . new ( width - 32 , height - 32 ) @texto = $game_party . actors [ 0 ]. name refresh end def refresh self . contents . clear self . contents . draw_text ( 0 , 0 , 128 , 32 , @texto ) end end
Mas temos que fazer com que ela mostre o nome exibido dependendo da escolha de um personagem.Então, iremos criar um novo método, que irá mudar o texto a ser impresso e atualizará a window de novo.Aqui está nossa nova window:
class Window_ShowName < Window_Base def initialize super ( 192 , 0 , 192 , 160 ) self . contents = Bitmap . new ( width - 32 , height - 32 ) @texto = $game_party . actors [ 0 ]. name refresh end def refresh self . contents . clear self . contents . draw_text ( 0 , 0 , 128 , 32 , @texto ) end def mudar_texto ( novo_texto ) @texto = novo_texto refresh end end
Aqui implementamos um método mudar_texto, que muda a variável @texto para o texto recebido e reatualiza nossa window, que mostrará o novo texto atribuído a nossa variável.Podem perceber que fui bem direto nessa parte, pois espero logo de cara que vocês já saibam como manipular uma window comum, pois já lhes ensinei isso.
6.4 - Fazendo nossa window selectable
O modo de se fazer uma window selectable é bem semelhante ao modo de se fazer uma window normal: nós fazemos o método initialize, que inicializará nossa window, e depois fazemos um método refresh, que atualiza a parte gráfica da nossa window.Usando isso pura e simplesmente, nossa window já fica assim:
class Window_SelectHero < Window_Selectable def initialize super ( 0 , 0 , 192 , 160 ) self . contents = Bitmap . new ( width - 32 , height - 32 ) refresh end def refresh self . contents . clear end end
[lohan]
Observe aí que usamos a notação < Window_Selectable. Colocar < Window_Base é um erro comum, e fazer isso daria erro com certeza, pois não podemos tratar uma window comum como uma window selectable.
[/lohan]
Porém, só fazer isso não funciona para nossa window. Temos de especificar duas coisas:seu número de colunas(no caso 1), mudando a variável @column_max e o número de opções, mudando @item_max.Como temos "Ator 1", "Ator 2", etc, somando tudo dá 4.Então nossa window ficará assim:
class Window_SelectHero < Window_Selectable def initialize super ( 0 , 0 , 192 , 160 ) @item_max = 4 self . contents = Bitmap . new ( width - 32 , height - 32 ) refresh end def refresh self . contents . clear end end
Observe que não mudamos a variável @column_max.Isso ocorreu porque 1 é o número de colunas padrão, e não há necessidade de especificar.Como @item_max colocamos o número de opções que vamos ter, no caso 4.Após isso, devemos especificar quais das opções estão selecionadas atualmente.Para isso, mudamos a variável self.index.Logo, nossa window já fica assim:
class Window_SelectHero < Window_Selectable def initialize super ( 0 , 0 , 192 , 160 ) @item_max = 4 self . contents = Bitmap . new ( width - 32 , height - 32 ) refresh self . index = 0 end def refresh self . contents . clear end end
Observe que colocamos 0 como o a opção atualmente selecionada, isso significa que nossa primeira opção é a selecionada.Se colocassemos 1, a opção atualmente selecionada seria a segunda.Funciona exatamente como um índice de array, como zero sendo a primeira opção, e não 1 como seria esperado.Após especificar tudo isso, falta apenas uma coisa: imprimir os texto das opções.Fazendo isso, nossa window ficará assim:
class Window_SelectHero < Window_Selectable def initialize super ( 0 , 0 , 192 , 160 ) @item_max = 4 self . contents = Bitmap . new ( width - 32 , height - 32 ) refresh self . index = 0 end def refresh self . contents . clear textos = [ "Ator 1" , "Ator 2" , "Ator 3" , "Ator 4" ] for i in [ 0 , 1 , 2 , 3 ] self . contents . draw_text ( 0 , 32 * i , 128 , 32 , textos [ i ]) end end end
Observe aí que usei de forma inteligente o for para imprimir os textos de forma fácil.Agrupar os textos a imprimir em uma variável só ajuda em uma posterior modificação, bastaria apenas que fosse editada a tal array.Imprimir os textos poderia ter sido feito de uma forma mais simples, porém menos inteligente:
class Window_SelectHero < Window_Selectable def initialize super ( 0 , 0 , 192 , 160 ) @item_max = 4 self . contents = Bitmap . new ( width - 32 , height - 32 ) refresh self . index = 0 end def refresh self . contents . clear self . contents . draw_text ( 0 , 0 , 128 , 32 , "Ator 1" ) self . contents . draw_text ( 0 , 32 , 128 , 32 , "Ator 2" ) self . contents . draw_text ( 0 , 64 , 128 , 32 , "Ator 3" ) self . contents . draw_text ( 0 , 96 , 128 , 32 , "Ator 4" ) end end
O RGSS tem essas características peculiares:às vezes, uma mesma coisa pode ser feita com códigos diferentes.Depende de cada scripter utilizar a forma mais preferida.Se preferiu a primeira forma, use-a, se preferiu a segunda, use-a.Além dessas duas, existem muitas mais formas de se fazer.É aí que entra aí sua inteligência, não a minha:depende apenas de VOCÊ escolher de que forma fazer.É aí que você começa a conseguir seu próprio jeito de pensar em scripts.Pois é...parece que nossas window estão prontas...Falta apenas manipulá-las usando nossa scene!
6.5 - Finalizando nossa scene
Para começar colocamos na scene o código que cria nossas windows:
class Scene_Exemplo def main @select_window = Window_SelectHero . new @name_window = Window_ShowName . new #=================== Graphics . transition loop do Graphics . update Input . update update if $scene != self break end end Graphics . freeze #=================== end def update end end
Observe que a criação das windows está antes de todo aquele código fix.Em um scene, geralmente esse é sempre o lugar em que se inicializa esse tipo de coisas.Ao acabar nossa scene, devemos remover nossas windows da tela.Para isso, chamamos o método dispose delas:
class Scene_Exemplo def main @select_window = Window_SelectHero . new @name_window = Window_ShowName . new #=================== Graphics . transition loop do Graphics . update Input . update update if $scene != self break end end Graphics . freeze #=================== @name_window . dispose @select_window . dispose end def update end end
Observe que o dispose foi colocado depois do código fix.Todo código que termina com a scene deve ser colocado nesse lugar.
[lohan]
Esquecer de dar dispose nas windows logo após a scene acabar resultará que as windows irão permanecer na tela, e desaparecerão depois de um certo tempo.
[/lohan]
Por último, implementamos nosso método update.Lembre-se que ele executa muitas vezes por segundo, e deve sempre atualizar nossa scene.Nele, atualizamos nossas duas windows, com o método update.O método update das windows não atualiza a parte gráfica, como o refresh, apenas partes não gráficas.Logo após disso, analisamos se nesse meio tempo o botão Z do teclado foi pressionado, com a expressão Input.trigger?(Input::C).Por enquanto só saiba que essa expressão analisa se o botão foi pressionado, depois vou explicá-la detalhadamente.
Se o Z foi pressionado, quer dizer que um novo ator foi selecionado.Devemos então atualizar nossa window que mostra o nome do ator.Fazemos isso chamando aquele método que criamos...mudar_texto, se lembram?Depois disso o código completo, com todas as windows e nossa scene fica assim:
class Window_SelectHero < Window_Selectable def initialize super ( 0 , 0 , 192 , 160 ) @item_max = 4 self . contents = Bitmap . new ( width - 32 , height - 32 ) refresh self . index = 0 end def refresh self . contents . clear textos = [ "Ator 1" , "Ator 2" , "Ator 3" , "Ator 4" ] for i in [ 0 , 1 , 2 , 3 ] self . contents . draw_text ( 0 , 32 * i , 128 , 32 , textos [ i ]) end end end class Window_ShowName < Window_Base def initialize super ( 192 , 0 , 192 , 160 ) self . contents = Bitmap . new ( width - 32 , height - 32 ) @texto = $game_party . actors [ 0 ]. name refresh end def refresh self . contents . clear self . contents . draw_text ( 0 , 0 , 128 , 32 , @texto ) end def mudar_texto ( novo_texto ) @texto = novo_texto refresh end end class Scene_Exemplo def main @select_window = Window_SelectHero . new @name_window = Window_ShowName . new #=================== Graphics . transition loop do Graphics . update Input . update update if $scene != self break end end Graphics . freeze #=================== @name_window . dispose @select_window . dispose end def update @name_window . update @select_window . update if Input . trigger ?( Input :: C ) @name_window . mudar_texto ( $game_party . actors [ @select_window . index ]. name ) end end end
Observe a linha @name_window.mudar_texto($game_party.actors[@select_window.index].name).Ela muda o texto exibido pela nossa window para o nome do ator atualmente selecionado, que depende do índice da window selectable.Se o índice for 0, o ator selecionado será 0.Se o índice for 1, o ator será 1 também.Por isso podemos utilizar o índice para localizar qual ator está selecionado.Cool.
[lohan]
Na aula passada eu havia dito que explicaria porque a window desaparecia depois de um tempo.Isso ocorre porque, quando um evento termina de acontecer, toda variável criada por scripts nesse evento acaba desaparecendo e, caso essa variável não tenha onde ser utilizada, o que ela guarda acaba sumindo também, no caso uma window.Quando colocamos uma window numa scene, essa window poderá ser utlizada enquanto essa scene existir.Quando a scene deixar de existir, a window acaba desaparecendo com o tempo também.Mas como queremos isso imediatamente, usamos o método dispose do qual falei.
[/lohan]
Até agora, só declaramos nossas windows e nossas scenes.Mas só declarar não basta, certo?Então vamos colocar nossa scene para funcionar!Para isso, coloque um comando de script de evento com o seguinte código, depois teste:
$scene = Scene_Exemplo . new
Toda vez que queremos que nossa scene execute, substituimos a variável $scene.Observe que após isso o mapa some, isso pois ele deixa de ser a scene atual.Mas como retornar ao mapa?Basta atribuir o mapa ao $scene, assim:
$scene = Scene_Map . new
No dever de casa pedirei uma aplicação disso.
6.6 - Conclusão
[center]
Puxa vida que aulinha que deu trabalho! Tenho certeza que , além disso, essa aula será considerada difícil para muitos.É por isso que estou aqui! Quaisqueres dúvias, basta postar no tópico que eu responderei prontamente.Tenho certeza que aqui é que surgirão muitas dúvidas.E lá vem os deveres de casa...Com certeza serão os mais difíceis de todos!Já chega de vocês pensarem com minha mente.Vocês agora terão que quebrar a cabeça e usar a mente de vocês.
[center]6.7 - Deveres de casa
[center]
Esse dever é bem fácil.No dever, quero que modifique nossa window selectable para exibir não 4 opções, porém 5.A 5ª opção será "Voltar".Quando essa opção for selecionada, a scene atual será trocada para o mapa.Boa sorte.Ah e para certos Mertholates, não façam nem mais nem menos do que eu pedi no dever ¬¬.
Faça uma scene do zero.Essa scene permitirá selecionar os atores da equipe.Quando selecionado um ator, haverá uma outra window que exibirá informações daquele ator.Essa window pode ser a window do dever passado, modificada para funcionar do jeito que queremos.Também deve ter uma opção "Voltar", para voltar ao mapa.
[center]Eu queria realmente dar mais deveres legais, porém eu acho que mataria vocês, então por enquanto é só isso.Até mais.
[center]