Sie sind auf Seite 1von 91

Curso de Scripts RGSS Retirado do Site: JogosRPG Aulas feitas por: JooNeto Lio 1: Fundamentos Bsicos

RGSS (Ruby Game Scripting System) uses the object-oriented scripting language Ruby to develop 2D games for the Windows platform. RGSS lets you build entirely original game systems far more easily than would other languages like C. Ruby is a simple language that's easy even for beginners to use, yet it's still a powerful and sophisticated tool. RGSS(Ruby Game Scripting System) usa a Linguagem de Script Ruby Orientada a objetos para desenvolver jogos 2D para a Plataforma Windows .RGSS leva voc a construir inteiramente sistemas de jogos com originalidade mais facilmente que outras linguagens como C. Ruby uma linguagem simples e de fcil aprendizado para os iniciantes, sendo esta uma poderosa e sofisticada ferramenta. -> Texto retirado do Help Original em Ingles. Sem mais pormenores vamos comear pelo que realmente interessa. O que vem a ser "Linguagem Orientada a objetos"? Pois bem. Significa que tudo que existe, j pronto, dentro dos padres de programao, pode ser reutilizado, reaproveitado, ou alterado. Vejamos um exemplo:

Observe que o objeto CLIENTE foi reaproveitado para comportar dois clientes diferentes, com nomes diferentes e telefones diferentes. Mas para isso eu precisei "Declarar" dois novos objetos. "DECLARAR"? Sim. Todo novo objeto deve ser declarado, de forma ao programa saber que ele existe e o que ele . Para isso vamos entrar no maior e mais importante de todos os objetos da programao : VARIVEIS. Eu costumo dizer que uma "Varivel como um balde, voc enche com algo que precisa, para usar depois, em outro lugar". Qualquer objeto que se deseja usar deve ser declarado numa varivel. Vejamos o exemplo:

Nesta janela do Editor de scripts vemos claramente que todos os nomes com $data esto sendo carregados cada qual com um objeto do RPG, atores, classes, habilidades... e a ultima linha que possui $game est iniciando um objeto, no carregando, mas criando. voc mesmo pode criar uma varivel, agora mesmo !! quer ver? Abra um projeto no RPGMaker XP, v no editor de scripts, na sesso Main. logo depois de Graphics.freeze, coloque assim:
Cdigo:

nome = "Z da silva" print nome.to_s

Agora rode o jogo. SIMPLES DEMAIS !! Agora que voc j sabe um pouco(bem pouco) sobre objetos, vamos falar de variveis... VARIVEIS: Para facilitar o estudo, eu vou cham-las de Vars. Existem Vrios tipos de vars, as mais comuns e mais usadas so: String - Comporta letras e nmeros Integer - Comporta numeros Boolean - Comporta 0 e 1, true e false, sim e no Array - Comporta vrias variveis Constante - Comporta tudo, porm seu valor fixo. No caso dos Eventos de mapa, eles usam vars booleanas(as switches) e vars numricas(as vars comuns). No RPGMaker, elas tambm possuem grau: var = var local @var = var pblica $var = var global VAR = Constante Vars locais servem para resolver problemas rpidos, como nomes ou nmeros que s sero alterados ali mesmo. Vars pblicas servem para toda a classe que a declarou, podendo ser alterada em qualquer procedimento da classe. Vars globais so geralmente declaradas no incio da execuo do

programa, servindo como base para classes e outras vars. Constantes S so declaradas no caso de valores imutveis, ou seja, que no necessitam ser mudados.

Lio 2: Classes,procedimentos e herana.


Para o perfeito endendimento desta lio, necessrio o contedo da lio anterior. Vamos l: O que so CLASSES ? Classes so objetos do RGSS que contem os procedimentos necessrios para todas as execues do jogo. Os atores, as armas, itens, mapas, eventos, tudo no RPGMaker uma classe pr-definida. Para usarmos as classes, ns as declaramos, em variveis, exemplo: $game_party = Game_Party.new Quando dizemos nomedaclasse.new estamos instanciando a classe nessa varivel. Porque? no era s chamar a bendita? No. Dae vem a orientao a objetos. O objeto Game_Party est l, pronto para ser usado, mas se vc no disser que voc quer us-lo, ele vai continuar l, esperando... T bom, chamamos a classe, com $game_party = Game_Party.new, e agora? Agora vem a parte interessante. Se voc decidir que precisa de outro objeto Game_Party, basta declarlo de novo, por exemplo: $game_party_2 = Game_Party.new Acabamos de instanciar outro objeto Game_Party, com um nome diferente, o que significa que temos dois objetos, identicos, porm com nomes diferentes, o que vai fazer com que voc possa us-los separadamente, da maneira que desejar, ou precisar. No vou me aprofundar no contexto classe, pois bem extenso. Agora que temos duas classes, o que fazer com elas? vamos usar alguns procedimentos.

PROCEDIMENTOS: Para o funcionamento da classe, ela deve conter procedimentos, os quais so vitais na maioria das ocasies. veja o exemplo:

Aqui, depois de declarada na var $game_party, chamamos o procedimento da classe "item_can-use?", atravs da sintaxe: nomedavar.nomedoprocedimento vejamos este procedimento dentro da classe:

Note que todos os procedimentos comeam com def nomedoprocedimento e terminam com end. Nos aprofundaremos nos procedimentos mais tarde. H algo muito importante que deve ser falado sobre as classes, antes de detalharmos seu contedo. a herana. HERANA ? o RGSS j possui vrias classes pr-definidas, como a classe Actors, a classe Window, a classe Sprite, entre outras.

Porm surge a necessidade de termos novos objetos, mais completos ou com procedimentos diferentes das classes pr-definidas. O que fazer? Nesse caso usamos a herana, veja o quadro abaixo:

TODAS as classes filho esto ligadas diretamente classe pai, porm umas so filhas de outras, ou seja, aproveitam dos procedimentos gerais(da classe Pai mor) e da classe filha inicial, que tambm possui novos procedimentos e funes. Mas como declarar quem pai de quem ou quem filho de quem? Simplesmente usando o sinal de <(menor), Assim: class Window_Base < Window class Window_Selectable < Window_Base class Window_Command < Window_Selectable Note que eu fiz uma hierarquia, onde W_Base filho de Window, W_Selectable filho de W_Base, e W_Command filho de W_Selectable. Mas como usar os procedimentos das classes pai? Para isso usamos a denominao super(). Todas as vezes que usamos super, estamos atribuindo quele procedimento as funes do procedimento pai. Por exemplo, esta uma parte da classe Window_Base:
Cdigo:

class Window_Base < Window def initialize(x, y, width, height) super() @windowskin_name = $game_system.windowskin_name self.windowskin = RPG::Cache.windowskin(@windowskin_name)

self.x = x self.y = y self.width = width self.height = height self.z = 100 end def dispose if self.contents != nil self.contents.dispose end super end

Observe que a palavra super usada nos dois procedimentos, no initialize e no dispose. O super usado aki para que, nesta classe, estes procedimentos usem as funes do procedimento da Superclasse(neste caso, a Window) e tenham mais funes. Mesmo que uma classe seja filha de outra, voc pode ter procedimentos com o mesmo nome, mas com funes diferentes, o que possibilita que a chamada de um procedimento se torne padro, mas obedecendo a construo do prprio dentro da classe. CONCLUSO: Nesta lio aprendemos mais um pouco(ou quase nada) sobre Classes, Hierarquia e uma pincelada nos procedimentos. Para evitar confuses, farei uma apndice destacando as principais palavras reservadas da programao RGSS(como a palavra super). Na prxima lio falaremos sobre os procedimentos com mais enfse, e teremos um exerccio, faremos nossa primeira classe, uma janela !! Eu peo a todos que lerem que deixem um comentrio, ou se tiverem dvidas que perguntem Obrigado.

Lio 3: Nossa primeira classe Uma Janela.

Antes de comear este tpico quero esclarecer que TODAS as apndices que forem colocadas neste frum s tem como finalidade referncia, no sendo de necessidade explicar ou detalhar seu contedo. Na lio de hoje vamos criar nossa primeira classe. Abra o RPGMaker Xp e crie um novo projeto. Chame-o como quiser. Abra o Editor de Scripts, e logo acima do Main, insira uma sesso (boto direito -> Inserir). Nomeie-a como quiser. O nome das sesses irrelevante, pois o RGSS l o seu contedo, no seus nomes. Na janela do Editor escreva isso:
Cdigo:

class Window_Minha < Window_Base

Note que a palavras class est em minsculas. TODO e qualquer cdigo escrito no RGSS que se refira a funes, classes, mdulos DEVE ser escrito em minsculas. Mais tarde veremos que o RGSS CASE-SENSITIVE (entraremos nos detalhes depois). Note tambm que estou definindo nossa classe como filha de Window_Base. Toda classe pr-inicializada possui como procedimento inicial o initialize. Ento logo abaixo do class escreva isso:
Cdigo:

def initialize

Seu cdigo deve estar assim:


Cdigo:

class Window_Minha < Window_Base def initialize

Agora vamos usar o procedimento de criao da superclasse, usando a palavra reservada super, e junto com ela os parmetros necessrios. PARMETROS??? Sim, vamos ver a superclasse para entender isso:

Note que o initialize da classe Window_Base possui dentro dos parnteses 4 vars, separadas por virgulas. Essas vars so os parmetros, atravz dos quais a classe cria a janela, usando seus valores logo abaixo nas declaraes self. A palavra self sempre usada quando falamos do prprio objeto, ou seja, relacionado a ele. Agora que sabemos pra que servem os parmetros aqui, vamos voltar para nossa janela. logo abaixo do initialize escreva assim:
Cdigo:

super(32,32,120,64)

Eu peo que escreva e no copie e cole, para que voc se habitue a escrever na janela do Editor. Seu cdigo deve estar assim:
Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64)

Para podermos visualizar nossa janela, devemos agora fechar as declaraes. TUDO que for declarado no RGSS, Mdulos, Classes, Funes deve ser fechado com a palavra end. Como temos uma classe e um procedimento abertos, vamos fech-los. Escreva no cdigo assim:
Cdigo:

class Window_Minha < Window_Base def initialize

super(32,32,120,64) end end

Agora vamos visualizar nossa janela. Crie um NPC no mapa, e nele use a funo "Chamar Script". Agora nela escreva assim:
Cdigo:

Window_Minha.new

Rode o game e fale com o NPC. A est !! Linda, maravilhosa, e vazia... Mas no se desespere, isso s a ponta do Iceberg. Vamos colocar algo dentro da nossa janela. O que voc v apenas um desenho do WindowSkin, na largura e altura que voc definiu. Para colocar algo dentro da janela, devemos criar dentro dela um bitmap. Um bitmap sempre usado nesses casos, em qualquer lugar, seja ele uma janela, um Spriteset ou um ViewPort, esses dois ltimos sero estudados mais tarde. Ento vamos l. Para criar o bitmap dentro da janela, usamos a denominao contents, que significa contedo. Logo abaixo do super escreva assim:
Cdigo:

self.contents = Bitmap.new(width - 32, height - 32)

Vamos analizar. Usamos o self, dizendo que este objeto, .contents, que seu contedo, um sinal de igual( = ) para definir, e a declarao Bitmap.new(width - 32, height - 32). Note que estamos passando parmetros para o bitmap, de largura e altura. Nosso bitmap est criado. e Agora Agora, podemos "desenhar" dentro dele, tanto uma imagem, tanto quanto um texto. Vamos comear pelo texto, que mais simples. A sintaxe assim: self.contents.draw_text(x, y, largura, altura, texto [,alinhamento]) O alinhamento opcional, por isso ele est dentro das chaves. Logo abaixo da declarao do bitmap, escreva assim:
Cdigo:

self.contents.draw_text(4, 0, self.width - 40, 32, "nome", 0)

Seu cdigo deve estar assim:


Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.draw_text(4, 0, self.width - 40, 32, "nome", 0) end end

Execute o projeto e fale com o NPC. Estamos indo bem. J conseguimos fazer uma janela e escrever algo nela. Mas repare que, depois de um tempo, a janela some. Isso se deve porque ela no faz parte dos processos de mapa, voc apenas a chamou. Ela no tem nenhum processo que a mantenha aberta. Vamos mudar isso!! Vamos agora alterar uma classe j existente. Dentro da sesso Main, logo aps Graphics.freeze, escreva isso:
Cdigo:

$janela = []

Agora v no NPC do mapa e mude o cdigo para:


Cdigo:

$janela = Window_Minha.new

E rode o game. A janela no some mais !! Mas porque? Porque ela foi DECLARADA. Por isso tudo que for feito no RGSS precisa de declarao. Vamos mudar o contedo da janela agora. Comente a linha self.contents.draw_text(4, 0, self.width - 40, 32, "nome", 0), para comentar, coloque um # (chama-se sharp) no ncio dela. Agora na linha self.contents = Bitmap.new(width - 32, height 32), coloque assim:
Cdigo:

self.contents = Bitmap.new("Graphics/Icons/001-Weapon01.png")

Seu cdigo deve ficar assim:


Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new("Graphics/Icons/001Weapon01.png") #self.contents.draw_text(4, 0, self.width - 40, 32, "nome", 0) end end

Agora rode o game. , eu tambm gosto do cone da espada. Repare que demos uma caminho de arquivo, no caso do bitmap basta dizer o caminho a partir da pasta do projeto. At agora aprendemos que com a classe bitmap(Bitmap.new, declarao de classe, correto?) comporta tanto texto quanto e imagens. Ela tambm comporta os dois juntos, mas para isso, iremos precisar de outra classe e um mdulo. MDULO ?? Sim, um mdulo uma pr-definio, como a classe, porm ele no permite instncias, voc no declara @var = modulo.new como feito com as classes, voc chama MODULO::Procedimento. Os mdulos sero estudados com mais nfaze numa prxima lio, agora s veremos o necessrio para o que precisamos. A classe que vamos precisar o Rect, que significa retngulo, a classe Rect cria uma rea dentro do bitmap, onde podemos "desenhar" qualquer coisa. Sua definio : Rect.new(x, y, largura, altura) ento vamos l. Retorne a linha bitmap para o que era antes, assim: self.contents = Bitmap.new(width - 32, height - 32) Logo abaixo dela escreva assim:
Cdigo:

icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height)

Acabamos de declarar duas variveis, uma com a imagem do cone, onde usamos o mdulo RPG::Cache e o procedimento icon, e o nome do arquivo. A extenso do arquivo desnecessria, o RGSS gera um erro se a imagem no for suportada por ele. A outra contm nosso rect, que exatamente do tamanho da imagem carregada na var icone. Agora usaremos mais uma funo do self.contents, a funo blt. A funo blt vai desenhar dentro do rect a imagem que foi carregada na var icone, sua definio essa: blt(x, y, bitmap,rect[,opacidade]) Vamos l. logo abaixo da declarao do rect, coloque isso:
Cdigo:

