sexta-feira, 19 de abril de 2013

Aprendendo RGSS do zero - Aula 10

Nesta aula veremos um exemplo prático de como fazer um sistema simples de dia e noite.
O sistema basicamente consiste em um ciclo de horas de 0 a 24 onde o tom da tela é alterado em função das horas.

- Introdução

Primeiro temos que saber onde fazer esta modificação, o script é a class Scene_Map, é lá onde é atualizado todo o mapa. Quando falo em atualizar, lembre-se do método update, e é ele que iremos modificar.

Como há momentos em que não desejamos ligar o sistema, temos que fazer uma condição para que ele só funcione se a switch estiver ligada.

Então vamos criar as variáveis globais:

$secs = 0
$mins = 0
$hours = 0
$hours_var = 1
$dn_on = 1


As três primeiras são as variáveis do tempo. A penúltima é a variável que armazena a hora, é a mesma que $hours, porém para que fique melhor utilizar em eventos, por condições fica melhor associá-la a uma variável do jogo. E a última é a switch que liga e desliga o sistema.

- Modificando o método update

Antes de modificar o método precisamos criar uma variável de velocidade do tempo, poderíamos deixar o valor 1 como velocidade assim os segundos passariam normalmente, porém como é apenas um exemplo vamos colocar um valor alto para vermos o tempo passar mais rápido.

$time_speed = 35

Crie um novo script e escreva a classe Scene_Map, não se esqueça de por a classe mãe Scene_Base por meio de herança e
copie o método update.

Agora antes do end cole o código:

if $game_switches[$dn_on]
  $secs += $time_speed
  if $secs >= 60
    $secs = 0
    $mins += 1
  end
  if $mins >= 60
    $mins = 0
    $hours += 1
  end
  if $hours >= 24
    $hours = 0
    $game_variables[$hours_var] = $hours
  end
  update_screen
end


Aqui são feitas as três condições do tempo, os segundos serão incrementados pela velocidade e ao atingirem 60 ou mais serão

zerados e os minutos serão incrementados em 1, repetindo o ciclo até que os minutos sejam igual a 60, zerando-os e incrementando as horas, que por sua vez será incrementada até chegar a 24, onde voltará a ser 0.

Chamamos o método update_screen então que é o que irá fazer a tela mudar de tonalidade.

- O método da tonalidade

Crie o método:

def update_screen
  case $hours
  when 0,1,2,3,4
    $game_map.screen.start_tone_change(Tone.new(-102,-102,-102),140)
  when 5,6,7
    $game_map.screen.start_tone_change(Tone.new(-34,-34,-34),140)
  when 8,9,10,11,12,13,14,15,16,17
    $game_map.screen.start_tone_change(Tone.new(20,10,10),140)
  when 18,19,20,21,22,23
    $game_map.screen.start_tone_change(Tone.new(-68,-68,-68),140)
  end
end


Aqui são feitas condições também para verificar qual é a hora e em sua função mudar a tonalidade. Usamos a classe Game_Map que tem uma instância da Game_Screen ($game_map.screen) a qual é a responsável pela tela do jogo, e nela há o método start_tone_change que muda a tonalidade da tela. Os argumentos são o tom e a velocidade. O tom é uma classe também, portanto temos que iniciá-la com o new e os argumentos são as cores RGB (vermelho, verde, azul) que vão de 0 a 255.

Para fazermos a condição, eu utilizei o comando case, poderíamos escrever 24 if + eslsif porém esta maneira é muito mais eficiente.

Aqui está o script completo. Para testá-lo, lembre-se de ativar a switch 1.

$secs = $mins = $hours = 0
$time_speed = 35
$hours_var = 1
$dn_on = 1


class Scene_Map < Scene_Base
 
  def update
    super
    $game_map.update(true)
    $game_player.update
    $game_timer.update
    @spriteset.update
    update_scene if scene_change_ok?
    if $game_switches[$dn_on]
      $secs += $time_speed
      if $secs >= 60
        $secs = 0
        $mins += 1
      end
      if $mins >= 60
        $mins = 0
        $hours += 1
      end
      if $hours >= 24
        $hours = 0
        $game_variables[$hours_var] = $hours
      end
      update_screen
    end
  end
 
  def update_screen
    case $hours
    when 0,1,2,3,4
      $game_map.screen.start_tone_change(Tone.new(-102,-102,-102),140)
    when 5,6,7
      $game_map.screen.start_tone_change(Tone.new(-34,-34,-34),140)
    when 8,9,10,11,12,13,14,15,16,17
      $game_map.screen.start_tone_change(Tone.new(20,10,10),140)
    when 18,19,20,21,22,23
      $game_map.screen.start_tone_change(Tone.new(-68,-68,-68),140)
    end
  end
 
end

segunda-feira, 15 de abril de 2013

Aprendendo RGSS do zero - Aula 09

Nesta aula finalmente aprenderemos algo prático, na verdade será um pouco de tudo
que vimos em todas as aulas, apesar de não ter uma utilidade em si, mas é um ótimo
exemplo de como funcionam as coisas na prática.

- Introdução

A Scene que criaremos consiste em uma janela com entrada para comandos, são as setas direcionais.