self.contents.blt(0, 0, icone, rect)

Descomente a linha self.contents.draw_text(4, 0, self.width 40, 32, "nome", 0) e troque o numero 4 por icone.width + 4. Seu cdigo deve estar assim:
Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height) self.contents.blt(0, 0, icone, rect) self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0) end end

Agora rode o game. Muito bom !! CONCLUSO: Comeamos a ver hoje como criar uma janela, colocar texto e figuras. Demos uma leve pincelada nos mdulos e nas funes internas da classe Window. Eu quero alertar que a partir de agora tanto as lies quanto os cdigos comearo a ficar complexos, por isso, se voc realmente tem interesse em aprender, faa perguntas concisas, programar em RGSS muito fcil, mas depende principalmente de ateno e pacincia.

No jogue fora o projeto com o Exemplo da janela, ele ser til na prxima lio, onde nos aprofundaremos nos procedimentos da classe, gerando novos resultados e alteraes na janela. Eu farei uma apndice destacando TODAS as funes das classes Window e Bitmap, para maior facilidade nas prximas lies.

Lio 4: Modificando nossa Janela Usando Dados Variveis


Antes de iniciar esta aula eu quero pedir desculpas pois eu errei uma coisa na 3 aula, Quando falamos de mdulos eu disse que a sintaxe era: MODULO::Procedimento E na verdade assim: MODULO::Classe.procedimento Descobri isso quando lia um dos posts, vi que estava errado. Por falar em posts, meu professor costumava dizer que "Aluno que no pergunta, ou entendeu tudo ou no entendeu nada." Se voc est entendendo tudo, timo, mas se no entendeu alguma coisa, poste, pergunte, mande PM, porque a partir de agora a coisa vai pegar e, quem estiver entendendo, vai se dar bem, quem no estiver... Hoje vamos ver como usar as funes da nossa classe pai. Se voc no leu a Lio 3, pare agora e a leia, pois sem ela essa lio impossvel. Caso voc tenha perdido o projeto criado na lio 3, retorne a ela crie-o novamente, pois continuaremos nele. Vimos na aula anterior como escrever e colocar uma figura numa janela, e como declarar uma janela de forma a ela ser consisa no game. Hoje vamos fazer nossa janela exibir dados variveis a partir de funes da classe pai Window_Base. DADOS VARIVEIS?? Sim, seu game posui uma enormidade de dados variveis, como o HP do heri, sua experincia, e outras coisas. Abra o projeto anterior e, abra o editor de scripts. Na sesso onde voc criou a nossa janela. Se

vc fez tudo corretamente na aula passada, nossa classe deve estar assim:
Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height) self.contents.blt(0, 0, icone, rect) self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0) end end

Voc deve ter percebido que a nossa janela s tem o procedimento initialize. Desta forma, na hora em que a janela chamada, todo o contedo de initialize lido e desenhado. Vamos colocar mais um procedimento na nossa janela. Logo abaixo do primeiro end escreva assim: def refresh Logo abaixo dele, vamos pedir que a janela se limpe, usando o mtodo clear, escreva assim: self.contents.clear Voc j sabe o que o self e o contents, estamos fazendo com que o contedo da janela seja limpo. Qual a necessidade disso? bem, voc vai ver... Agora retire esta parte de cdigo do procedimento initialize:
Cdigo:

icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height) self.contents.blt(0, 0, icone, rect) self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0)

e coloque-o logo abaixo do self.contents.clear. Seu cdigo deve ficar assim:


Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) end def refresh self.contents.clear icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height)

self.contents.blt(0, 0, icone, rect) self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0) end end

Salve o cdigo e rode o game. A janela vai aparecer vazia. Agora v no NPC e coloque o seguinte cdigo junto com o que j est l: $janela.refresh Nosso texto e nosso cone voltaram a aparecer, porque chamamos o procedimento refresh. Para que no precisemos fazer isso sempre, vamos fazer com que a prpria janela chame o procedimento. MAS COMO??. Muito simples, antes do end que fecha o procedimento initialize, escreva refresh. Seu cdigo deve estar assim:
Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) refresh end def refresh self.contents.clear icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height) self.contents.blt(0, 0, icone, rect) self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0) end end

V no NPC e comente a linha que chama o refresh(vamos us-la mais tarde) e rode o game. At agora tudo bem. Vamos agora aprofundar um pouco mais, vamos chamar uma funo da classe pai, a funo draw_actor_name(actor, x, y). Quero ressaltar que, quando estamos DENTRO da classe, chamamos procedimento, quando estamos FORA da classe, seu procedimento se torna uma funo. A funo que vamos chamar da classe pai escreve na janela onde foi chamada o nome de um ator(ou heri) designado no parmetro actor, e x e y aonde devemos desenhar. Mas como saber qual ator escrever o nome? Vamos ver essa funo em ao. V na sesso Window_MenuStatus, na linha 34. voc vai ver isto:
Cdigo:

actor = $game_party.actors[i]

Mais para a frente aprenderemos o que significa esse i, por enquanto vamos nos atentar ao que precisamos. copie esta linha. V na nossa

janela, no procedimento refresh e, antes de draw_text, cole a linha. Agora troque o i por 0(zero). Comente a linha draw_text. logo abaixo de actor =... coloque a funo draw_actor_name(actor, x, y). Substitua o x por icone.width + 4 e o y por 0(zero). Seu cdigo deve estar assim:
Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) refresh end def refresh self.contents.clear icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height) self.contents.blt(0, 0, icone, rect) actor = $game_party.actors[0] draw_actor_name(actor, icone.width + 4, 0) #self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0) end end

Agora rode o game. Maravilha !! mas o que fizemos?? Criamos uma var local, a actor, e definimos para ela um valor, que vem de uma var global, a $game_party. Como $game_party uma var instanciada da classe Game_Party, eu posso chamar suas funes e variveis pblicas. Neste caso, estamos lendo a var publica actors que uma var array, onde esto TODOS os heris do grupo de heris. o nmero 0(zero) significa que queremos o primeiro heri, aumente o nmero(1, 2, no mximo 3, seno haver um erro) e rode o game. Ento possvel concluir que, usando deste artifcio, podemos retornar o que quisermos, de quem quisermos(heris, armas, itens, classes, habilidades, parmetros, dinheiro do jogo) e mostrar em qualquer lugar, em qualquer janela. J que estamos embalados em mostrar coisas, vamos fazer um "joguinho". Dentro do def initialize declare uma var pblica com o nome de ator e como uma var numrica. Como fazer isso?? Assim:
Cdigo:

@ator = 0

Agora no def refresh, escreva a seguinte linha:


Cdigo:

@ator == 3 ? @ator = 0 : @ator += 1

Calma, voc j vai saber o que isso. Agora crie um outro NPC, e nele coloque um chamar Script com a seguinte linha:
Cdigo:

$janela.refresh

Na linha actor = $game_party.actors[0], troque o 0(zero) pela var @ator. Antes de testar, verifique se seu cdigo est assim:
Cdigo:

class Window_Minha < Window_Base def initialize super(32,32,120,64) self.contents = Bitmap.new(width - 32, height - 32) @ator = 0 refresh end def refresh self.contents.clear @ator == 3 ? @ator = 0 : @ator += 1 icone = RPG::Cache.icon("001-Weapon01") rect = Rect.new(0, 0, icone.width, icone.height) self.contents.blt(0, 0, icone, rect) actor = $game_party.actors[@ator] draw_actor_name(actor, icone.width + 4, 0) #self.contents.draw_text(icone.width + 4, 0, self.width 40, 32, "nome", 0) end end

Agora rode o game. Fale com o primeiro NPC, depois fale repetidas vezes com o segundo. Se voc fez tudo correto, o nome escrito na janela deve mudar. A linha que criamos ali em cima, a qual voc no entendeu patavina, uma linha condicional. Sim, igualzinho s condies que voc v dentro da programao de eventos. O seu uso agora foi apenas de demonstrao e as condicionais sero explicadas mais tarde. CONCLUSO: Nesta lio apenas vimos como criar novos procedimentos dentro de uma janela, usar funes da classe pai e como funciona(basicamente) o uso de Dados variveis. Este assunto muito, muito extenso, e para que voc no se sinta desmotivado, eu vou variar um pouco, e depois voltamos ao assunto janelas, pois ainda h muito o que ver. A partir desta lio eu comearei a colocar os Tpicos "Dicas e Truques", onde voc aprender vrias coisas legais e teis no RGSS,

enquanto treina seu conhecimento em programao. At.

Lio 5: Sprites e Planes Abusando das Imagens


Quero comear esta lio agradecendo a todos os que tem mandado PMs e e-mails com agradecimentos e perguntas. Isso de grande valor para mim, pois eu tenho aprendido tanto quanto tenho ensinado. Na ltima lio falva-mos de janelas. Hoje falaremos de Imagens. Todos ns sabemos que impossvel fazer um game sem imagens. O prprio Tileset, os chars, os panoramas... at mesmo o texto que voc escreve como dilogo uma imagem. Para aqueles que j leram o Apndice sobre a classe bitmap, talvez fique mais claro o que eu falarei hoje. Vamos comear pela Classe Sprite. A Classe Sprite responsvel diretamente pelo Tileset e pelos Chars(heri e eventos). Nela, carregamos uma imagem para ser usada e abusada. Observe esta linha da Classe Scene_Title:

1 - A Classe Sprite declarada 2 - definida uma imagem para ela atravs da Funo RPG::Cache assim que se tem uma imagem no ttulo do game. o Sprite uma classe variante, que possui muitas funes de grande importancia, como no caso das x e y, que definem a posio da imagem. Voc ainda possui aquele exemplo feito nas lies anteriores? abra-o, v no editor de Scritps, e v na sesso Scene_Title, e procure a linha 36(a do nosso exemplo). Logo abaixo da 37 escreva assim: @sprite.x += 250 Rode o Game. O fundo est deslocado, essa era a inteno. Mas observe que ficou um fundo preto na tela. O Sprite comporta apenas o tamanho da imagem. Podemos mexer nele de forma a ocultar o espao vazio... Logo abaixo da x escreva assim: @sprite.zoom_x = 2.5 Rode o Game. A imagem ficou esticada. Essas so apenas 2 das

funes da Classe Sprite, eu farei uma apndice sobre ela detalhando-a. Mas a imagem do title neste caso uma imagem fixa, e se eu quisesse ela mvel Bem, podemos umsa uma funo da classe Sprite que serve basicamente para isso, mover a imagem dentro do conteiner. CONTEINER?? Sim, na declarao @sprite = Sprite.new voc criou um conteiner do tipo Sprite para mostrar a figura. H mais tipos de conteiners de imagem, que sero mostrados depois. Usando o funo @sprite.ox ou ]@sprite.oy podemos mover a imagem dentro do conteiner. Quando usamos x e y movemos o conteiner, como o caso das janelas. Procure o procedimento update da classe Scene_Title. Dentro dele escreva assim: @sprite.ox += 1 Rode o game. A imagem vai andar at sumir. Ela some porque a imagem sai do campo da tela, mas ela continua l. Quando precisamos de imagens que andem, usamos uma outra classe, A classe Plane. A Classe Plane nos permite que uma imagem se mova e, quando esta passa do limite do conteiner, ela repetida, dando a impresso de continuao. Vamos fazer um teste? V na linha 36 e troque @sprite = Sprite.new por @sprite = Plane.new. Rode o Game. O fundo acaba e comea novamente. Isto usado nos panoramas, porque o mapa pode ser maior que a tela, e nos fogs, que possuem movimento. Se voc observou j um fog em funcionamento, voc nunca sabe aonde a "Emenda" por que uma imagem feita para isso. Para que voc entenda melhor esta diferena(que eu acho que voc j entendeu) vamos fazer um title animado. Remova todas as linha que voc colocou e conserte a linha 36. Baixe estas imagens e importe para seu projeto na pasta title:

Agora mos massa: No lugar da linha 36 e 37, escreva assim:


Cdigo:

@sprite = Sprite.new @sprite.bitmap = RPG::Cache.title("Morning1") @sprite2 = Plane.new @sprite2.bitmap = RPG::Cache.title("Cloud01") @sprite3 = Plane.new @sprite3.bitmap = RPG::Cache.title("Cloud02")

Rode o Game. Bonito no? Agora vem o legal. V novamente no procedimento update e escreva assim:
Cdigo:

@sprite2.ox -= 1 @sprite3.ox += 2

Rode o Game. LEGAL !! Mas o que fizemos ?? Declaramos duas imagens como Plane, e no procedimento update, onde o scene mantm a atualizao da tela, colocamos: @sprite2.ox -= 1 A cada atualizao da tela, diminui 1 na ox. @sprite3.ox += 2 A cada atualizao da tela, aumenta 2 na ox. Se variar estes nmeros, a velocidade maior, e se por 0(zero) ele(o plane) para. Scene?? atualizao de tela?? Bem, acho que no d mais, vamos ter que entrar nessa parte... Scenes.

CONCLUSO : Hoje vimos um pouco(bem pouco) sobre Sprites e Planes. Vou ter q fazer aulas menores, porque no d mais s explicar. Se voc no praticar, difcilmente vai entender. Nossa pincelada nesse assunto foi pequena, eu pretendo voltar e falar mais. A inteno tambm foi de quebrar o parmetro janela que tnhamos entrado. Eu devo falar mais um pouco sobre janelas, Sprites e Planes, antes de entrarmos em Scenes. Deverei postar duas apndices, uma falando da classe Sprite e outra da Classe Plane. Por hoje s. At a prxima e obrigado.

Lio 6: Retornando a Sintaxe Condies


Tenho visto muitos posts em meus D&T me comparando com outras pessoas e comparando o que eu ensino com o que j existe. Bem... O Grande Mestre Vagner me deu este espao para que VOC aprenda, eu disponho do meu tempo para estar aqui escrevendo para que voc saiba um pouco mais sobre programao, no s RGSS, porque programar, mesmo que em linguagens diferentes, exige-se os mesmos conceitos e regras. Hoje o Assunto vai ser bem chato, vamos deixar um pouco de lado os exemplos e vamos falar de Sintaxe. Voc j viu nas aulas anteriores o uso de uma condicional. Hoje falaremos sobre as condicionais mais usadas no RGSS. CONDICIONAIS: 1 Estrutura - If e Unless O prprio nome j diz. Para quem est habituado s condies dos eventos, j sabe mais ou menos como funciona. A estrutura principal esta: if <condio> then <ocorrencia> else

<outra coisa> end No Ruby, o then dispensvel na maioria dos casos. IF, THEN, ELSE ?? Pra quem no sabe ingls, mais ou menos assim: if = SE then = ENTO else = SENO Ento possvel entender que uma Estrutura condicional faz uma pergunta, se ela for respondida, ocorre algo, se no, ocorre outra coisa. Seria assim: Se <laranja> == "Amarelo" ento <"A laranja amarela"> seno <"Desde quando uma laranja amarela?"> fim As condicionais so variantes, ou seja, sua estrutura pode ser mudada, por exemplo, podemos contruir uma condio sem else, por exemplo: if $game_switches[1] == true print "ok" end A condio acima vai mostrar o texto somente quando a Sw 1 estiver ligada. if $game_variables[1] == 50 print "50" end A condio acima vai mostrar o texto somente quando a var 1 tiver o valor igual a 50. Com certeza voc vai ter minhares de dvidas... Como testar isso? Como saber se isto verdade? Porque as comparaes usando Sws e vars? Eu pretendo ir introduzindo o uso das Sws e Vars internas do RMXP nas nossas aulas, para que voc veja que "TUDO QUE OS EVENTOS FAZEM, NADA MAIS SO QUE EXECUES DE SCRIPTS." Vamos exemplificar...

Quando voc faz uma condicional num evento, como o da imagem abaixo:

Internamente o RMXP est fazendo isso: if $game_switches[1] == true <> end Se voc mudar o "Adicionar Exceo.." fica assim: if $game_switches[1] == true <> else <> end Se voc est habituado aos eventos, voc j reconheceu a estrutura...

As condicionais so de extrema importncia na programao, pois

so elas que nos ajudam a tornar o cdigo mais dinmico. com as condicionais, voc muda valores, aceita ou no que coisas tenham sido feitas no jogo ou simplesmente impede que algo acontea, se a determinada condio no for verdadeira. Olhe esta parte de cdigo retirada do RMXP:

Este texto vem do menu principal. observe que o if questiona o pressionamento de uma tecla(Input.trigger?(Input::B)). Observe tambm que no h else. Significa que o que est neste if s vai funcionar quando a tecla for pressionada, caso contrrio no ocorrer nada. A caixa vermelha mais escura mostra o procedimento principal se caso a tecla for pressionada. Logo abaixo eu mostro outro questionamento de teclas, que neste caso tem outro if dentro dele. At agora vimos que eu a condio if verifica se um valor verdadeiro e, se na estrutura houver um else, faz com que a resposta no verdadeira condio tambm resulte numa ao. Mas e se eu quiser que hajam mais clausulas, ou que sejam mais restritas as minhas condies ?? Para mais clausulas, acrescentamos na estrutura o elsif. O elsif permite que tenhamos mais de uma clausula verdadeira em nossa estrutura. Vamos exeplificar: if $game_variables[1] == 1 <> elsif $game_variables[1] == 2 <> elsif $game_variables[1] == 3 <> else <>

end Desta forma, podemos ter vrios resultados dependendo do valor de $game_variables[1]. elsif uma fuso de else e if, que significa MAS SE. Por Exemplo: Se <CordoCarro> == "Amarelo" ento <"Minha Braslia Amarela"> Mas se <CordoCarro> == "Preto" <"Fusco Pretooo..."> Mas se <CordoCarro> == "Azul" <"Minha Belina Azul, e da?"> seno <" Eu no tenho carro..."> fim Exemplos a parte, acho que foi possvel entender como ampliar a estrutura if. Mas e para aumentar a restrio das clausulas ?? Existem palavras reservadas que so exatamente para isso. elas so: and - (e) Significa que depende de uma de da outra clausula or - (ou) Significa que uma OU outra clausula Qualquer uma das RW acima pode ser usada junto com a RW not (no), para especificar que uma e no a outra e que uma ou no a outra, por exemplo: if $game_variables[1] == 1 and $game_variables[2] == 3 <> elsif $game_variables[1] == 2 or $game_variables[2] == 3 <> elsif $game_variables[1] == 3 and not $game_variables[2] == 4 <> elsif $game_variables[1] == 3 or not $game_variables[2] == 5 <> else <> end Podemos ver que vai tornando bem vasta nossa condio. Vamos aprender um pouco de matemtica do RGSS agora... Voc j deve ter se perguntado porque eu uso dois sinais de igual (==) nas clausulas do if. Para o RGSS, essa a forma de comparar valores. Pra quem gosta de matemtica (como eu) deve se lembrar de alguns dos smbolos matemticos usados pelo RGSS: == - (igualigual) compara se os valores so iguais. <= - (menorigual) Compara se o primeiro menor ou igual ao

segundo. >= - (maiorigual) Compara se o primeiro maior ou igual ao segundo != - (diferente) Compara se o primeiro e o segundo so diferentes. Com isso, podemos ampliar mais ainda nossa estrutura, recebendo apenas a resposta que precisamos. veja o exemplo: if $game_variables[1] == 1 and $game_variables[2] == 3 <> elsif $game_variables[1] == 2 or $game_variables[2] == 3 <> elsif $game_variables[1] == 3 and not $game_variables[2] == 4 <> elsif $game_variables[1] == 3 or not $game_variables[2] == 5 <> elsif $game_variables[1] == 2 or $game_variables[2] <= 3 <> elsif $game_variables[1] <= 3 and not $game_variables[2] >= 4 <> elsif $game_variables[1] >= 3 or not $game_variables[2] != 5 <> elsif $game_variables[1] != 3 or not $game_variables[2] == 5 <> else <> end ... As possibilidades se tornam infinitas. E voc deve estar se perguntando... "EU PRECISO MESMO SABER ISSO PRA PROGRAMAR EM RGSS ??" A resposta sim. variveis, classes, condies, repeties o que faz com que a programao funcione. Voc deve se lembrar de uma condicional que foi usada na nossa primeira janela, era essa: @ator == 3 ? @ator = 0 : @ator += 1 Veja que a estrutura no usou nenhuma palavra, apenas sinais. uma forma rpida de se fazer uma condio de alterao de valores. Veja que perguntado a var em questo se o seu valor igual 3. Se for, ele torna a var igual a 0(zero), se no, ele adiciona mais 1(um) a

ela. Neste caso, a ? funciona como um then, e os : como um else. J que falamos sobre o not, vamos falar de um if diferente. A palavra reservada unless serve como um if ao contrrio. o if espera um resultado verdadeiro, j o unless um resultado falso. usar unless e usar if not a mesma coisa, com as mesmas clausulas e procedimentos. Nem vou dar exemplos, o uso do unless bem simples e se restringe a apenas "aceitar um no como resposta". 2 Estrutura - Case A estrutura case asemelha-se ao if, pelo fato de tambm ser uma comparativa, e pelo fato de retornar apenas um resultado. A estrutura essa: case <condio> when <valor> <> when <valor2> <> when <valor3> <> else <> end No caso do Case, Declaramos a condio e as clausulas when (Quando) que comparam os valores. A diferena principal entre o if e o case que no caso do case no possvel o uso de and e or e nem os fazer comparaes matemticas. Ou o resultado est nos when(gera uma ao), ou no est, e no gera nada. No case possivel usar o else tambm, no caso das excees. Observe este exemplo do RGSS:

Este cdigo foi retirado da classe Game_Player, e se refere ao movimento do heri. Repare que o case diretamente no Input.dir4, que a classe se teclas.direcionais. nos when, os valores das direes e, dentro deles, o que vai acontecer quando a condicional for

verdadeira. Mas qual a vantagem de se usar if ?? E qual a vantagem de se usar case ?? O if nos permite uma gama maior de clausulas em nossa condio, mas torna o cdigo lento, pois o RGSS analiza cada condio da estrutura para saber a qual delas ele deve responder. No caso do case, ele tem menos cdigo para ler, pois ele sabe que o case vai apenas comparar o valor principal(declarado no case) com os valores declarados nos when. O material sobre o case foi um pouco mais curto, na realidade tudo que necessrio saber sobre ele foi dito. CONCLUSO: Hoje demos uma leve pincelada nas estruturas de condio. H muito o que ver sobre estas e, para o nosso caso, no h necessidade de aprofundamento. Eu queria falar nesta aula sobre as estruturas de repetio, mas o post t meio extenso e meu tempo meio curto. Eu no dei nenhum exerccio hoje, porque necessrio falar um pouco de teoria antes de entrarmos no assunto principal do RGSS, o qual eu tenho certeza que muitos esto esperando... As Scenes. Somente depois de falarmos sobre as estruturas de repetio eu entrarei neste assunto, que eu tenho certeza vai gastar umas 3 aulas... At a prxima.

Lio 7: Estruturas de Repetio


Eu tenho recebido vrios pedidos sobre como fazer animaes de introduo, e principalmente como alterar janelas ou scripts de menu. Eu posso at fazer isso, e mandar, mas se voc tem interesse em saber como funciona, tenha pacincia, eu no posso postar uma aula por dia, e mesmo se pudesse, j recebi inmeras PMs de pessoas que lem a 3 aula, e me perguntam o que so Vars...(Obviamente ele no leu a 1 aula, por achar que era desnecessrio.) Mais uma vez eu digo. Tenha pacincia. Tudo que voc precisa saber sobre RGSS para seu prprios games voc aprender aqui. Hoje eu falarei de algo muito importante na programao, que faz com que as coisas "Funcionem" nos games, as Estruturas de repetio. Este nome usado exatamente porque o que elas fazem, repetem e repetem e repetem, at que seja necessrio parar. Voc com certeza j se deparou com um cdigo assim:
Cdigo:

for i in 0...$game_party.actors.size x = 64 y = i * 116 actor = $game_party.actors[i] draw_actor_graphic(actor, x - 40, y + 80) end

ou assim:
Cdigo:

loop do Graphics.update Input.update update if $scene != self break end end

Eu pretendo demonstrar apenas as principais estruturas usadas pelo RGSS, pois existem vrias. Estrutura FOR A Estrutura for o que chamamos de estrutura programada. Nela, sabemos que quando o valor descrito como inicial chegar no valor descrito como final, a repetio termina. Podemos ter dois tipos de for: 1 - for numrico: for var in <valorinicial> ...<valorfinal> <ocorrencia> <ocorrencia> <ocorrencia> end Ex:
Cdigo:

for i in 0...$game_party.actors.size x = 64 y = i * 116 actor = $game_party.actors[i] draw_actor_graphic(actor, x - 40, y + 80) end

2 - for quantitativo: for <objeto> in <arraydeobjetos> <ocorrencia> <ocorrencia> <ocorrencia>

end Ex:
Cdigo:

for i in @map.events.keys @events[i] = Game_Event.new(@map_id, @map.events[i]) end

Note que nos dois tipos de for ele possui um valor final, o que faz com que ele seja uma estrutura programada ou, prevista, que significa que sabemos quando ela vai finalizar. O primeiro exemplo da estrutura numrica foi retirada da classe Window_MenuStatus, onde calculando a quantidade de heris presentes na Game_Party, ele desenha o char do heri. Note que a var y uma operao matemtica, que faz com que, a cada vez que i seja diferente, o desenho do char mude de lugar. Como o i tambm significa o index do heri na var, tambm mudado o char que vai ser desenhado. O segundo exemplo foi retirado da Classe Game_Map, onde atravs da quantidade de eventos do mapa, ele instnca uma nova classe Game_Event, dispensando saber se h um, ou nenhum evento. Por enquanto ainda no faremos exerccios, pois nosso grande exerccio ainda est por vir... Estrutura WHILE A Estrutura while ("faa enquanto") exatamente o que sua traduo sugere. uma estrutura simples, que pode ou no ser completada com a RW not para inverter a condio, e as RWs and e or, para complementar a condio. Veja os exemplos:
Cdigo:

while $scene != nil $scene.main end


Cdigo:

while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0 @level += 1 for j in $data_classes[@class_id].learnings if j.level == @level learn_skill(j.skill_id) end end end

No 1, A estrutura Main se obriga a executar o $scene.main toda vez que a var $scene no for vazia. No 2, Retirado da Classe Game_Actor, Ele condiciona o ganho de skills para os heris, de acordo com as suas classes e, de acordo com a experincia ganha. Estrutura loop - do Esta uma estrutura interessante, porque loop do significa refaa, ou seja, ela uma estrutura j condicionada a nunca terminar. E ela assim, s existe uma forma de parar um loop do, que usando a RW break dentro da estrutura. Observe o cdigo abaixo:
Cdigo:

loop do Graphics.update Input.update update if $scene != self break end end

Todos os Scenes do seu game possuem esta estrutura, exatamente por fazer o que necessrio. 1 - Graphics.update - Atualiza os grficos. 2 - Input.update - Atualiza as entradas de teclas 3 - update - Executa o procedimento update da classe. Aqui h um if, que verifica se ainda o mesmo $scene. 4 - if $scene != self Se a condio for falsa(ainda o mesmo) ele repete tudo, desde o incio, mas se for verdadeira(mudou a Scene) h um break e o encerramento da estrutura. Como vamos nos aprofundar mais nisto na prxima aula, voc vai ver que, de dentro do procedimento update de uma scene, tudo que faz seu game funcionar parte dali. No h muito o que dizer sobre as estruturas de repetio, a no ser pelo fato de que tudo que foi aprendido at agora(Variveis,Classes,Condies) foram apenas alicerces de algo bem maior que est por vir e que, tudo se interliga, da mesma forma que podemos ter uma "cascata" de condies, podemos ter uma cascata de fors, e de whiles, onde o while o mais parecido com o if, pois aceita vrios condicionamentos.

CONCLUSO: Hoje vimos apenas o bsico do bsico sobre Estruturas de repetio. Estou me preparando mental e fsicamente para entrar no assunto mais importante da programao em RGSS, as Scenes. Eu peo a voc que se prepare tambm, para sorver o mximo que puder a partir daqui, pois voc ver que descobriu a "Origem do Game" quando comear a entender esta que a classe mais importante do RGSS. Aos que me pediram como fazer animaes, e outras coisas, apenas depois de aprendermos sobre Scenes eu poderei postar algo aqui. Eu j tenho at os exemplos prontos, com uma animao de apresentao bem legal feita. Mas eu no posso passar o carro na frente dos bois ento... At a prxima !!

Lio 8.0 Scenes A Estrutura


Finalmente comearemos a falar sobre a Classe MAIS importante do RGSS. Mas porque a mais importante? porque as Scenes so responsveis por dar vida aos cdigos. Os objetos principais de um game so:

Tela de Ttulo Mapas Menus Batalhas Tela de Game Over

Observe a imagem abaixo:

Mas como assim, Dar vida?? As Scenes so classes pr-definidas onde a sua composio torna possvel a criao de movimento no mapa por exemplo, a exibio do menu quando apertamos uma tecla, quando entramos em batalha, e por ae vai. Primeiramente vamos entender como funciona uma Scene, para depois exeplic-la com mais nfase. Sua estrutura a seguinte: #definimos a classe: class Scene_nomedascene #definimos o procedimento principal def main #delaramos os objetos que sero usados na scene @var = objeto.new @var2 = objeto2.new #Aqui, iniciamos a estrutura de "funcionamento" #da Scene, iniciando a transio dos grficos Graphics.transition #A partir daqui, tudo que acontece dentro do #Scene vai estar nesta parte, iniciamos um loop loop do