Primeiro criamos um módulo com os caracteres desejados.

module Commands
  Commands = {'u' => '↑', 'd' => '↓', 'l' => '←', 'r' => '→'}
end


Utilizamos uma hash para associar cada comando a um caractere.
Os comandos ou chaves são u,d,l,r respectivamente up, down, left e right.

- Criando a janela

class Window_Commands < Window_Selectable
  def initialize(x,y,w,h)
    super(x,y,w,h)
    @commands = []
    refresh
  end
  def refresh
    contents.clear
    draw_commands
  end
  def commands
    return @commands
  end
  def draw_commands
    x = 0
    for c in @commands
      draw_text(x, 0, contents.width, 30, Commands::Commands[c])
      x += 20
    end
  end
  def pop
    return if @commands.size == 0
    @commands.pop
    refresh
  end
  def push(c)
    return if @commands.size == 14
    @commands << c
    refresh
  end
end


Vamos dividir a explicação em cada método.

No primeiro método criamos uma variável lista que armazenará os comandos u,d,l,r e chamamos o método
que escreverá eles.

No segundo, apagaremos todo o conteúdo e em seguida escreveremos novamente.

No terceiro, criamos um método que retorna a própria lista dos comandos.

No quarto, escrevemos os caracteres um a um utilizando o for, perceba que para não sobrepor cada seta,
cria-se uma variável x que será incrementada a cada repetição, assim cada vez que tiver uma seta, terá um espaço de 20 pixels.
Usamos a hash para dizer qual caractere será impresso, por exemplo se for o u, ficaria assim:

Commands::Commands['u'] # => ↑

No quinto e sexto os métodos são respectivamente de remoção e adição de comandos, como visto na aula 6.
Veja a condição em cada método, o comando só será executado caso a condição seja realizada. Não será possível remover
um comando se a lista estiver vazia e não será possível adicionar se a lista tiver 14 elementos.

- Criando a scene

class Scene_Commands < Scene_Base
  def start
    super
    draw_windows
  end
  def draw_windows
    @command_window = Window_Commands.new(10,10,310,50)
  end
  def update
    super
    return_scene if Input.trigger?(:B) and @command_window.commands.size == 0
    @command_window.pop if Input.repeat?(:B)
    @command_window.push('u') if Input.repeat?(:UP)
    @command_window.push('d') if Input.repeat?(:DOWN)
    @command_window.push('l') if Input.repeat?(:LEFT)
    @command_window.push('r') if Input.repeat?(:RIGHT)
  end
  def terminate
    super
    @command_window.dispose
  end
end


Novamente a explicação por métodos.

No primeiro, criamos o método principal e chamamos o método de criação da janela.

No segundo, criamos a janela. Perceba que o método start só é chamado uma vez, que é quando chamamos a scene, bem como este
método, pois só é preciso criar a janela uma vez!

No terceiro, fazemos várias condições de checagem de teclas. Perceba na primeira linha que retornamos a scene anterior somente se

a lista estiver vazia, isso serve para não voltar a scene simplesmente ao pressionar ESC, pois pode conter comandos ainda na

lista. Caso tenha, usamos o método pop para remover o último elemento. Em seguida criamos as quatro condições para cada tecla e

adicionamos a lista o comando respectivo.

No quarto simplesmente destruimos a janela ao sair.

- Finalizando

Copie todos os códigos e cole num script novo e teste o jogo chamando o código:

SceneManager.call(Scene_Commands)

Pronto, agora é só teclar as setas direcionais e pressionar ESC para remover o último comando ou sair.

domingo, 14 de abril de 2013

Aprendendo RGSS do zero - Aula 08

Nesta aula iremos aprender a criar Scenes. Scenes são classes que possuem uma interação com o jogador, eu costumo dizer que são a alma dos jogos, a ideia delas está amplamente ligada à janelas, pois somente as janelas não fazem a interação.

- Introdução

Antes de mais nada saiba que o nome Scene é uma convenção, você pode por qualquer nome que quiser na sua classe, porém quando se põe Scene fica mais claro o que ela é.

No RGSS3 há a classe mãe Scene_Base, que facilita muito a nossa vida, pois precisamos apenas chamar os métodos básicos e não criá-los do zero.

class Scene_Teste < Scene_Base
  def start
    super
  end
end


O método obrigatório é o start, ele faz rodar toda a janela.
Chama-se uma Scene da seguinte forma:

SceneManager.call(Nome_Da_Scene)

Note que não há necessidade de por .new pois o programa se encarrega disso.
Obviamente se você chamar o script acima verá apenas uma tela preta permanente.
Vamos adicionar um comando de voltar ao pressionar ESC:

class Scene_Teste < Scene_Base
  def start
    super
  end
  def update
    super
    return_scene if Input.trigger?(:B)
  end
end


Sempre que precisar checar se algo é cumprido ou algo do tipo, que será necessário repetir várias vezes, ou um valor atingir certo número, usa-se o método update.

Neste, tudo será repetido em um determinado tempo, no caso será sempre checada a condição de pressionada a tecla ESC (usa-se o símbolo :B) e chamamos e método return_scene que retorna a scene anterior.