# Atualizamos a tela de jogo Graphics.update # Atualizar a entrada de teclas Input.update #Aqui colocamos TUDO que quisermos que #Acontea no Scene <AQUI> # Abortar o loop caso a scene tenha sido alterada if $scene != self break end end #Congelamos o Scene, para iniciar #uma nova transio (de uma para a outra) Graphics.freeze #E destrumos todos os objetos que foram #declarados @var.dispose @var2.dispose end end Vejamos de uma forma mais limpa:
Cdigo:

class Scene_nomedascene def main @var = objeto.new @var2 = objeto2.new Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end Graphics.freeze @var.dispose @var2.dispose end def update #<coloque o que quiser aqui> end

endObserve que, dentro do loop, estamos atualizando os grficos e a

entrada de teclas. exatamente aqui que fazemos as coisas acontecerem. Tudo que estiver dentro deste loop ira acotecer, de acordo com a programao, como se fosse um "filme". Observe tambm que, se houver uma mudana de de Scene(if $scene != self - self ->Ela mesma) o loop quebrado(break) e tudo que estiver abaixo ocorre, como a parada nos grficos e a destruio dos objetos que foram criados. Como j aprendemos que o RGSS uma POO, para facilitar a vida no vamos encher a estrutura loop de linhas, vamos direcionar para um procedimento, no caso, o procedimento mais comum o update. No lugar do nosso #<AQUI> vamos por o update e, logo abaixo do end do procedimento main vamos criar o procedimento update.
Cdigo:

class Scene_nomedascene def main @var = objeto.new @var2 = objeto2.new Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end Graphics.freeze @var.dispose @var2.dispose end def update #<coloque o que quiser aqui> end end

Agora, tudo que for acontecer em nossa Scene partir do procedimento update. Ele foi intencionalmente chamado assim por referncia, para facilitar saber o que cada procedimento faz. Como qualquer classe, As classes Scene podem ter quantos procedimentos forem necessrios, e possuir o procedimento initialize, que por padro, sempre o primeiro procedimento da classe a ser executado(salvo a primeira Scene do game, que por padro a Classe Main chama o procedimento $scene.main). Se voc der uma olhada nas Scenes padro do RGSS, ver que

muitas delas como a Scene_Menu, possuem o procedimento initialize. L em cima eu disse que podemos declarar objetos, mas que objetos?? Na maioria das Scenes, so declaras as Janelas, As imagens(em forma de Sprites ou Planes) e as Vars. Tudo que voc v em funcionamento num game possvel por causa desse loop do, que se voc leu a aula passada, sabe que significa "faa enquanto". Enquanto est neste Scene, enquanto est dentro do loop, tudo acontece, como o movimento dos eventos no mapa, o movimento do fog, o cursor que muda de cor no menu, a prpria movimentao do cursor, e infinitas outras coisas de nossos games, como as batalhas, a seleo de heris e monstros, o uso de skills com animaes. Este apenas o incio do incio deste assunto. Na prxima aula, iniciaremos a contruo de uma Scene, para que voc entenda melhor o seu funcionamento. At l.

Lio 8.1 Nosso Primeiro Menu 1 parte


Gostaria de iniciar este tpico agradecendo a quantidade enorme de PMs que tenho recebido, em especial ao amigo reddragon, que at agora parece ser o que mais tirou proveito de minhas aulas. Na aula anterior vimos a estrutura bsica de uma Scene. Se voc foi curioso, com certeza j deu uma olhada nas Scenes dos seus projetos, e viu como simples seu funcionamento. Porm para entendermos realmente como uma Scene funciona e se comporta em determinadas situaes, vamos criar um menu personalizado, tranformando este menu:

Num menu diferenciado, para um nico heri e com funcionamento integrado com o Sistema Squad Based Action System, Assim:

Eu postarei aqui um projeto com o Menu e com o sistema j em funcionamento. Vamos l: Primeiramente, crie um novo projeto, ou use o projeto de testes(aquele antigo). Abra o Editor de Scripts. V na rea de sesses de Scenes, selecione a sesso Scene_Menu, copie-a e cole novamente antes do main. Remoneie-a para New_Menu. Esta ser nossa base. Vamos criar, alterar e excluir cdigo desta classe. Podamos construir um menu do zero, mas levaramos o triplo do

tempo. Os tipos principais de janelas de um menu: Menus so baseados em dois tipos de janelas, as de Visualizao, que so classes filhas de Window_Base, e as janelas de seleo, que uma classe complementar chamada Window_Selectable. A janela de comandos do menu, uma classe especial, chamada Window_Command, filha direta de W_selectable, que permite a criao rpida de um objeto de seleo de itens. Estas classes, alm de controlarem o cursor (Veja o apndice sobre a classe Window) geram um nmero de indexao, ou seja, A posio do cursor na janela. Vamos nossa Scene. Observe este cdigo:
Cdigo:

s1 = $data_system.words.item s2 = $data_system.words.skill s3 = $data_system.words.equip s4 = "Status" s5 = "Salvar" s6 = "Fim de Jogo" @command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6]) @command_window.index = @menu_index

Veja que declaramos 6 vars, cada uma com um texto diferente, e depois criamos um array na definio da classe. Se voc for at a sesso da Window_Command e observar seu funcionamento, vai entender que ela pr-fabricada para isso. Voc define a sua largura( o 160 do incio ) e sua altura ser definida pela quantidade de itens que voc declarou. Quer ver isso acontecer? Remova o item Status da declarao. No necessrio apagar a declarao dele, apenas na definio da classe, assim: @command_window = Window_Command.new(160, [s1, s2, s3, s5, s6]). Rode o game. O menu ficou assim:

Se voc tentar usar os dois ultimos itens do menu, vai ver que eles chamam Scenes diferentes da do seu nome. PORQUE ?? No mantemos os nmeros da forma como estavam? Apenas apagamos um item? Por causa da Indexao. Para a W_Command, no importao que est escrito no item, mas sim a sua posio na hierarquia. De cima para baixo, conte os itens como 0(zero), 1,2... No se preocupe com isso agora, vamos "consertar" isso depois. Acho que j deu pra entender um pouco sobre a indexao. Ela ser importante toda vez que voc quiser criar um objeto de seleo, seja ele um simples W_Command ou uma seleo de heris como esta:

Voltemos ao nosso Menu. Olhe a imagem final do novo menu. Ela possui alguns complementos, como barras de HP/SP, e o char do heri est dobrado de tamanho. No nosso exerccio, ele tambm tem movimento, a animao dele andando constante naquela janela. Observe que continuamos a usar as janelas de dinheiro,Passos e Tempo. porm com pequenas modificaes. Uma coisa muito importante sobre janelas, que talvez voc ainda no saiba, que elas devem respeitar uma medida padro, a de 32 pixels quadrados. Se vc dividir 640/32 = 20 e 480/32 = 15. Agora voc sabe porque os mapas mnimos tem 20/15 quadros... . ento na hora de mudar o tamanho de uma janela, tente respeitar estas medidas. ** Edit: "Voc no obrigado a respeitar as medidas, elas existem para manter a beleza das janelas. Para manter a diviso exata e no ficar nem sobrando nem faltando espaos nos seus menus. Mas a deciso sua." Se for aumentar ou diminuir seus tamanhos, tente sempre aumentar ou diminuir de 32 em 32 pixels, para que sua janela esteja sempre bonitinha. Mas aonde eu mecho nisso?? Na 3 aula, quando fizemos nossa primeira janela, declaramos a seguinte linha no initialize da janela: super(0, 0, 160, 64) onde os valores so respectivamente x, y, Largura e Altura. Como j falamos sobre janelas e tem uma apndice enorme pra ser lida, a

alterao das janelas de Tempo, passos e dinheiro ficar por sua conta. Tente fazer e, s se no conseguir, copie os cdigos abaixo:
Cdigo:

class Window_PlayTime < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear @total_sec = Graphics.frame_count / Graphics.frame_rate hour = @total_sec / 60 / 60 min = @total_sec / 60 % 60 sec = @total_sec % 60 text = sprintf("%02d:%02d:%02d", hour, min, sec) self.contents.font.color = normal_color self.contents.draw_text(4, 4, 120, 24, text, 1) end def update super if Graphics.frame_count / Graphics.frame_rate != @total_sec refresh end end endCdigo: class Window_Steps < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear self.contents.font.color = system_color self.contents.draw_text(4, 0, 120, 32, "Passos") self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120, 32, $game_party.steps.to_s, 2) end end
Cdigo:

class Window_Gold < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120-cx-2, 32, $game_party.gold.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(124-cx, 0, cx, 32, $data_system.words.gold, 2) end end

Feito isso, nossa janela est assim:

At aqui, com certeza voc j se cansou. Eu ainda no, mas se eu continuar, talvez voc no entenda bem o que est acontecendo e possa no "Querer" fazer isso. Faa tudo que foi dito, experimente, tente, poste dvidas. A nica coisa que eu quero que continuem da forma como esto na imagem, para que possamos concluir o menu. Na prxima aula, o Script de HP/SP e a janela de Status com o

movimento do heri. Nosso menu vai ganhar mais vida !! At l !!

Lio 8.2 Nosso Primeiro Menu 2 Parte


Quero iniciar esta aula agradecendo a todos pela pacincia. Tenho estado com tantos projetos ao mesmo tempo que meu tempo livre acabou. Ser Torneiro Mecnico(minha profisso), Baixista(1 Hobby), Programador(2,3 e 4 Hobbys) e Marido(Obrigao ) no nada fcil... Na aula anterior eu prometi que ia mostrar algo que muitos esperam, a muito tempo, que a animao do heroi numa janela. J vou adiantando que eu no sei se funciona com 4 ao mesmo tempo, eu sei como fazer de apenas um. Fizemos algumas alteraes nas janelas do menu, hoje vamos construir uma janela que ir substituir a janela de Status. Vamos l. Criando uma janela com Barras de HP/SP e Animao As barras no vamos criar, h vrios cdigos prontos para isso e eu no vejo necessidade de "recriarmos a roda". Para tanto, insira no projeto este cdigo:
Cdigo:

class Window_Base def draw_actor_name2(actor, x, y,align=0) self.contents.font.color = normal_color self.contents.draw_text(x, y, 64, 32, actor.name ,align) end def draw_actor_parameter2(actor, x, y, type) case type when 0 parameter_name = $data_system.words.atk parameter_value = actor.atk when 1 parameter_name = $data_system.words.pdef parameter_value = actor.pdef when 2 parameter_name = $data_system.words.mdef parameter_value = actor.mdef when 3 parameter_name = $data_system.words.str

parameter_value = actor.str when 4 parameter_name = $data_system.words.dex parameter_value = actor.dex when 5 parameter_name = $data_system.words.agi parameter_value = actor.agi when 6 parameter_name = $data_system.words.int parameter_value = actor.int end self.contents.font.color = system_color self.contents.draw_text(x, y, 120, 32, parameter_name) self.contents.font.color = normal_color self.contents.draw_text(x + 164, y, 36, 32, parameter_value.to_s, 2) end alias cbs_draw_actor_hp draw_actor_hp def draw_actor_hp(actor, x, y, width = 146, height = 15) bg = Color.new( 0, 0, 0, 160) c1 = Color.new(255, 0, 0, 0) c2 = Color.new(255, 255, 0, 160) self.contents.fill_rect(x, y, width, height, bg) width2 = width * actor.hp / actor.maxhp gradient(x + 1, y + 1, width2 - 2, height - 2, c1, c2) cbs_draw_actor_hp(actor, x, y, width) end alias cbs_draw_actor_sp draw_actor_sp def draw_actor_sp(actor, x, y, width = 146, height = 15) bg = Color.new( 0, 0, 0, 160) c1 = Color.new( 0, 0, 255, 0) c2 = Color.new( 0, 255, 255, 160) self.contents.fill_rect(x, y, width, height, bg) if actor.maxsp != 0 width2 = width * actor.sp / actor.maxsp else width2 = width * actor.sp / 1 end gradient(x + 1, y + 1, width2 - 2, height - 2, c1, c2) cbs_draw_actor_sp(actor, x, y, width) end def gradient(x, y, width, height, c1, c2) for i in 1..width x2 = x + i - 1

r = c1.red * (width - i) / width + c2.red * i / width g = c1.green * (width - i) / width + c2.green * i / width b = c1.blue * (width - i) / width + c2.blue * i / width a = c1.alpha * (width - i) / width + c2.alpha * i / width self.contents.fill_rect(x2, y, 1, height, Color.new(r, g, b, a)) end end end

Neste cdigo j h alguns complementos que usaremos depois. Inicie o cdigo da janela, chamando-a de Window_Hero_Status. Ela ter uma clausula no procedimento initialize, o heri em questo. Como vamos fazer um menu para um nico heri, vamos usar muito daqui para a frente a var $game_party.actors[0], que indica o primeiro heri da equipe. Sempre que for desenhar qualquer classe ou mdulo, lembre-se de ir colocando os end, para evitar erros futuros. Inicie o cdigo da janela assim:
Cdigo:

class Window_Hero_Status < Window_Base def initialize(actor) end end

No initialize, voc com certeza j sabe o que necessrio para o funcionamento da janela. Crie uma janela com 320 X 192, e declare as seguintes vars: @actor = actor -> O Heri em questo @frame = 0 -> Var necessria para a animao @pose = 0 -> Var necessria para a animao

E crie j um procedimento refresh. Se voc j prestou bastante ateno nas outras aulas, j sabe que so os procedimentos necessrios de uma janela. At aqui, seu cdigo deve estar assim:
Cdigo:

class Window_Hero_Status < Window_Base def initialize(actor) super(0, 0, 320, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor @frame = 0 @pose = 0

refresh end def refresh end end

Na sesso refresh, vamos desenhar o heri, nome, level, Status, Exp, HP e SP. Para isso, usaremos alguns dos procedimentos declarados como complementos da classe Window_Base. Vamos l. Inicie o Procedimento refresh com um self.contents.clear, necessrio, pois ele quem permite a aualizao da janela sem erros. Agora, usaremos alguns procedimentos usados na Window_MenuStatus. D uma boa olhada na imagem do menu anterior e, imagine quais procedimentos sero usados. Os nomes so bvios, como draw_actor_hp sabendo que draw desenhar, bem... Para que voc no se complique muito, aqui est o cdigo:
Cdigo:

draw_actor_name2(@actor, 8, 0, 1) draw_actor_class(@actor, 96, 0) draw_actor_level(@actor, 96, 24) draw_actor_state(@actor, 96, 48) self.contents.font.color = system_color self.contents.draw_text(96, 72, 80, 32, "EXP:") self.contents.font.color = normal_color self.contents.draw_text(96, 72, 160, 32, @actor.exp_s + "/" + @actor.next_exp_s , 2) draw_actor_hp(@actor, 96, 100, 172) draw_actor_sp(@actor, 96, 124, 172)

O cdigo de sua janela j deve estar assim:


Cdigo:

class Window_Hero_Status < Window_Base def initialize(actor) super(0, 0, 320, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor @frame = 0 @pose = 0 refresh end def refresh self.contents.clear draw_actor_name2(@actor, 8, 0, 1) draw_actor_class(@actor, 96, 0)

draw_actor_level(@actor, 96, 24) draw_actor_state(@actor, 96, 48) self.contents.font.color = system_color self.contents.draw_text(96, 72, 80, 32, "EXP:") self.contents.font.color = normal_color self.contents.draw_text(96, 72, 160, 32, @actor.exp_s + "/" + @actor.next_exp_s , 2) draw_actor_hp(@actor, 96, 100, 172) draw_actor_sp(@actor, 96, 124, 172) end end

Acho que no h nada pior que escrever muito e no testar... Vamos testar nossa janela substituindo-a pela Window_MenuStatus do menu. procure a seguinte linha no Scene_Menu: @status_window = Window_MenuStatus.new Aqui, declare assim: @status_window = Window_Hero_Status.new($game_party.actors[0]) repare que j enviamos para a janela o parametro do heri. Execute o game e abra o menu, ele deve estar assim:

Ele ainda no tem o heri em movimento, por enquanto... Gerar uma animao, desde que voc j tenha os quadros, simples. No caso do Heri, uma animao padro, que o RMXP usa. S vamos reproduz-la. Lembra da aula passada quando falamos de Indexao?? Bem, se voc pretende ser um bom programador, voc ver essa palavra para o resto da sua vida... ela que torna simples as tarefas que seriam complicadssimas na linguagem. Vamos ver porque. Declaramos duas vars no incio do cdigo, a @frame e a

@pose. baseado na @frame, vamos "mover" o heri, e na pose vamos mudar sua direo. Observe a imagem abaixo:

Na horizontal, temos nossos frames, na vertical nossas poses. Levando em conta a indexao(que sempre comea no zero) vamos apenas "Substituir" o quadro do heri que ser desenhado. Para isso, acrescente este procedimento na sua janela:
Cdigo:

def draw_actor_sprite #Limpa a rea onde o heroi ser desenhado self.contents.fill_rect(0, 32, 80, 120, Color.new(0, 0, 0, 0)) #Carrega a imagem do heri numa var bitmap = RPG::Cache.character(@actor.character_name, @actor.character_hue) #desenha o heri, aumentado de tamanho e no frame correnspondente self.contents.stretch_blt(Rect.new(0, 32, 80, 120), bitmap, Rect.new(bitmap.width / 4 * @frame, bitmap.height / 4 * @pose , bitmap.width / 4 , bitmap.height / 4)) end

Se voc observou bem esta matemtica acima, j entendeu como funciona a "Animao". Mas eu vou explicar. Quando usando a funo Stretch_blt, explicada na apndice sobre a classe Bitmap, ela desenha o bitmap no tamanho predefinido no rect, distorcendo se for mal calculada claro. Neste caso, eu fiz uma apliao mediana, pois as dimenses originais do char so de 32/48, aqui ele est sendo desenhado em 80/120. Agora a mgica vem aqui. Determinamos a rea que ser desenhada da imagem no Rect.new, usando uma frmula bem simples: bitmap.width / 4 * @frame Aqui, eu digo ao Rect que eu quero que ele desenhe a imagem na posio X, usando a medida do bitmap dividida por 4 e multiplicada por @frame. Se voc lembrar que qualquer valor multiplicado por 0 0, por 1 ele mesmo, e assim vai, o rect muda de frame na direo Horizontal de acordo com a variao da var @frame. A mesma coisa

acontece com a posio Y, e altura e largura no tem alteraes. No procedimento refresh, adicione esta linha logo abaixo de self.contents.clear: draw_actor_sprite Experimente rodar seu projeto agora. O menu estar assim:

O heri ainda est esttico. bem, a soluo j vem. Voc se lembra que na Scene h um loop infinito que mantm tudo atualizado no procedimento update? que todos os objetos declarados na Scene possuem um objeto.update dentro do procedimento? aqui que faremos nossa animao funcionar. Dentro da janela, insira um procedimento update, assim:
Cdigo:

def update super end

O super significa que vamos apenas complementar o procedimento, o restante fica por conta da superclasse. Lembra das condies rpidas? aqui vamos usar a contagem de frames para, a cada determinado tempo, ele atualizar a imagem. assim:
Cdigo:

if Graphics.frame_count % 10 == 0 @frame == 3 ? @frame = 0 : @frame += 1 draw_actor_sprite end

MAS O QUE FIZEMOS AQUI ?? Toda vez que a contagem de frames radiciada por 10 retornar 0, a ao ocorrer. Sim, uma radiciao, uma "Raiz". Porque isso? bem, se eu for explicar temos que abrir um tpico de aulas de

matemtica ... O mais importante que, toda vez que, na contagem de frames, existir o valor, ele efetue nossa condio. Se @frame for 3, ele a torna zero, se no, ele adiciona 1, e executa o draw_actor_sprite. Depois de feito isso, rode seu game. MARAVILHOSO !! Simples demais fazer uma animao. ( Meu pai sempre diz que depois que a ona t morta qualquer um quer pegar no rabo dela ) Se quiser mudar a direo do heri, basta mudar o valor de @pose, entre 0 e 3. UFA !! que dureza. Bem, esse foi mais um complemento do nosso menu. Ainda faltam 4 janelas, concertar funes, inserir o ABS... Bem, como eu sei que voc se deu bem com este, o mais complexo, vou passar uma lio de casa... Observe a imagem abaixo, veja o que as outras janelas tem, as duas abaixo do heri. Uma delas mostra as armas, a outra os parmetros. Todos estas funes voc as encontra na Window_Status.

Sua lio ser criar estas duas janelas, e inser-las no menu.


Mudar a posio das janelas fcil, j falamos sobre x e y e tenho certeza que pra voc ser simples. As outras( Nome do Mapa e Armas do SBAS) faremos na prxima aula. A partir de Segunda Feira(12/02/2007) Eu estarei todos os dias no Chat do site entre 12 e 13, 20 e 22 horas. Estarei explicando coisas sobre esta aula e sobre o game Online. Por enquanto s.

Obrigado.

Lio 8.3: Scenes - As janelas Especiais e a reconfigurao da Scene.


Ol amigos !! Desculpem a demora, mas tenho trabalhado muito e no tenho tido tempo pra nada. resolvi dar um jeito de terminar logo com este menu para que possamos aprender mais, acho que este assunto est muito massante sem uma necessidade real. Devido quantidade de PMs que eu tenho recebido sobre coisas que, se as pessoas parassem para ler com ateno as aulas, saberiam resolver, e devido a certos Makers que acham que esto me fazendo um favor atrapalhando o desenrolar das aulas, terminarei o menu, e depois disso passaremos para uma nova fase. Vamos ao menu ento: Lio passada eu pedi que fizessem a janela de Atributos do heri e a janela de Equipamento. Vrios de vocs, como o morzan, tiveram facilidade, e a maioria no conseguiu nada. ento, aqui est o cdigo das janelas:
Cdigo:

class Window_Equipamento < Window_Base def initialize(actor) super(0, 0, 240, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor refresh end def refresh self.contents.clear draw_item_name($data_weapons[@actor.weapon_id], 0, 0) draw_item_name($data_armors[@actor.armor1_id], 0, 32) draw_item_name($data_armors[@actor.armor2_id], 0, 64) draw_item_name($data_armors[@actor.armor3_id], 0, 96) draw_item_name($data_armors[@actor.armor4_id], 0, 128) end end #===============================================================

=============== class Window_Status2 < Window_Base def initialize(actor) super(0, 0, 240, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor refresh end def refresh self.contents.clear draw_actor_parameter(@actor, 0, 0, 0) draw_actor_parameter(@actor, 0, 21, 1) draw_actor_parameter(@actor, 0, 42, 2) draw_actor_parameter(@actor, 0, 63, 3) draw_actor_parameter(@actor, 0, 84, 4) draw_actor_parameter(@actor, 0, 105, 5) draw_actor_parameter(@actor, 0, 126, 6) end end

Peo a todos que fizeram as janelas que remoneiem para os nomes das do exemplo, para evitarmos erros. Todos conseguiram configurar a posio das janelas? No? Bem, aqui vai ento o cdigo completo do procedimento main da Scene, para que vocs tenham uma idia:
Cdigo:

def main s1 = $data_system.words.item s2 = $data_system.words.skill s3 = $data_system.words.equip s4 = "Salvar" s5 = "Fim de Jogo" @command_window = Window_Command.new(160, [s1, s2, s3, s4, s5]) @command_window.index = @menu_index @command_window.x = 640 - 160 @command_window.y = 192 if $game_party.actors.size == 0 @command_window.disable_item(0) @command_window.disable_item(1) @command_window.disable_item(2) @command_window.disable_item(3)

end if $game_system.save_disabled @command_window.disable_item(4) end @playtime_window = Window_PlayTime.new @playtime_window.x = 640 - @playtime_window.width @steps_window = Window_Steps.new @steps_window.x = 640 - @steps_window.width @steps_window.y = 64 @gold_window = Window_Gold.new @gold_window.x = 640 - @gold_window.width @gold_window.y = 128 #@mapname_window = Window_Mapname.new #@mapname_window.y = 480 - 96 @status_window = Window_Hero_Status.new($game_party.actors[0]) @status_window.y = 0 @equip_window = Window_Equipamento.new($game_party.actors[0]) @equip_window.y = 192 @stats_window = Window_Status2.new($game_party.actors[0]) @stats_window.x = 240 @stats_window.y = 192 #@dummy_window = Window_Dummy.new($game_party.actors[0]) #@dummy_window.x = 320 Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end Graphics.freeze @command_window.dispose @playtime_window.dispose @steps_window.dispose @gold_window.dispose @status_window.dispose #@mapname_window.dispose

@equip_window.dispose @stats_window.dispose #@dummy_window.dispose end

Observe que j h a declarao das janelas com o nome do mapa e com a janela de ataque do SBAS. elas esto comentadas, para evitar erros. Seu menu deve estar assim agora:

Criar uma janela que mostre o nome do mapa O RMXP tem muita coisa literalmente escondida. Seria de uma simplicidade enorme haver uma funo/procedimento que mostrasse o nome do mapa atual. Mas por padro no h. Para isso, declaramos numa var global, a $map_infos, os nomes dos mapas, lendo-os no arquivo MapInfos.rxdata. No fui eu quem inventou este cdigo. e em alguns Menus, como o do FF7 que vem no Help do XP, h esta funo, mas ela dispersa. Aqui, construiremos uma concisa. No topo do seu menu, ou em outra sesso que seja acima da sesso do menu, vamos declarar a funo name na classe Game_Map, assim:
Cdigo:

class Game_Map def name $map_infos[@map_id] end end

Isto ainda no mostra o nome do mapa, precisamos criar a funo que l para a var os nomes dos mapas. Para isso, logo baixo da funo acima, declare assim:
Cdigo:

class Scene_Title $map_infos = load_data("Data/MapInfos.rxdata") for key in $map_infos.keys $map_infos[key] = $map_infos[key].name end end

O que fizemos? Criamos uma estrutura for para ler os nomes dos mapas e grav-los na var $map_infos. E na Classe Game_map criamos o procedimento. Agora, sempre que voc quiser, na janela ou no, basta chamar $game_map[id].name. Para facilitar, vou por aqui o cdigo da janela:
Cdigo:

class Window_Mapname < Window_Base def initialize super(0, 0, 640, 96) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = 24 refresh end def refresh self.contents.clear self.contents.draw_text(4, 16, 608, 32, $game_map.name.to_s, 1) end end

Agora sim, voc pode remover o # das linhas:


Cdigo:

@mapname_window = Window_Mapname.new @mapname_window.y = 480 - 96 ... @mapname_window.dispose

Agora, o menu est quase pronto:

A ultima janela, que iria mostrar as Habilidades equipadas no SBAS, eu no vou fazer. Decidi isso porque recebi uma msg muito estranha de um Maker que se dizia "inconformado" por eu estar usando um sistema de batalha para dar aulas que no fosse um de minha autoria. O Criador do Sistema, com certeza disponibilizou o cdigo por saber que ele seria bem usado, no me importo, e espero que voc tambm no. Corrigindo o funcionamento do Menu Depois de muito mexermos com os cdigos, tenho certeza que seu menu est uma baguna. As opes no funcionam, ou do erro. Vamos comear pelo principal: Agora, voc no possui mais um menu de Status, que recebia o foco para selecionar um heroi. no procedimento update h a seguinte definio:
Cdigo:

if @command_window.active update_command return end # Se a janela de Status estiver ativa: call update_status if @status_window.active update_status

return end

Aqui, quando o menu de comandos est ativo, a scene se direciona para o procedimento update_command, quando a janela de Status, para a update_status. Como nosso menu no ter mais a janela de Status, no precisaremos verificar se ele est ativo, e no precisaremos verificar se a de Status est ativa. remova todo este cdigo e deixe somente a chamada update_command. Seu procedimento update deve estar assim:
Cdigo:

def update @command_window.update @playtime_window.update @steps_window.update @gold_window.update @status_window.update @mapname_window.update @equip_window.update @stats_window.update update_command end

Muito bem. Sabendo que o procedimento update_status no ser mais usado, voc pode remov-lo, para diminuir cdigo intil. Ele est na linha 185 do menu original. Feito isso vamos corrigir o update_command. houve um maker ae que achou que eu estava "perdido" e no sabia o que estava fazendo, at se disponibilizou para arrumar o "problema" se eu no soubesse como o fazer... Como tem pessoas ingenuas nesse mundo... Observe o procedimento update_command:
Cdigo:

def update_command # Se o boto B for pressionado if Input.trigger?(Input::B) # Reproduzir SE de cancelamento $game_system.se_play($data_system.cancel_se) # Alternar para a tela do mapa $scene = Scene_Map.new return end # Se o boto C for pressionado if Input.trigger?(Input::C) # Se o comando for outro seno Salvar, Fim de Jogo e o nmero de Heris no

# Grupo for 0 if $game_party.actors.size == 0 and @command_window.index < 4 # Reproduzir SE de erro $game_system.se_play($data_system.buzzer_se) return end # Ramificao por posio do cursor na janela de comandos case @command_window.index when 0 # Itens # Reproduzir SE de OK $game_system.se_play($data_system.decision_se) # Alternar para a tela de Itens $scene = Scene_Item.new when 1 # Habilidades # Play decision SE $game_system.se_play($data_system.decision_se) # Ativar o status da janela @command_window.active = false @status_window.active = true @status_window.index = 0 when 2 # Equipamentos # Reproduzir SE de OK $game_system.se_play($data_system.decision_se) # Ativar o status da janela @command_window.active = false @status_window.active = true @status_window.index = 0 when 3 # Status # Reproduzir SE de OK $game_system.se_play($data_system.decision_se) # Ativar o status da janela @command_window.active = false @status_window.active = true @status_window.index = 0 when 4 # Salvar # Se Salvar for proibido if $game_system.save_disabled # Reproduzir SE de erro $game_system.se_play($data_system.buzzer_se) return end # Reproduzir SE de OK $game_system.se_play($data_system.decision_se)

# Alternar para a tela de save $scene = Scene_Save.new when 5 # Fim de Jogo # Reproduzir SE de OK $game_system.se_play($data_system.decision_se) # Alternar para a tela de Fim de Jogo $scene = Scene_End.new end return end end

Procure pela linha case @command_window.index. aqui que a mgica acontece. Sempre que a janela de comandos est ativa e voc pressiona a tecla Enter/Espao o Scene vem aqui neste case, procura saber qual comando estava selecionado atravs do index da janela, e executa o comando. A primeira coisa que devemos fazer trocar o contedo do when 3 # Status pelo do when 4 # Salvar, e o do when 5 # Fim de Jogo, pelo do when 4 # Salvar. Podemos apagar o when 5 # Fim de Jogo, pois nossa janela de comandos no possui mais 6 itens, apenas 5. Outra coisa importante. Observe que when 1 e when 2 direcionam para a janela de Status:

Como no estamos mais usando a janela de Status, vamos chamar diretamente as Scenes de Skill e Equip aqui. Mas como? Se voc ainda no deletou o procedimento update_status, ver nele que ele passa como parmetro para essas Scenes o ID do heri na indexao da $game_party, em forma do index da janela, observe:
Cdigo:

$scene = Scene_Equip.new(@status_window.index) $scene = Scene_Status.new(@status_window.index)

Ao invs de passarmos o index da janela, como sabemos que nosso heri o ID do heri na indexao da $game_party 0(zero), basta colocarmos assim:
Cdigo:

$scene = Scene_Equip.new(0) $scene = Scene_Status.new(0)

e colocar as linhas nas respectivas when. O cdigo completo do procedimento:


Cdigo:

def update_command if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) $scene = Scene_Map.new return end if Input.trigger?(Input::C) if $game_party.actors.size == 0 and @command_window.index < 4 $game_system.se_play($data_system.buzzer_se) return end case @command_window.index when 0 $game_system.se_play($data_system.decision_se) $scene = Scene_Item.new when 1 # Habilidades #------------------------------------------------------# if $game_party.actors[0].restriction >= 2 $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) $scene = Scene_Skill.new(0) #------------------------------------------------------# when 2 # Equipamentos #------------------------------------------------------# $game_system.se_play($data_system.decision_se) $scene = Scene_Equip.new(0) #------------------------------------------------------# when 3 # Salvar if $game_system.save_disabled $game_system.se_play($data_system.buzzer_se) return end

$game_system.se_play($data_system.decision_se) $scene = Scene_Save.new when 4 # Fim de Jogo $game_system.se_play($data_system.decision_se) $scene = Scene_End.new end return end end

Se foi tudo feito de maneira correta, seu menu est funcionando, e com todas as funes direcionadas ao primeiro heri. A rea que ficou vazia? bem, coloque o que quiser, uma janela de fome, ou algo parecido, ela ia ficar assim:
Cdigo:

class Window_Dummy < Window_Base def initialize(actor) super(0, 0, 160, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor refresh end def refresh self.contents.clear bitmap = RPG::Cache.windowskin($game_system.windowskin_name) src_rect = Rect.new(128,64,32,32) self.contents.blt(0, 0, bitmap, src_rect) self.contents.blt(0, 42, bitmap, src_rect) self.contents.blt(0, 84, bitmap, src_rect) self.contents.blt(0, 126, bitmap, src_rect) self.contents.draw_text(0,8,32,32,"H",0) self.contents.draw_text(0,50,32,32,"J",0) self.contents.draw_text(0,92,32,32,"K",0) self.contents.draw_text(0,132,32,32,"L",0) end end

Mas mude-a de acordo com o seu gosto. Eu sei, foi terrvel. Para uma aula que seria esclarecedora, acho que surgiram muito mais dvidas. eu pretendo voltar no assunto janelas, exmplificar melhor, mostrar tudo que pode e no pode ser feito com elas. Se voc tem seguido as aulas com empenho, j sabe bastante coisa suficiente para aprofundarmos mais nos cdigos.

Tentarei no me demorar tanto para postar uma aula e, mais uma vez eu peo desculpas. estou pensando em algo bem interessante para a prxima aula, para que essa impresso ruim saia. At l, e obrigado. Ah sim, o cdigo completo da Scene, do jeito q eu fiz aqui:
Cdigo:

class Game_Map def name $map_infos[@map_id] end end class Scene_Title $map_infos = load_data("Data/MapInfos.rxdata") for key in $map_infos.keys $map_infos[key] = $map_infos[key].name end end #4############################################################## # class Window_Base def draw_actor_name2(actor, x, y,align=0) self.contents.font.color = normal_color self.contents.draw_text(x, y, 64, 32, actor.name ,align) end def draw_actor_parameter(actor, x, y, type) case type when 0 parameter_name = $data_system.words.atk parameter_value = actor.atk when 1 parameter_name = $data_system.words.pdef parameter_value = actor.pdef when 2 parameter_name = $data_system.words.mdef parameter_value = actor.mdef when 3 parameter_name = $data_system.words.str parameter_value = actor.str when 4 parameter_name = $data_system.words.dex parameter_value = actor.dex

when 5 parameter_name = $data_system.words.agi parameter_value = actor.agi when 6 parameter_name = $data_system.words.int parameter_value = actor.int end self.contents.font.color = system_color self.contents.draw_text(x, y, 120, 32, parameter_name) self.contents.font.color = normal_color self.contents.draw_text(x + 164, y, 36, 32, parameter_value.to_s, 2) end alias cbs_draw_actor_hp draw_actor_hp def draw_actor_hp(actor, x, y, width = 146, height = 15) bg = Color.new( 0, 0, 0, 160) c1 = Color.new(255, 0, 0, 0) c2 = Color.new(255, 255, 0, 160) self.contents.fill_rect(x, y, width, height, bg) width2 = width * actor.hp / actor.maxhp gradient(x + 1, y + 1, width2 - 2, height - 2, c1, c2) cbs_draw_actor_hp(actor, x, y, width) end alias cbs_draw_actor_sp draw_actor_sp def draw_actor_sp(actor, x, y, width = 146, height = 15) bg = Color.new( 0, 0, 0, 160) c1 = Color.new( 0, 0, 255, 0) c2 = Color.new( 0, 255, 255, 160) self.contents.fill_rect(x, y, width, height, bg) if actor.maxsp != 0 width2 = width * actor.sp / actor.maxsp else width2 = width * actor.sp / 1 end gradient(x + 1, y + 1, width2 - 2, height - 2, c1, c2) cbs_draw_actor_sp(actor, x, y, width) end def gradient(x, y, width, height, c1, c2) for i in 1..width x2 = x + i - 1 r = c1.red * (width - i) / width + c2.red * i / width g = c1.green * (width - i) / width + c2.green * i / width b = c1.blue * (width - i) / width + c2.blue * i / width a = c1.alpha * (width - i) / width + c2.alpha * i / width

self.contents.fill_rect(x2, y, 1, height, Color.new(r, g, b, a)) end end end #4############################################################## # class Window_Steps < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear self.contents.font.color = system_color self.contents.draw_text(4, 0, 120, 32, "Passos") self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120, 32, $game_party.steps.to_s, 2) end end #=============================================================== =============== class Window_PlayTime < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear @total_sec = Graphics.frame_count / Graphics.frame_rate hour = @total_sec / 60 / 60 min = @total_sec / 60 % 60 sec = @total_sec % 60 text = sprintf("%02d:%02d:%02d", hour, min, sec) self.contents.font.color = normal_color self.contents.draw_text(4, 4, 120, 24, text, 1) end

def update super if Graphics.frame_count / Graphics.frame_rate != @total_sec refresh end end end #=============================================================== =============== class Window_Gold < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120-cx-2, 32, $game_party.gold.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(124-cx, 0, cx, 32, $data_system.words.gold, 2) end end #=============================================================== =============== class Window_Equipamento < Window_Base def initialize(actor) super(0, 0, 240, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor refresh end def refresh self.contents.clear draw_item_name($data_weapons[@actor.weapon_id], 0, 0) draw_item_name($data_armors[@actor.armor1_id], 0, 32) draw_item_name($data_armors[@actor.armor2_id], 0, 64)

draw_item_name($data_armors[@actor.armor3_id], 0, 96) draw_item_name($data_armors[@actor.armor4_id], 0, 128) end end #=============================================================== =============== class Window_Status2 < Window_Base def initialize(actor) super(0, 0, 240, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor refresh end def refresh self.contents.clear draw_actor_parameter(@actor, 0, 0, 0) draw_actor_parameter(@actor, 0, 21, 1) draw_actor_parameter(@actor, 0, 42, 2) draw_actor_parameter(@actor, 0, 63, 3) draw_actor_parameter(@actor, 0, 84, 4) draw_actor_parameter(@actor, 0, 105, 5) draw_actor_parameter(@actor, 0, 126, 6) end end #=============================================================== =============== class Window_Hero_Status < Window_Base def initialize(actor) super(0, 0, 320, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor @frame = 0 @pose = 0 refresh end def refresh self.contents.clear draw_actor_sprite draw_actor_name2(@actor, 8, 0, 1) draw_actor_class(@actor, 96, 0)

draw_actor_level(@actor, 96, 24) draw_actor_state(@actor, 96, 48) self.contents.font.color = system_color self.contents.draw_text(96, 72, 80, 32, "EXP:") self.contents.font.color = normal_color self.contents.draw_text(96, 72, 160, 32, @actor.exp_s + "/" + @actor.next_exp_s , 2) draw_actor_hp(@actor, 96, 100, 172) draw_actor_sp(@actor, 96, 124, 172) end def draw_actor_sprite self.contents.fill_rect(0, 32, 80, 120, Color.new(0, 0, 0, 0)) bitmap = RPG::Cache.character(@actor.character_name, @actor.character_hue) self.contents.stretch_blt(Rect.new(0, 32, 80, 120), bitmap, Rect.new(bitmap.width / 4 * @frame, bitmap.height / 4 * @pose , bitmap.width / 4 , bitmap.height / 4)) end def update super if Graphics.frame_count % 10 == 0 if @frame == 3 #@pose == 3 ? @pose = 0 : @pose += 1 end @frame == 3 ? @frame = 0 : @frame += 1 draw_actor_sprite end end end #=============================================================== =============== class Window_Dummy < Window_Base def initialize(actor) super(0, 0, 160, 192) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize @actor = actor refresh end def refresh self.contents.clear bitmap = RPG::Cache.windowskin($game_system.windowskin_name)

src_rect = Rect.new(128,64,32,32) self.contents.blt(0, 0, bitmap, src_rect) self.contents.blt(0, 42, bitmap, src_rect) self.contents.blt(0, 84, bitmap, src_rect) self.contents.blt(0, 126, bitmap, src_rect) self.contents.draw_text(0,8,32,32,"H",0) self.contents.draw_text(0,50,32,32,"J",0) self.contents.draw_text(0,92,32,32,"K",0) self.contents.draw_text(0,132,32,32,"L",0) end end #=============================================================== =============== class Window_Mapname < Window_Base def initialize super(0, 0, 640, 96) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = 24 refresh end def refresh self.contents.clear self.contents.draw_text(4, 16, 608, 32, $game_map.name.to_s, 1) end end #=============================================================== =============== # Scene_Menu #=============================================================== =============== class Scene_Menu def initialize(menu_index = 0) @menu_index = menu_index end def main s1 = $data_system.words.item s2 = $data_system.words.skill s3 = $data_system.words.equip s4 = "Salvar" s5 = "Fim de Jogo" @command_window = Window_Command.new(160, [s1, s2, s3, s4,

s5]) @command_window.index = @menu_index @command_window.x = 640 - 160 @command_window.y = 192 if $game_party.actors.size == 0 @command_window.disable_item(0) @command_window.disable_item(1) @command_window.disable_item(2) @command_window.disable_item(3) end if $game_system.save_disabled @command_window.disable_item(4) end @playtime_window = Window_PlayTime.new @playtime_window.x = 640 - @playtime_window.width @steps_window = Window_Steps.new @steps_window.x = 640 - @steps_window.width @steps_window.y = 64 @gold_window = Window_Gold.new @gold_window.x = 640 - @gold_window.width @gold_window.y = 128 @mapname_window = Window_Mapname.new @mapname_window.y = 480 - 96 #@mapname_window.visible = false @status_window = Window_Hero_Status.new($game_party.actors[0]) @status_window.y = 0 @equip_window = Window_Equipamento.new($game_party.actors[0]) @equip_window.y = 192 @stats_window = Window_Status2.new($game_party.actors[0]) @stats_window.x = 240 @stats_window.y = 192 @dummy_window = Window_Dummy.new($game_party.actors[0]) @dummy_window.x = 320 @dummy_window.visible = false Graphics.transition loop do Graphics.update Input.update update if $scene != self break

end end Graphics.freeze @command_window.dispose @playtime_window.dispose @steps_window.dispose @gold_window.dispose @status_window.dispose @mapname_window.dispose @equip_window.dispose @stats_window.dispose @dummy_window.dispose end def update @command_window.update @playtime_window.update @steps_window.update @gold_window.update @status_window.update @mapname_window.update @equip_window.update @stats_window.update @dummy_window.update update_command end def update_command if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) $scene = Scene_Map.new return end if Input.trigger?(Input::C) if $game_party.actors.size == 0 and @command_window.index < 4 $game_system.se_play($data_system.buzzer_se) return end case @command_window.index when 0

$game_system.se_play($data_system.decision_se) $scene = Scene_Item.new when 1 # Habilidades #------------------------------------------------------# if $game_party.actors[0].restriction >= 2 $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) $scene = Scene_Skill.new(0) #------------------------------------------------------# when 2 # Equipamentos #------------------------------------------------------# $game_system.se_play($data_system.decision_se) $scene = Scene_Equip.new(0) #------------------------------------------------------# when 3 # Salvar if $game_system.save_disabled $game_system.se_play($data_system.buzzer_se) return end $game_system.se_play($data_system.decision_se) $scene = Scene_Save.new when 4 # Fim de Jogo $game_system.se_play($data_system.decision_se) $scene = Scene_End.new end return end end end

Lio 9: Janelas Um pouco sobre a Window_Selectable


Ol amigos !! Eu sei que parece estranho voltarmos neste assunto, mas as janelas so o tema mais importante da programao. Sim, atravz delas que vemos ou no tudo que necessrio, desde o

tempo de jogo at o HP/SP dos heris. Algumas coisas ns j sabemos sobre a classe Window, quem ainda no souber procure ler as aulas anteriores. Hoje ns vamos aprofundar neste Item to importante da programao para jogos. Primeiramente, devemos lembrar que existem 2 tipos de janelas:

Janelas Estticas Janelas Selecionveis

As Janelas Estticas so as mais comuns, como as que mostram o dinheiro e o tempo. Janelas Selecionveis so aquelas que mostram o Cursor, como a janela de seleo do menu, ou a janela de Status, onde se escolhe o heri alvo. Sabendo com preciso a aplicao de sua janela, voc j ter condies de fazer com que ela funcione. Mas o que as torna to diferentes, alm do cursor? Levando em conta que, graas ao cursor, a janela precise de dois comandos:

self.active = true/false - Indica se ela est ativa ou no self.index = numero - Indica o ncio do Cursor. Quando este valor -1(menos um) o cursor no aparece.

E de um procedimento a mais o update_cursor_rect. Neste procedimento, a janela atualiza a posio do cursor, quando este possui um tamanho diferente do padro. Alguns de meus Scripts, como o Montar Grupo de heris: http://www.jogosrpg.com.br/forum/index.php?topic=562 Usam uma janela selecionvel. Mas como diferenci-las? Toda janela esttica filha direta de Window_Base, e toda janela selecionvel filha direta de Window_Selectable. Algum engraadinho vai dizer que a Window_Selectable filha de Window_Base. Sim, ela , pois a Window_Base realmente a BASE para a construo das janelas. A Window_Selectable possui os mtodos de sua classe pai, porm ela foi desenhada para suportar o cursor, mov-lo, gerar um numero de indexao, no mover o cursor quando self.active for igual a false, essas coisas. Qualquer construtor de menus deveria saber que, antes de mais nada, deve-se conhecer a fundo a classe Window_Selectable, pois sem ela, a construo de menus seria praticamente impossvel. Eu digo praticamente pois alguem como eu que j construiu vrios

menus num sistema sem Scripts, como o Rm2k3, sabe que a dificuldade enorme. Voltemos ao assunto. H algum padro para se construir menus? No. porm h como facilitar a construo. O Prprio RGSS traz uma classe de comandos facilitada, a Window_Command, onde voc s passa como parmetros um array contendo os textos dos itens do menu, e a largura da janela. olhe este cdigo:
Cdigo:

s1 = $data_system.words.item s2 = $data_system.words.skill s3 = $data_system.words.equip s4 = "Status" s5 = "Salvar" s6 = "Fim de Jogo" @command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6]) @command_window.index = @menu_index