- Adicionando uma janela

Para adicionarmos uma janela usamos o método start, pois será criada apenas uma vez e não várias!

class Scene_Teste < Scene_Base
  def start
    super
    @window = Window_Teste.new(0,0,200,200)
  end
  def update
    super
    return_scene if Input.trigger?(:B)
  end
end


Agora vamos adicionar um método para apagar a janela quando sairmos da Scene.

class Scene_Teste < Scene_Base
  def start
    super
    @window = Window_Teste.new(0,0,200,200)
  end
  def update
    super
    return_scene if Input.trigger?(:B)
  end
  def terminate
    super
    @window.dispose
  end
end


Este método é chamado terminate. O comando dispose é o que apaga a janela.

Por enquanto é isso, na próxima aula vamos usar um exemplo envolvendo tudo que aprendemos nas últimas aulas!

sábado, 13 de abril de 2013

Aprendendo RGSS do zero - Aula 07

Nesta aula vamos aprender um pouco sobre Windows, que são as janelas do jogo.
Uma Window é uma classe, logo toda janela é um objeto, elas são um ótimo exemplo de porque utilizar classes, visto que há dezenas de janelas, e como elas têm muito em comum, é viável usar o conceito de orientação a objeto.

- Introdução

Definimos uma janela assim:

class Window_Teste < Window_Base
end


A classe mãe é a Window_Base, herdamos todos os métodos dela.
Agora vamos utilizar o método de início.

class Window_Teste < Window_Base
  def initialize(x,y,w,h)
    super(x,y,w,h)
  end
end


O método initialize requer quatro argumentos, que são respectivamente posição x, posição y, largura e altura.

A palavra reservada super chama o método da classe mãe, nesse caso chamará o método initialize da classe Window_Base com os argumentos dados.

Crie um evento e chame o script

Window_Teste.new(10,10,200,200)

- Escrevendo textos

Agora vamos escrever um texto na nossa janela.

class Window_Teste < Window_Base
  def initialize(x,y,w,h)
    super(x,y,w,h)
    draw_text(0,0,140,30,"Hello World")
  end
end


Usa-se o método draw_text para escrever um texto. Os argumentos são os seguintes: posição x, posição y, largura do retângulo, altura do retângulo, texto

O retângulo é a área do texto.

Para fazer a janela ficar permanente e também ter interações utiliza-se as Scenes, conteúdo que veremos adiante.

- Mudando a cor

Para mudarmos a cor do texto, usa-se o método change_color

change_color(text_color(2))
change_color(Color.new(200,0,0))


O método text_color(n) retorna uma cor pré definida de acordo com a Windowskin, caso queira uma cor que não esteja disponível, use a classe Color e coloque os três argumentos RGB, de 0 a 255.

- Exemplo

Vamos colocar uma imagem na nossa janela.

class Window_Teste < Window_Base
  def initialize(x,y,w,h)
    super(x,y,w,h)
    bitmap = Cache.battler("Assassin",0)
    rect = Rect.new(0,0,bitmap.width,bitmap.height)
    contents.blt(0,0,bitmap,rect)
  end
end


Na quarta linha criamos uma Bitmap (classe das imagens e textos em geral) com o método battler do módulo Cache. O primeiro argumento é o nome do arquivo e o segundo a tonalidade.

Na quinta linha criamos um retângulo, que será a delimitação da imagem, a imagem fica dentro do retângulo. Os argumentos são os mesmos das janela, a diferença é que quando colocamos bitmap.width, bitmap.height não nos restrigimos a um valor número, o próprio programa se encarrega de pegar os valores.

Na sexta linha pegamos esse retângulo com a imagem e jogamos na janela. Os argumentos são posição x e y, imagem e o retângulo.

Você pode modificar os valores dos argumentos para entender melhor o que cada um faz.

quinta-feira, 11 de abril de 2013

Aprendendo RGSS do zero - Aula 06

Neste módulo intermediário aprederemos um pouco mais de algumas coisas que não foram vistas. É altamente recomendando que você tenha lido e entendido o módulo básico.

- Hashes

Hashes ou dicionários são váriaveis que armazenam valores, diferente das listas (arrays) hashes não se referem ao valores por índices, e sim por chaves. Declara-se hashes assim:

var = {}

Podemos também já definir os valores na declaração.

var  = {1 => "um"}
var2 = {2 => 'dois'}


Para colocar vários conjuntos numa mesma variável, use o operador vírgula:

var = {"au au" => "cachorro", "miau" => "gato"}


O operador => tem a função de associar os valores relacionados, veja como se usa as hashes:

var["au au"] # cachorro
var["miau"]  # gato


Os termos do lado esquerdo (antes do =>) são chamados chaves e os do lado direito, valores.

Perceba que se chama as hashes com o operador de array também (colchetes), porém usa-se as chaves para fazer a referência.

Pode-se usar números e símbolos e outros objetos nas chaves.

var = {1=>'um',:s="string"}

- Exemplo

Um exemplo para pegar todos os valores:

hash = {1=>"um",2=>"dois",3=>"três"}
for i in hash.keys # 1,2,3
  msgbox hash[i]
end


O método keys retorna um array das chaves [1,2,3], e em seguida são passados ao for, que neste caso não tem o operador de ponto, pois ele já sabe quantos elementos ler.


- Um pouco mais sobre arrays

Vamos aprender mais dois métodos úteis das arrays, o push e pop.

O push serve para adicionar um elemento a fila, colocando-o em último lugar.

a = [1,2,3]
a.push(4)  # a = [1,2,3,4]


Podemos também utilizar o operador <<

a = [4,5,6]
a << 7  # a = [4,5,6,7]


O pop serve para remover o último elemento da lista.

a = [1,2,3,5]
a.pop() # a = [1,2,3]



Bom, pessoal por enquanto é isso, gostaria que postassem nos comentários que tipos de aula vocês gostariam. Nas próximas irei falar sobre windows.

segunda-feira, 18 de março de 2013

Aprendendo RGSS do zero - Aula 05

Resolução do exercício anterior

def maior_elemento
    a = [5,20,50,98,68,120]
    indice = 0
    for i in 0...a.size # size é igual a length
        if a[i] > a[indice]
        indice = i
    end
    return a[indice]
end


- Introdução

Classes são elementos da programação orientada a objeto, imagine-as como um pai ou mãe que terão um ou vários filhos, estes chamados de instâncias.
A principal característica das classes é a herança, as suas instâncias terão os mesmos métodos e variáveis (somente as de classe).

Assim como definimos métodos, se define classes com uma palavra reservada.

class Nome_da_classe
end


Por conveniência se utiliza inicial maiúscula em classes e minúsculas em métodos.
Para iniciar-se uma classe não basta apenas declarar uma variável, temos que "ativá-la".

class A
    def initialize
        msgbox "Fui criada"
    end
end


A.new # Fui criada

O método initialize é comum em todas as classes, ele é o primeiro método a ser executado quando a classe é criada, porém não é necessário criá-lo.

- Herança

Agora vem a parte interessante, vamos entender este conceito. Veja o exemplo:

class Animal
    attr_accessor :nome
end

class Cachorro < Animal
    def initialize
        @nome = "Cachorro"
    end
end

class Gato < Animal
    def initialize
        @nome = "Gato"
    end
end

msgbox Cachorro.new.nome # Cachorro
msgbox Gato.new.nome     # Gato


Primeira coisa, o método attr_accessor cria um atributo da classe, no caso a variável de classe nome.
Perceba que nome é um símbolo, que é um pouco diferente das variáveis, não vou me aprofundar agora nisso, mas toda vez que for criar um atributo utilize-o desta forma.

Há três tipos de atributos:

attr_reader   => somente de leitura/consulta
attr_writer   => somente de escrita
attr_accessor => leitura e escrita


Segunda coisa, notou o operador ponto? Usamos ele também para nos referirmos à atributos, poderíamos escrever as últimas duas linhas da seguinte forma:

cachorro = Cachorro.new()
msgbox(cachorro.nome)

gato = Gato.new()
msgbox(gato.nome)


Terceira coisa, o operador < nesse caso indica herança, a classe da esquerda herda os métodos e variáveis da classe a direita.

- Métodos de classe e instância

Há dois tipos de métodos em classes, o primeiro é o de classe. Não podemos criar uma instância nele.

class Matematica
    def self.pi
        3.1415
    end
end

Matematica.new.pi # errado
Matematica.pi     # correto


Quando usamos o new, criamos uma instância dessa classe, porém nos métodos de classe não é criada uma instância, o método é simplesmente lido diretamente da classe.

Usamos o self para substituir o nome da classe, assim se mudarmos o seu nome, não será necessário mudar o nome do método, veja como é mais conveniente:

def self.pi
    3.1415
end

def Matematica.pi
    3.1415
end


Já os métodos de instância necessitam que a classe seja criada.

class Matematica
    def pi
        3.1415
    end
end


Matematica.new.pi # 3.1415

- Módulos

Os módulos são basicamente classes, porém não são criadas instâncias pois eles são somente para consulta, devem ser iniciado com letra maiúscula.
Geralmente todas as variáveis são constantes.

module Teste
    VAR = 10
    def self.m
        return VAR+VAR
    end
end

Teste::VAR  # 10
Teste.m     # 20


O operador de módulo é o ::, funciona do mesmo jeito que o . dos attr_x.
Note não é criada uma instância com o uso do new.


Acabamos a primeira parte das aulas, o nível básico. Agora entraremos no nível intermediário.
Não exite em voltar ao começo para ver o que esqueceu e pratique muito, pois não é fácil aprender algo novo, principalmente a programar.

sábado, 16 de março de 2013

Aprendendo RGSS do zero - Aula 04

Resolução do exercício anterior

i = 0
while i < $game_party.all_members.length
    msgbox $game_party.all_members[i].level
    i += 1
end


- Introdução

Nesta aula vamos falar sobre métodos!
Um método ou função é um ou um conjunto de instruções feito em um bloco.
Define-se um método da seguinte forma:

def nome_do_metodo
# instrução
end


A grande vantagem dos métodos é que assim que você os define, só
precisa chamá-los para que a ação seja executada. Isso poupa tempo e linhas de código.