De s1 a s6 criada um array, dentro da declarao, usando [], diz-se que o menu ter 160 de largura, e logo abaixo da declarao diz-se que o index do cursor ser o valor da var @menu_index. Muitos ainda no sabem o que array, ou como funciona. Seria um bom tema para a prxima aula no? Observe como foi construda esta janela:
Cdigo:

class Window_Gold < Window_Base def initialize super(0, 0, 160, 64) self.contents = Bitmap.new(width - 32, height - 32) self.contents.font.name = $fontface self.contents.font.size = $fontsize refresh end def refresh self.contents.clear cx = contents.text_size($data_system.words.gold).width self.contents.font.color = normal_color self.contents.draw_text(4, 0, 120-cx-8, 32, $game_party.gold.to_s, 2) self.contents.font.color = system_color self.contents.draw_text(120-cx, 0, cx, 32, "$", 2) end end

ela uma janela esttica, ou seja, ela no possui cursor(no h a necessidade de um). Agora observe esta:

Cdigo:

class Window_PartyCommand < Window_Selectable def initialize super(0, 0, 640, 64) self.contents = Bitmap.new(width - 32, height - 32) self.back_opacity = 160 self.windowskin = RPG::Cache.windowskin("522_a2") @commands = ["Lutar", "Fugir"] @item_max = 2 @column_max = 2 draw_item(0, normal_color) draw_item(1, $game_temp.battle_can_escape ? normal_color : disabled_color) self.active = false self.visible = false self.index = 0 end def draw_item(index, color) self.contents.font.color = color rect = Rect.new(160 + index * 160 + 4, 0, 128 - 10, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) self.contents.draw_text(rect, @commands[index], 1) end def update_cursor_rect self.cursor_rect.set(160 + index * 160, 0, 128, 32) end end