Vamos a um exemplo básico:

def falar()
    msgbox "Olá"
end


Vamos chamar o método:

falar()

Note que não é preciso o uso de parêntesis, mas por convenção, usa-se. Aqueles métodos
que vimos nas outras aulas também se aplicam a essa afirmação. msgbox e exit também são métodos!

def falar_mensagem(msg)
    msgbox msg
end


A variável entre os parêntesis é chamada de argumento ou parâmetro,
dependendo do método pode não havê-lo ou haver mais de um. Ele serve para usarmos uma variável de fora nele, em resumo.

No caso acima poderia também por msgbox(msg). Os argumentos são separados por vírgula (ela também é um operador):

def falar_duas(msg1, msg2)
    msgbox msg1 + " " + msg2
end


- O comando return

Quando usamos um método e esperamos um valor de retorno, usamos o comando return.

def potencia(n, p)
    return n**p
end

O operador ** é o de potenciação. No exemplo acima podemos declarar uma variável que
receberá esse valor, veja:

var = potencia(2,3) # 2 ** 3 => 8


Atenção, assim que o return for lido, a função "quebrará", ou seja, irá parar de rodar e voltará a próxima linha
após o seu end.

def advinhar(n)
    g = rand(3)
    if g == n
        return true
    else
        msgbox g
        g = rand(3)
        advinhar(n)
    end
end


O método rand gera um número aleatório até o valor dado, no exemplo acima será 0, 1 ou 2.
Pode-se também chamar o método dentro dele próprio, esse é o conceito de recursividade.
O método continuará rodando até que o número da variável g seja o mesmo que o argumento.

- Exemplo

Vamos criar um método que verifica se o número é par.

def par_ou_impar(n)
    if n % 2 == 0
        return "é par"
    else
        return "é ímpar"
    end
end


O operador % (modulo) é o de o resto da divisão.

par_ou_impar(22) # é par
par_ou_impar 37  # é ímpar


- Outro tipo de return

Em ruby, quando a última linha tem apenas o nome da variável ou expressão, fica implícito que há o seu retorno.

def retorno_explicito(n)
    i = (n*2)+1
    return i
end

def retorno_implicito(n)
    (n*2)+1
end


- Exercício

Crie um método que retorne o maior valor de um array aleátorio (crie).
Dica: Você usará o for aqui, não se esqueça de usar o operador de maior.

Na próxima aula veremos classes.

sexta-feira, 15 de março de 2013

Aprendendo RGSS do zero - Aula 03

Vamos agora ver as estruturas de controle, que são instruções
de condição, repetição e etc.

- Continuação dos operadores

Você verá muito pela frente operadores de maior que, menor que e igualdade. Eles são muito usados em condições.

Um erro muito comum dos novatos é confundir o operador de atribuição '=' com o de comparação '==', a grande diferença é que o primeiro não é usado em controles de fluxo, é somente usado para atribuir um valor a uma variável e não para comparar com outra ou fazer uma condição.

x = 10  # atribuimos a x o valor 10
x == 10 # comparamos x com 10, se for igual, x = true, senão, x = falso


Os operadores de menor que e maior que são os seguintes:

exp < exp2 # exp menor que exp2
exp > exp2 # exp maior que exp2


Há também os de menor ou igual que e maior ou igual que:

exp <= exp2 # exp menor ou igual que exp2
exp >= exp2 # exp maior ou igual que exp2


E por último o operador diferente de.

exp != exp # falso, exp == exp
20 != 11   # verdadeiro


- Condição

A mais básica e elementar estrutura é a condição, onde simplesmente retorna um valor verdadeiro caso a expressão for verdadeira e falso se ela for falsa.

A sintaxe é a seguinte:

if exp == true
# caso for true, executa este bloco
end

 
Antes de mais nada, na linguagem Ruby, se delimita blocos com a palavra reservada end, justamente para informar o interpretador onde deve ser parado, porque senão tudo abaixo
da condição seria interpretado! Mas lembre-se, não são todas as palavras reservadas que requerem o end!

Retornando à aula, o if pode ser usado também com false:

exp = true && false # false
if exp == false
# ...
end


Quando não fica explícito um valor boolean (true/false), implica-se que o valor é true, ou seja, o valor natural da condição é verdadeiro.

if exp
# caso for verdadeiro
end

 
Há várias formas de escrever uma condição, vamos a elas!

-> Usa-se then caso queira por tudo em uma linha.
if exp == true then exp2 end

-> Há também o operador ternário.
exp == false ? exp2 : exp3

Que seria igual a isto:

if exp == false
# caso for false
else
# caso for verdadeiro
end

 
Também pode ser escrito numa linha após uma expressão.

metodo if exp
msgbox "Teste" if variavel == false


Explicarei o else agora. Ele pode ser traduzido para se não e só pode ser usado com um if pareado, não se pode usar somente ele sem o if, o contrário é possível.

if 10 > 50
# se for verdadeiro
else
# falso será executado este bloco
end


O elsif pode ser traduzido para mas se, ele funciona assim:

if exp == 1
# ...
elsif exp == 2
# mas se exp for igual a 2
elsif exp == 3
# mas se exp for igual a 3
else
# se não for nem 1,2 ou 3
end


Ele serve para evitar o uso excessivo de if.

Há também o unless, que é o contrário do if, ele tem valor de condição falso.

unless 10 == 10
# se for verdade, é igual a if 10 != 10
else
# falso, será executado este bloco
end


Exemplo, vamos a um exemplo prático. Crie um evento e chame o script:

if $game_actors[1].level > 5
   msgbox "level maior que 5"
elsif $game_actors[1].level == 5
   msgbox "level igual a 5"
else
   msgbox "level menor que 5"
end


A variável $game_actors como se vê é global e é uma instância da classe Game_Actors, que por sua vez é uma lista de Game_Actor. O índice 1 indica o primeiro personagem
e o level o atributo nível. Faça um teste modificando o nível do herói e veja o resultado.

- Repetição

Os controles de repetição são extremamente úteis, então tente entendê-los o mais rápido possível.

Começaremos pelo for.

for i in 0...10
    msgbox i.to_s
end


Este código faz com que apareça a caixinha de mensagem 10 vezes, porém o interessante é que cada vez tem um número diferente. Nesse caso usei números, a variável i armazenará 10 vezes, um valor de cada vez, no caso de 0 a 9. Então usamos o método to_s para converter de número para string, por conveniência.

A diferença entre '...' e '..' (operadores) é que o primeiro não vai até o último número, e o segundo sim.

... => 0,1,2,3,4,5,6,7,8,9
..  => 0,1,2,3,4,5,6,7,8,9,10

Podemos também utilizar o for com arrays. Já aproveito para falar um pouco delas.

Declara-se uma array da seguinte forma:

var = []

Uma array ou lista é uma variável que pode armazenar vários valores dentro dela. Vamos a um outro exemplo.

var = [1,2,3,4]

Para nos referirmos a um valor usa-se o operador '[]'. Atenção, o índice começa pelo zero!!

var[0] # => 1
var[1] # => 2
var[2] # => 3
var[3] # => 4

 
Podemos usar o for para varrer cada valor seu, e utilizá-lo na caixinha. Vamos a um exemplo mais elaborado.

for i in var
    msgbox (i*2).to_s
end


O comando next funciona como um pulo dentro do laço, caso tal condição seja alcançada, não será executada tal volta no laço.

ary = [0,2,4,8,16,32,64]
for i in 0...ary.length
  next if i == 2
  msgbox ary[i]
end


Assim aparecerão os seguintes números:
0,2,8,16,32 e 64

- Looping

Uma estrutura de looping é um laço que se repete até que uma condição seja alcançada. Há dois laços, o while e until, basicamente o while é um if o until um unless.

O while funciona da seguinte maneira:

while exp
# executa  o laço até que exp seja falso
end


É muito comum ouvir a expressão laço ou loop infinito pois se não houver mudança na expressão, o laço nunca acabará! Vamos a um exemplo!

ary = [0,2,4,8,16,32,64,128,256,512,1024]
i = 0
while i < ary.length
  msgbox ary[i].to_s
  i += 1
end

 

O método lenght retorna o tamanho do array. Então nesse caso será feito 11 repetições. Perceba a condição do loop, i < ary.lenght e veja que dentro do laço há o incremento de i por 1, isso significa que quando i == ary.lenght (11) o loop irá se quebrar.

Por falar em quebrar, vamos ao comando break

ary = [0,2,4,8,16,32,64,128,256,512,1024]
i = 0
while i < ary.length
  msgbox ary[i].to_s
  i += 1
  break if i == 5
end


O comando break faz o laço parar caso a expressão seja alcançada, nesse caso o loop irá parar se i for igual a 5.

E por fim o until. Ele signifca até que:

i = 10
until i == 0
i = i - 1
end


Funciona como o contrário do while, até que a expressão tenha um valor, será rodado o laço.

- Exemplo prático


Crie um evento e chame o código.

for i in 0...$game_party.all_members.length
    msgbox $game_party.all_members[i].name
end


Será exibida caixinhas com os nomes de todos os personagens do grupo.

Note que all_members é um método da classe Game_Party que retorna um array de Game_Actor.

Como exercício, deixo o exemplo acima, utilizando o while e use o nível ao invés do nome. A resolução virá na próxima aula.

Veremos mais sobre métodos na próxima aula.

quinta-feira, 14 de março de 2013

Aprendendo RGSS do zero - Aula 02


Nesta aula vamos falar sobre os operadores!

- Introdução

Os operadores são instruções que usamos em conjunto das variáveis ou instâncias. É com o uso deles que fazemos cálculos aritméticos, declaramos uma variável, etc.

Vamos começar pelo de atribuição:

= => Atribui ou declara uma variável.

x = 10

+ e - => Soma e subtração, respectivamente.

var1 + var2
var3 = var2 - var1

Pode-se também usar += e -=, logo as expressões e os comentários são idênticos:

v += 10 # v = v + 10
v -= v  # v = v - v

* e / => Multiplicação e divisão, respectivamente.

10 * 58
v / v

Também pode-se usar *= e /= como acima.

+ e - (Unários) => Sinal positivo e negativo, respectivamente:

-10
+58

! => Negador, troca o valor da expressão (verdadeiro ou falso):

!true # => false
!false # => true

&& ou and => AND (e), retorna verdadeiro se duas expressões forem verdadeiras, falso se pelo menos uma for falsa e falso se todas forem falsas.

true && true   # => true
true && false  # => false
false && false # => false

|| ou or => OR (ou), retorna verdadeiro se duas expressões forem verdadeiras, verdadeiro se pelo menos uma for falsa e falso se todas forem falsas.

true || true   # => true
true || false  # => true
false || false # => false

. => Usa-se para chamar uma variável ou método de uma classe ou módulo.

class A
     attr_accessor :var
     def metodo
       msgbox "método chamado"
     end
end

A.metodo # "método chamado"
A.var    # valor de var

() => Usa-se para tornar uma expressão separada da outra, assim, evita-se que haja problemas com prioridade, também para chamar um método, porém não é obrigatório.

x = (10/2)*(5+8)-8 # => (5*13)-8

Há outros que serão apresentados futuramente.

- Propriedades dos operadores

Por conveniência e melhor legibilidade usa-se espaço para separar os operadores dos operandos, mas pode-se também escrever toda a expressão junta:

a=10+b*4 # a = 10 + b * 4
x*2/4-y  # x * 2 / 4 - y

Há também prioridade entre os operadores, ou seja, a propriedade de um operador ser lido e interpretado antes do outro.

Aqui está a lista de prioridade, em ordem decrescente:

::
[]
**
-(unary)  +(unary)  !  ~
*  /  %
+  -
<< >>
&
|  ^
> >=  < <=
<=> ==  === !=  =~  !~
&&
||
..  ...
?:(conditional operator)
=(+=, -= ... )
not
and or

Vamos agora ver exemplos com prioridades.

a = 10*5-4
a = 98-10/2

A resposta será:

a = (10*5)-4    # 46
a = 98-(10/2)   # 93 

Pois os operadores * e / tem maior prioridade que + e -, logo são interpretados antes. Para mudar a o ordem de interpretação, separa-se a expressão com o operador parêntesis. Como mostrado acima.

Na próxima aula falaremos de estrutura de controle e outros operadores.

Aprendendo RGSS do zero - Aula 01

Olá pessoal, estou aqui para iniciar uma série de aulas de RGSS. Note que quando falo RGSS, não estou especificando qual, visto que todos os três têm muita coisa em comum, tudo que faço num, posso fazer noutro, com pouquíssimas exceções. A grande diferença deles é que cada versão utiliza um "sistema de classes" diferentes, ou seja, a forma a qual as classes são feitas. Por exemplo, no RGSS1 não há uma classe base para scenes, já presente no RGSS2, enquanto que neste não há classes gerenciadoras de procedimentos, presente no RGSS3.

Bom, na primeira aula vamos ver um pouco de tudo.

- Introdução

Caso você não saiba nada de linguagem de programação, saiba que RGSS é a linguagem Ruby utilizada no RPG Maker. Um código ou script é um conjunto de instruções que o programa usa para transformar em "ações". Para fazer uma janela aparecer e sumir, utiliza-se eles.

Saiba também que um script é lido de cima para baixo e linearmente, ou seja, linha por linha, se houver um erro de programação numa linha e eventualmente causar um loop, a próxima linha não será lida e executada.

Antes de tudo saiba onde ver a lista de scripts. É um ícone de um papel com um lápis (RMVX Ace), porém em todas as versões pode-se abri-lo com a tecla F11. Outra informação importante é o fato dos scripts serem lidos de cima para baixo, não, não é uma repetição do que disse antes, me refiro ao fato do programa ler script por script de cima para baixo, isso significa que você não pode por um script que faz referência ou o modifica acima pois ele ainda não foi lido! Por exemplo, não dá para por o script Scene_Menu acima de Scene_Base pois esse faz o uso de herança deste.

- Começando

Primeiro vamos saber o que cada coias é. O editor facilita nossas vidas dando cor a cada elemento da linguagem. Aqui vão as cores:

  • Verde: Comentário, não é lido pelo interpretador, geralmente é deixado como instruções.
  • Azul: Palavras reservadas da linguagem, não podendo ser usadas como variáveis.
  • Azul claro: Operadores.
  • Azul escuro: Classes ou métodos.
  • Roxo: Strings, basicamente textos.
  • Preto: Identificadores. São os nomes das classes, variáveis e métodos.
  • Vinho: Números.
  • Laranja: Símbolos.

- As variáveis

As variáveis são os elementos mais importantes do RGSS e de qualquer linguagem de programação. Não quero complicar o conceito, mas entenda elas como uma folha de papel a qual pode ser escrita qualquer coisa. O seus valores podem ser de qualquer coisa, ou objeto, sendo específico. A função da variável é armazenar valores.

Vamos a um breve exemplo.
Abra o editor e logo acima do script Vocab, insira um novo script em branco.
Nele escreva o seguinte código:

msgbox "10" # Use print "10" no RGSS1 e RGSS2
exit