Observe que esta janela possui vrios itens que a definem como Selecionvel: @item_max = 2 - A quantidade de itens que ela ter @column_max = 2 - Se esse valor for maior que 1, significa que ela ter tambm deslocamento horizontal do cursor self.active = false - No est ativa self.visible = false - No est visvel self.index = 0 - O cursor aparecer no primeiro item def update_cursor_rect - Para atualizar a posio do cursor

Observe a matemtica desta janela(Eu adoro matemtica, voc no? ), ela usa de um calculo simples para montar os itens na janela e mover o cursor sobre eles. O procedimento draw_item recebe dois paramentros, a indexao e a cor. Como a var @commands foi declarada l em cima no initialize, ele apenas usa do valor de index para saber qual item ele ir

desenhar e aonde. o parmetro color muda se caso a clausula $game_temp.battle_can_escape for false/true. No caso de nossa segunda janela, o programador no precisou "pensar" ou "calcular" aonde os itens do menu iro aparecer, o cdigo faz isso por ele. Observe esta linha: rect = Rect.new(160 + index * 160 + 4, 0, 128 - 10, 32) Ela cria uma regio onde ser desenhada o item. se voc j conhece a funo Rect, sabe que ela assim: rect = Rect.new(x, y, largura, altura) A posio X designada por aquela pequena frmula: 160 + index * 160 + 4 Se voc bom de matemtica, j sabe que em index * 160 se index for 0(zero) a conta fica assim: 160 + 0 + 4 ou seja 164 a posio X do primeiro item. No caso do segundo: 160 + 160 + 4 ou seja 324 a posio X do segundo item. Observe que o procedimento update_cursor_rect usa o mesmo clculo: self.cursor_rect.set(160 + index * 160, 0, 128, 32) Significa que sempre que voc mover o cursor, ele muda o index, e muda a posio dele. Por hoje chega. Pesquise suas janelas, observe todas que forem filhas de Window_Selectable, seus funcionamentos. Pretendo extender o assunto, mas j est grande e cansativo. Prxima aula falaremos mais sobre janelas e uma boa explicao sobre Arrays. At l !!

Lio 10: Arrays Fundamento e Utilizao


Como eu tambm no podia deixar de dedicar um tpico ao Aniversrio do JogosRPG, vamos ver hoje um dos temas de programao mais complexos(para muitos). as Variveis ARRAY. Vou comear tentando explicar o que e como funciona.
Citar array - Dicionrio Michaelis arranjo; estrutura ordenada contendo elementos acessveis individualmente referenciados por nmeros, usada para armazenar tabelas ou conjuntos de dados relacionados e de mesmo tipo;

Imagine que voc precise de 5 variveis, que sero uma sequencia(var0,var1,...,var4). quando voc declara uma var, o sistema aloca(monta) um espao na memria do computador para aquela var. Se voc declarou 5, o Sistema vai alocar 5 espaos, e criar 5 endereos para elas(O endereo pro sistema saber onde ele est, igual qdo vc pede o endereo daquela menina linda l da escola ). Dependendo da utilizao, voc vai gastar toneladas de IFs para verificar os valores dessas variveis. O Array simplifica essa declarao, primeiro que o sistema alocar um espao maior, mas com apenas um endereo de memria. O que faz com que o sistema as diferencie a indexao. ao invs de voc criar 5 vars assim: var0,var1,var2,var3,var4 = 0,0,0,0,0 Voc cria assim: var = [0,0,0,0,0] Agora, se voc quiser saber o valor de uma delas, nas duas maneiras fcil: if var1 == 0 ... if var[1] == 0 ... Mas e para saber um valor em uma determinada?? Na programao, usamos muito duas funes: Condies(if,elsif,[ ? : ]) Estruturas de repetio(while,for,loop do,until)

Nas condies, podemos perguntar uma por uma, sem problema:


Cdigo:

if var0 == 5 <condio> elsif var1 == <condio> elsif var2 == <condio> elsif var3 == <condio> elsif var4 == <condio> end

5 5 5 5

aqui, testamos uma por uma, para saber qual delas tinha o valor igual a 5. Mas imagine quantas linhas voc gastaria se fossem, ao invs de 5,

50 ? Agora, usando uma Estrutura de repetio e a declarao do array...


Cdigo:

for i in 0... var.size #Ignorando que eu sei a quantidade de itens if var[i] == 5 <condio> end end

Parece confuso... array, indexao... Voc com certeza j entendeu o que indexao. uma forma de "numerar" objetos, de forma a nos referenciarmos a ele pelo seu numero. Quando voc cria uma janela de comandos com 5 itens, a indexao dela vai de 0 a 4. A indexao facilita o no-uso de nomes para distinguir objetos dentro de um array. Sim, uma janela de comando um array. Sempre que voc criar um objeto que usa indexao, indiretamente voc est criando um array. O RGSS ainda permite algo muito maior. Um array pode conter Vrios itens dentro de cada item. Significa que se voc declarar assim:
Cdigo:

for i in 0... 50 var[i] = [10,2,"Maluco","Doido",0,""] end

Voc vai criar 50 itens, cada um com 6 itens internos, ou seja 300 itens. Podemos usar tambm o mtodo push, assim:
Cdigo:

for i in 0... 50 var.push(10,2,"Maluco","Doido",0,"") end

Eu sei, t cada vez mais confuso... Vamos citar um exemplo. No Scene_Title, quando voc inicia o game, ele cria a seguinte array: $game_party = Game_Party.new ?? Array ?? mas ele no est declarando uma classe ?? Sim, mas olha s essa declarao: $game_party.setup_starting_members Aqui, o jogo coloca na var $game_party os heris que iro comear o jogo. Vamos classe Game_Party para ver como ela funciona?, aqui est:
Cdigo:

def setup_starting_members @actors = []

for i in $data_system.party_members @actors.push($game_actors[i]) end end

Observe que ele usa como referencia outras duas vars, a $data_system e a $game_actors. Olha a definio de party_members na var data_system:
Citar party_members The initial party. An array of actor IDs. A equipe inicial. Um array com o ID dos heris.

Observando a funo setup_starting_members, vemos que a estrutura for no usa numeros. Neste caso, ela conta os itens, independente de numerao. Chamamos este tipo de for como for each, usado largamente em outras linguagens. A funo usa o mtodo push para colocar em sua var @actors, que um array(olha a declarao,@actors = []) os Heris contidos na var $game_actors. A classe Game_Actors, por sua vez, criada um array na sua inicializao(@data = []) E este array contem todos os heris do database, observe o procedimento:
Cdigo:

def [](actor_id) if actor_id > 999 or $data_actors[actor_id] == nil return nil end if @data[actor_id] == nil @data[actor_id] = Game_Actor.new(actor_id) end return @data[actor_id] end

Ento quando voc declara $game_actors[ID], ela verifica se h realmente este ID de heri, e declara na array @data a Classe Game_Actor. Vamos a ela: Logo no initialize, ela chama o procedimento setup, passando como parametro o ID do heri: actor = $data_actors[actor_id] Ento, TODAS ESTAS CLASSES, PARA MOSTRAREM UM HERI NO GRUPO, USAM DE ARRAYS E INDEXAO. Ae voc vai me dizer "Mas onde ele usou indexao ??" O ID do heroi..., um nico nmero, que faz com que toda essa avalanche de cdigo funcione. Podemos ver o quanto a indexao primria no caso de arrays. Agora vem a parte boa...

T bom, o RGSS sabe usar as arrays, e eu, como fico nessa estria ?? Voc pode usar arrays de milhares de formas. Suponhamos que voc queira criar uma atributo novo qualquer para os heris. O atributo "preguia" por exemplo. Voc no tem que desmachar o mdulo Actor para fazer isso. L no Scene_Title, declare a var, assim: $preguica = [] Agora, com um simples for, crie o array relacionado aos heris:
Cdigo:

for hero in $data_actors $preguica[hero.id] = 0 end

Agora, voc tem uma var preguia para cada heri de seu database. Quando quiser mudar o valor ou saber o valor, basta usar o ID do heri em questo. Olha a baguna: Podemos usar a classe Game_Party:
Cdigo:

#Para setar os valores: for i in 0...$game_party.actors.size $preguica[$game_party.actors[i].id] = 5 end #Para ler os valores: for i in 0...$game_party.actors.size print $preguica[$game_party.actors[i].id].to_s end

Podemos usar a var $data_actors:


Cdigo:

#Para setar os valores: for i in 0...$data_actors.size $preguica[$data_actors[i].id] = 5 end #Para ler os valores: for i in 0...$data_actors.size print $preguica[$data_actors[i].id].to_s end

Por hoje s. Foi apenas uma pincelada sobre arrays. A programao algo extenso, que depende mais de estudo e testes do que simplesmente leitura. Na prxima aula, falaremos mais sobre janelas, e comearemos a ver a contruo da classe de desenho principal, os Spritesets. At l.

E parabns ao jogosRPG, espero que eu ainda esteja por aqui para ver este frum completar 10 anos...

Lio 11: Programao: Herana,Alias e Modelagem de Procedimentos


Fiquei muito tempo afastado do RMXP. Me aprofundei no estudo do Game Maker, enquanto estudava DotNet pra entrar num novo emprego. Entrei no emprego, e agora tudo mudou. T tendo que estudar programao 16 horas por dia e tudo que antes era divertido passou a ser "Pra hora que der". Acabei descobrindo algumas coisas interessantes sobre programao que apenas o Ruby possui, e resolvi compartilhar, j que algo que muitos perguntam.... Vamos l. Nas primeiras aulas eu disse que o RMXP uma linguagem orientada a objeto que suporta herana. O que isso significa?? Significa que as Classes "Filho" herdam das Classes "Pai" seus mtodos, procedimentos, funes e variveis. Por exemplo: Todas as Classes de Janela, em suas declaraes, seus nomes vem precedidos de um sinal de <(menor) e o nome da Classe da qual ela est herdando. Veja:
Cdigo:

class Window_Selectable < Window_Base

Veja que a classe Window_Selectable filha de Window_Base. Isso significa que todos os filhos de Window_Selectable tambm herdaro a Classe Window_Base. Isso algo simples de ver na Classe Window_MenuStatus. Ela Filha de Window_Selectable, porm ela invoca o mtodo draw_actor_name, proveniente da Classe Window_Base. Sim, mas e dae?? A programao orientada a objeto foi feita para que escrevamos menos cdigo, pois, usando a herana, podemos apenas invocar mtodos e funes das classes pai sem ter que reescrev-los. Porm, algumas linguagens como C, C++ e Java(e agora Ruby) permitem que voc complemente um mtodo/procedimento/funo sem ter que reconstru-lo(claro que depende da necessidade, se o metdo far algo completamente diferente do original, voc tem que reconstruir) e sem ter que "alcanar" a Classe pai. ou seja, as modificaes