O código acima faz com que seja exibida a mensagem de aviso com o texto 10.
Atenção, você pode também por 10 sem aspas, assim deixando de ser string e virando um número (Integer). Mas não é indicado pois quando se trata de mensagens, deve-se usar textos (Strings).

Note que msgbox e exit são métodos, veremos eles mais adiante.
Agora vamos usar uma variável para armazenar o valor e depois exibir a mensagem com seu valor:

var = "10"
msgbox var
exit

Na primeira linha nós declaramos a variável, ou seja, criamos e damos um valor a ela, no caso uma string. Isso é feito da seguinte forma:

nome_da_variável = valor

Atenção, não se pode dar um nome a um identificador, no caso a variável, com espaços, usa-se o "underline". Em seguida o operador igual e o valor. Veremos o valor a seguir.

- Os valores das variáveis

Um valor é um objeto, tudo em Ruby é objeto, ou seja, instância de uma classe, para não complicar entenda que cada valor tem seus atributos, propriedades e métodos.
Não posso usar o método de dividir em uma string, mas posso usá-lo em um número.
Da mesma forma, não posso usar o método de trocar um caractere numa string por outro
num número.

Aqui estão alguns valores:

String: Textos, são delimitados pelo operador "" (aspas), devem ter começo e fim, ou seja, "texto é errado, pois todo o resto do script estará dentro da string.
"Texto"

Número inteiro (Integer): São os números inteiros, nada a acrescentar.
50

Número decimais (Float): São os números decimais separados por um ponto.
10.69

Listas (Arrays): Tipo de variáveis que armazena vários valores em si.
[10,20,30,"oi",58.69]

Boolean: Tem apenas dois valores, verdadeiro ou falso.
true, false

Note que há vários outros tipos, você mesmo pode criar o seu, geralmente com o uso de classes.

- Os tipos de variáveis

Agora vamos conhecer como as variáveis são classificadas:

Locais: Variáveis que só funcionam no escopo local.

var = "10"
msgbox var
def metodo
    var = "20"
    return var
end
msgbox metodo

Veja que agora elas têm valores diferentes. Uma é diferente da outra.

Classe: Variáveis que funcionam em toda classe ou num escopo de classe.

@var = "10"
msgbox @var
def metodo
    #var = "20"
    return @var
end
msgbox metodo

Para tornar uma variável de classe basta adicionar @ como prefixo.

Globais: Variáveis que funcionam em todo escopo de jogo.

Um exemplo é a variável game_switches que é uma lista. Pode-se usá-la
em qualquer script. Para torná-la global adiciona $ como prefixo.

Faça um teste criando um evento e chame o script:

if $game_switches[1] == true
   msgbox "Switch ativada"
else
   msgbox "Switch desativada"
end

Constantes: Variáveis que servem apenas para consulta, iniciam-se com letra maiúscula, têm escopo global.
PI = 3.14

- Exemplo

Agora que sabemos identificar o que é cada coisa, fica muito mais fácil de trabalhar.
Vamos começar editando uma string, a do título, especificamente. Para isso vamos ao script Scene_Title. Na linha 92:

def create_command_window
    @command_window = Window_TitleCommand.new
    @command_window.set_handler(:new_game, method(:command_new_game))
    @command_window.set_handler(:continue, method(:command_continue))
    @command_window.set_handler(:shutdown, method(:command_shutdown))
end

Perceba a menção ao Window_TitleCommand, o .new indica a criação dele. Isso quer dizer que será criada esta classe, vamos então à ela.

Na linha 34 há o seguinte trecho:

def make_command_list
    add_command(Vocab::new_game, :new_game)
    add_command(Vocab::continue, :continue, continue_enabled)
    add_command(Vocab::shutdown, :shutdown)
end

Perceba a sequência "Vocab::_nome_", o Vocab é um módulo, você pode confirmar isso ao vê-lo no editor, ele é o primeiro script. Logo de cara você verá module Vocab.

Um módulo é uma livraria onde se armazena variáveis e métodos, diferente das classes os módulos são somente para leitura e consulta.

O operador :: indica a consulta em si do módulo, neste caso os métodos são new_game, continue e shutdown (a palavra def indica método). Na linha 140 você verá o seguinte trecho:

def self.new_game;    command(18);  end   # Novo Jogo
def self.continue;    command(19);  end   # Continuar
def self.shutdown;    command(20);  end   # Sair

As linhas poderiam ser escritas da seguinte forma:

def self.new_game # Novo Jogo
    command(18)
end
# ....

Você deve estar confuso agora, vamos em breve veremos os métodos.
O importante agora é notar este command(18), ele faz referência a um texto específico do Database, neste caso o de "Novo Jogo". Vamos alterá-lo para
"Novo Teste". Deixe assim essas linhas:

def self.new_game;    "Novo Teste";  end   # Novo Jogo
def self.continue;    command(19);  end    # Continuar
def self.shutdown;    command(20);  end    # Sair

Dê OK e teste o jogo. Viu que o nome na janela mudou?
Isso aconteceu porque substituímos uma string por outra, um texto por outro, não poderíamos substituir um texto por um número ou outra coisa!

Agora faça um teste modificando também os comandos "Continuar" e "Sair".