podem ser Globais(atingir a Classe pai) ou locais(Atingir apenas a Classe atual). Para isso usamos um mtodo muito visto nos scripts MADE-IN-USA, o mtodo Alias. O mtodo Alias remomeia mtodo/procedimento/funo em tempo de execuo, de forma a no mais direcionar as chamadas para o original, e sim para o novo mtodo/procedimento/funo que ser escrito para complementar o antigo. Vamos ver um exemplo simples? Abra um projeto no RMXP, Abra o Editor de Scripts e insira uma nova sesso antes do Main. Dentro dela declare isto:
Cdigo:

class Window_Base < Window alias draw_actor_name_old draw_actor_name def draw_actor_name(actor, x, y) self.contents.font.color = disabled_color self.contents.draw_text(x + 2, y + 2, 120, 32, actor.name) draw_actor_name_old(actor, x, y) end end

Observe que eu estou direcionando para a Classe Window_Base. Com isso, esta modificao alcanar todas as classes que forem "filhas" dela(no nosso caso, Todas as classes Window_). Rode o projeto e abra o menu. Observe como ficou o efeito de "sombra" no nome dos heris. Passeie pelo menu e olhe todas as janelas que mostram o nome dos heris. Em todas, o efeito de "sombra" aparece. Aparece pois modificamos a Classe MOR, de onde todas as outras classes so filhas. Modifique agora o Script que escrevemos para este:
Cdigo:

class Window_MenuStatus < Window_Selectable alias draw_actor_name_old draw_actor_name def draw_actor_name(actor, x, y) self.contents.font.color = disabled_color self.contents.draw_text(x + 2, y + 2, 120, 32, actor.name) draw_actor_name_old(actor, x, y) end end

Rode o jogo. Observe que, apenas a tela principal, a MenuStatus, possui o efeito, e todas as outras no. Mas e dae, pra qu isso vai me servir?? Bem, o exemplo mostra tudo, se voc desejar fazer uma alterao global, voce pode iniciar novamente a classe, como foi feito no exemplo, remomear o mtodo/procedimento/funo usando o mtodo alias como foi usado no exemplo, e modific-lo a vontade. Vale lembrar que o Ruby, assim como outras linguagens OOP, no

permite dois mtodo/procedimento/funo com o mesmo nome, ento quando usar Alias, lembre-se de dar a ele um nome que no exite ainda no seu projeto, ou voc receber a mensagem Stack level to deep, indicando que o mtodo/procedimento/funo est duplicado. A sintaxe do mtodo alias essa: alias nome_novo nome_antigo Um mtodo pode ser renomeado vrias vezes dentro do mesmo projeto, desde que seguidas as normas acima citadas. Algumas programaes OOP, como o DotNet(minha linguagem de trabalho agora) permite o polimorfismo, ou seja, eu posso ter vrios mtodos dentro de uma classe com o mesmo nome, diferenciando-os pelos parametros passados ou pelo tipo de parametro. Neste caso, a Engine da linguagem se encarrega de descobrir qual dos metodos ser chamado. Acho que por hoje s. Deu pra esclarecer o que e como funciona o mtodo alias e como podemos tirar proveito do que j existe no RMXP pra criarmos nossos proprios scripts. Espero que eu tenha mais tempo para escrever mais aulas, pois o assunto RGSS realmente muito extenso. At a proxma.

MINI-FAQ
Resolvi abrir um tpico especial sobre Scenes por vrios motivos. Graas ao Maker Ewertonsjn e vrias PMs recebidas, percebi que muitos tiveram dificuldade de entender o funcionamento de uma Scene. Neste Tpico vou Explicar os problemas e dvidas mais comuns. Vamos l. 1 - Eu criei uma janela, como fao para mostr-la no menu? No procedimento def main voc deve declarar uma varivel que ser a classe da janela. Procure escrever um nome que voc identifique depois, para no ter problemas. Exemplo: @janela_dinheiro = Window_Gold.new Veja que eu chamei-a de janela_dinheiro, para facilitar caso eu precise dela depois. mas ATENO !, todo Scene possui esta estrutura:
Cdigo:

Graphics.transition loop do

Graphics.update Input.update update if $scene != self break end end Graphics.freeze

A declarao de qualquer objeto deve ser feita ANTES deste cdigo. 2 - Como fao para mostrar uma imagem no fundo do menu? A mesma regra das janelas se aplica s imagens. Se voc quer mostrar uma imagem esttica, declare um Sprite, Assim: @img_fundo = Sprite.new @img_fundo.bitmap = RPG::Cache.picture("nomedaimagem") Se voc deseja mostrar uma imagem dinmica, que se mover, declare um Plane, assim: @img_fundo = Plane.new @img_fundo.bitmap = RPG::Cache.panorama("nomedaimagem") O RPG::Cache pode ser usado para qualquer pasta de imagens do projeto. A regra de onde deve ser declarada tambm igual a das janelas. 3 - Eu quero que o Mapa com o heri aparea no fundo, possvel? Sim, porm uma declarao fixa. O nome da Varivel dever ser este, por convenincia da classe Window. Voc deve declarar o Spriteset, que a visualizao do mapa. Assim: @spriteset = Spriteset_Map.new E agora o mapa aparece, como se o menu fosse transparente. Ah, voc deve abrir espao no menu para que o fundo aparea, ou voc vai achar que deu erro. 4 - Eu consegui colocar a janela, mas eu quero mudar o lugar onde ela est posicionada, possvel? Sim, possvel. Para posicionar a janela basta voc configurar, logo abaixo da declarao inicial da janela, os valores X e Y dela, Exemplo: @janela_dinheiro = Window_Gold.new @janela_dinheiro.x = 160

@janela_dinheiro.y = 32 Lembre-se, Valores que:


X menor que 0 e maior que 640 Y menor que 0 e maior que 480 Faro com que a janela suma. E Valores que:

X mais a largura da janela seja maior que 640 Y mais a altura da janela seja maior que 480 Faro com que a janela aparea cortada.

5 - Legal, Tudo funcionou. Mas agora, quando eu saio do menu, as janelas continuam l !! ao que fazer ?? Todo e qualquer objeto declarado deve ser destrudo. COMO ASSIM?? Quando declaramos um varivel, abrimos uma rea na memria, que fica ali guardando aquilo que colocamos. Por isso, se voc no "destruir"as janelas que criou, elas continuaro al, at que o sistema precise daquela memria, e veja que ela est sobrando, ae ele vai l e derruba elas. Como voc no quer esperar pelo sistema, bem simples. Lembra-se do cdigo padro das Scenes?? este:
Cdigo:

Graphics.transition loop do Graphics.update Input.update update if $scene != self break end end Graphics.freeze

Logo depois de Graphics.freeze, voc deve escrever assim: @nome_da_variavel.dispose Isso vale pra tudo, Janelas, Imagens, Spriteset. Vou demonstrar com as dos exemplos acima: @janela_dinheiro.dispose @img_fundo.bitmap.dispose @img_fundo.dispose @spriteset.dispose Repare que eu dei um Dispose na funo Bitmap da var @img_fundo. Em alguns casos, necessrio, mas nem sempre.

Fazendo isso, suas janelas desaparecero ao mudar do menu para o mapa, ou para outro Scene. 6 - PUXA !! Tudo funciona agora. Porm eu fiz uma janela com um texto varivel, como o da janela de Help, mas o texto no muda. O que h de errado? Todo e qualquer objeto que precise ser mudado dentro de uma Scene depende de uma atualizao. Se voc leu com ateno a aula 8.0, eu falo que o procedimento update responsvel pela atualizao de tudo que h na Scene. ento, dentro do def update declare o update das variveis, assim: @janela_dinheiro.update @img_fundo.update @spriteset.update E pronto. Todas as mudanas necessrias varivel sero executadas. Acho que por enquanto s. tem mais dvidas? algo que eu esqueci? poste aqui ou me mande uma PM. Terei o maior prazer em esclarecer. Abrao a todos e obrigado mais uma vez.

APNDICE
Palavras reservadas no podem ser usadas como nomes de classes, variveis ou qualquer outra coisa. Porm palavras com @ ou $ tornam-se nulas, ao entendimento do RGSS. Palavras aps o Incio de procedimentos, Exemplo def false, Tambm so consideradas nulas, entendendo-se que estas passam a ser nomes de procedimentos. As palavras reservadas so: BEGIN END alias and begin break case class ensure nil self when def false not super while defined? for or then yield do if redo true else in rescue undef elsif module retry unless end next return until

Aqui eu descrevo as funes da Classe Window. windowskin (nomedoarquivo) Refere-se ao Bitmap usado como WindowSkin Contents Refere-se ao Bitmap usado no contedo da janela Stretch(=true,=false) O modo de exibio do fundo. Se for TRUE, expande o grfico de fundo, se for FALSE, usa o modo tile(lado a lado). O valor padro TRUE. cursor_rect O Cursor(no caso de janelas c/ seleo). Active(=true,=false) Status do Cursor. Se TRUE, o cursor pisca visible (=true,=false) Se a janela est visvel. Pause(=true,=false) Pausa a visibilidade do grfico. o smbolo de seta que aparece nas janelas de mensagem, esperando que o jogador aperte o boto. x A coordenada X da Janela y A coordenada X da Janela width A Largura da Janela height A Altura da Janela z A coordenada Z da janela. Quanto maior o seu valor, mais acima a janela exibida. Se vrios objetos compartilharem o mesmo Z, o mais recente criado que ser mostrado por cima. ox A coordenada X do ponto inicial do contedo da janela. Mude este valor para rolar o contedo da janela na horizontal. oy A coordenada Y do ponto inicial do contedo da janela. Mude este valor para rolar o contedo da janela na Vertical. opacity A opacidade da Janela(0-255). Valores fora do padro so automaticamente corrigidos. back_opacity A opacidade do Fundo da janela(0-255). Valores fora do

padro so automaticamente corrigidos. contents_opacity A opacidade do Contedo da janela(0-255). Valores fora do padro so automaticamente corrigidos. Um exemplo de como usar estas Funes: Dentro da classe: self.x = 200 - Seta a posio X da janela em 200 Fora da Classe: @janela = Window_Janela.new() @janela.x = 200 - Seta a posio da Instancia da janela em 200 Textos retirados do Help em Ingls do RPGMaker, traduzido e exemplarizado por JOAONETO. Nesta apndice vou descrever o Objeto Bitmap, com seus mtodos e propriedades.

Bitmap.new(nomedoarquivo) Carrega um arquivo de imagem especificado em nomedoarquivo e cria um objeto bitmap. Ele automaticamente procura arquivos includos no RTP e em Arquivos encriptados. A extenso do arquivo pode ser omitida.(no necessria.) Bitmap.new(largura,altura) Cria um objeto bitmap com o tamanho especificado. dispose Descarrega o bitmap. Se ele j foi descarregado, nada acontece. disposed? Retorna TRUE se o bitmap foi descarregado. width Retorna a Largura do bitmap height Retorna a Altura do bitmap rect Retorna o Retngulo do bitmap blt(x, y, src_bitmap, src_rect[, opacidade]) Copia uma imagem especificada em src_bitmap no src_rect para as coordenadas especificadas(x,y) stretch_blt(dest_rect, src_bitmap, src_rect[, opacidade]) Copia redimensionando a imagem especificada em src_bitmap no src_rect para o

rect de destino(dest_rect) fill_rect(x, y,largura, altura, cor) fill_rect(rect, cor) Preenche o bitmap box(x, y,largura, altura) ou o rect(rect) com uma cor. clear Limpa o bitmap hue_change(hue) Muda o Hue do bitmap com 360 graus de alterao. Este processo consome tempo. E tambm, com os erros de converso, repetidas mudanas de Hue causam perda de cor. draw_text(x, y,largura,altura[, alinhamento]) draw_text(rect, str[, alinhamento]) Escreve um texto(str) num bitmap(x,y,largura,altura) ou num rect(rect) Se a quantidade de letras exceder o tamanho estipulado na largura, o texto autmaticamente ser reduzido de tamanho para caber. O Alinhamento possui 3 posies: 0 Esquerda, 1 Centro, 2 Direita. Por padro, ele 0. font (=nomedafonte) A fonte usada no desenho do texto. Texto retirado do Help em Ingls, traduzido por JOAONETO. A classe Sprite o conceito bsico usado para mostrar qualquer imagem na tela do jogo. A Classe Plane se parece com a Classe Sprite, porm ela "cola" lado a lado o bitmap que ela contem, esparramando-o pela tela. usada para panoramas e Fogs. * Por serem classes parecidas e com os mesmos atributos, elas estaro juntas aqui. Basta mudar a declarao do Procedimento. Procedimentos: Sprite.new([viewport]) - Cria um novo Sprite. Define-se um viewport quando necessrio. Plane.new([viewport]) - Cria um novo Plane. Define-se um viewport quando necessrio. Mtodos:

dispose - Libera o Sprite. Se j est liberado, no acontece nada. disposed? - Retorna TRUE se o Sprite foi liberado. viewport - Retorna o ViewPort especificado quando o Sprite foi criado. flash(color, duration) - Inicia um Flash no Sprite. Duration especifica o nmero de frames que vai durar. Se Color for vazio, o Sprite desaparece depois do flash. update - Atualiza o Flash do Sprite. Este mtodo deve ser chamado a cada frame. Ele se torna desnecessrio se o Sprite no vai conter Flash. Propriedades: bitmap - Refere-se ao Bitmap usado no Sprite. Ex:
Cdigo:

@sprite = Sprite.new @sprite.bitmap = RPG::Cache.icon(nome)

src_rect O Rect ocupado pelo Bitmap. visible - Se for TRUE, o Sprite est visvel. x , y, z Coordenadas. No caso da z, quanto maior o seu valor, mais alto ela est. ox , oy Coordenadas de incio do Sprite. Quando alteradas, movimentam o bitmap dentro do Sprite e, se um Viewport for declarado, o Sprite dentro do Viewport. zoom_x , zoom_y - Nveis de zoom do Sprite. 1.0 denota o tamanho atual. O zoom pode ser alterado por valores decimais, de 0.1. angle O angulo de rotao do Sprite. Especificar ngulos maiores que 360 acontece uma rotao anti-horrio. mirror - Flag responsvel pela inverso horizontal do Sprite. Se TRUE, o Sprite ser desenhado invertido. bush_depth Determina a cor de pixel que mostrada Semitrnaparente. opacity - Opacidade do Sprite(0 a 255) blend_type - Efeitos de cor (0: normal, 1: adio, 2: subtrao).

www.jogosrpg.com.br

Das könnte Ihnen auch gefallen