Desenvolvendo Web-Games com Ruby on Rails Game Development School 2011
Oi • Endel Dreyer • Aluno de Jogos Digitais • Desenvolvedor na Ocapi (ocapi.com.br) • Utiliza Ruby / Rails à 2 anos http://twitter.com/endel http://github.com/endel
Ruby • Japão, 1993 • Perl / Smalltalk / Lisp • Interpretada • Tipagem dinâmica e forte puts "Hello world!" • Expressiva
bléh!
=)
Operadores aritméticos • Soma: + • Subtração: - • Multiplicação: * • Divisão: / • Módulo: % • Expoente: **
Operadores lógicos • Igualdade ==, <, <=, >, >= 5 == 4 => false • And && true && false => false • Or || true || false => true • Not ! !false => true Igual: C++, PHP, Java, etc
Operadores lógicos • Comparativo <=> (retorna 0, -1 ou 1) 7 <=> 5 => 1 • Ternário ? : (5 == 5) ? “Ok” : “Errado” => “Ok”
Core classes Integer, String, Symbol, Array, Hash, etc.
Core classes: Integer numero = 5 numero.is_a? Integer # => true numero += 1.2 # => 6.2 numero.is_a? Integer # => false numero.is_a? Float # => true
Core classes: Integer • 83.odd? # => true • 83.even? # => false • 83.chr # => "S"
Core classes: String nome = "Joselito" "Oi, meu nome é #{nome}"   # => "Oi, meu nome é Joselito" 'Oi, meu nome é #{nome}' # => "Oi, meu nome é #{nome}"
Core classes: String string = "Sou uma string bonita" string.length # => 21 string[15..-1] # => "bonita" string[15..-1] = "feiosa!" # => "Sou uma string feiosa!" string.gsub('feiosa!', 'bonitona') #  => "Sou uma string bonitona"
Core classes: String • “Hello”.upcase # => “HELLO” • “Hello”.reverse # => “olleH” • “Hello” * 5 # => “HelloHelloHelloHelloHello” •“ Hello “.strip # => “Hello”
Core classes: Symbol • Imutáveis • Únicos em toda a aplicação sym = :simbolo sym.object_id        # => 332668 sym2 = :simbolo sym2.object_id       # => 332668   str = "uma string" str.object_id        # => 2149466880 str2 = "uma string" str2.object_id       # => 2149437560
Core classes: Array • Armazenam qualquer tipo de objeto • Índices inteiros array1 = [1, 2, 3, 2] array2 = Array.new     # => [] array3 = Array.new(5) # => [nil, nil, nil, nil, nil]
Core classes: Array array = [1, 2, 3, 2] array << 4 # => [1, 2, 3, 2, 4] array.pop # => 4 array.shift # => 1 array.uniq # => [2,3]
Core classes: Array notas = [8, 4, 5.9, 9, 4, 10] notas.select {|nota| nota >= 6 } #  => [8, 9, 10] notas.sort # => [4, 4, 5.9, 8, 9, 10] OBS: Blocos podem ser entre {} ou do / end
Core classes: Hash • Similar ao Array • Armazenam qualquer tipo de objeto • Índices podem ser qualquer tipo de objeto hash = Hash.new hash2 = {1 => 'um', 2 => 'dois'}
Core classes: Hash hash = {:um => 1, :dois => 2} hash['um'] # => nil hash[:um] # => 1 hash[:tres] = 3 hash.keys # => [:um, :dois, :tres] hash.values # => [1, 2, 3]
Notação literal • Array array = [1, 2, 3] • Símbolos symbol = :simbolo • Hash hash = {:first => “value”, :second => “Value”} • Expressões Regulares regexp = /[0-9]{8}/
Tudo é objeto 3.class                   # => Fixnum 3.14.class                # => Float :simbolo.class            # => Symbol [1,2,3].class             # => Array /expressao/i.class       # => Regexp {:key => 'value'}.class # => Hash Array.class               # => Class
Fluxo: Condicionais • if • unless if condição bloco de código end unless condição bloco de código variavel = 5 if condição end variavel = 5 unless condição
Fluxo: Case / When nota = 6 case nota when 10 then puts "Excelente!" when 8..9 then puts "Muito bom" when 6..7 then puts "Regular" else puts "Noob!" end
Fluxo: Loops • begin...end while • enquanto (...) faça (...) begin   alguma_coisa end while (condicao == true)
Fluxo: Loops • begin...end until • faça (...) até (...) begin   alguma_coisa end until (condicao == true)
Fluxo: Loops • Array#each [1,2,3,4].each do |item| puts item end
Fluxo: Loops • Hash#each_pair {:first => 1, :second => 2}.each_pair do |key, value| puts "#{key} => #{value}" end
Fluxo: Loops • Integer#times • Integer#upto • Integer#downto 5.times do |i| 0.upto(10) do |i| puts i puts i end end
Fluxo: Loops • String#each_line • String#each_char • String#each_byte "Hello world".each_line do |line| puts line end
Convenções e nomenclaturas • Classes e módulos: CamelCase • Métodos e variáveis locais: com_underlines • Variáveis de instância: @com_arroba • Variáveis de classe: @@duplo_arroba • Constantes: UPPER_CASE • Variáveis globais: $COM_DOLAR
Convenções e nomenclaturas • Métodos modificadores: finalizam em “!” • Ex: ”string”.upcase! # => ”STRING” [1,2,2,3,2].uniq! # => [1,2,3] • Métodos que retornam Boolean: finalizam em “?” • Ex: [1,2,3].include? 5 # => false 5.is_a? String # => false
Funções • A última expressão é o retorno da função def soma(n1, n2)     return n1 + n2 end def soma(n1, n2)     n1 + n2 end soma(7, 2) # => 9 soma("Oi", "Tchau") # => "OiTchau"
Funções • A última expressão é o retorno da função def soma(n1, n2)     return n1 + n2 end def soma(n1, n2)     n1 + n2 end soma 7, 2 # => 9 soma "Oi", "Tchau" # => "OiTchau" Parênteses são opcionais
Funções • Argumentos default def cumprimentar(nome = "anônimo")     "Olá, #{nome}!" end   cumprimentar            # => "Olá, anônimo!" cumprimentar("pessoal") # => "Olá, pessoal!"
Funções • Method missing def method_missing(name, *args)     "Método '#{name}' não foi definido. Argumentos: # {args.inspect}" end   alguma_coisa(1) # => "Método 'alguma_coisa' não foi definido. Argumentos: [1]"
Arrays e hashes implícitos array = 1, 2, 3 # => [1, 2, 3] hash = :um => 1, :dois => 2 # => {:um => 1, :dois => 2}
circle.rb Classes class Circle # constant PI = 3.141592653589793 # getter and setter attr_accessor :id # getters attr_reader :diameter, main.rb :radius require './circle.rb' def initialize(id, radius = nil) circle = Circle.new('My beautiful circle', 7) @id = id circle.area radius = radius unless radius.nil? => 153.93804002589985 end circle.circunference def radius= radius => 43.982297150257104 @radius = radius circle.diameter @diameter = radius * 2 => 14 end Circle::PI => 3.141592653589793 def area PI * (@radius ** 2) end def circunference PI * @diameter end end
Rails “Web development that doesn’t hurt”
Rails • Padrão MVC (Model-View-Controller) • Convenção sobre configuração (CoC) • Não repita a si mesmo (DRY) • Objeto-relacional (ORM)
Quem está usando?
Setup • $ gem install rails • $ rails new nome_do_projeto
Estrutura padrão Arquivo/Diretório Finalidade Especifica as dependências de “gems” para a Gemfile aplicação. app/ Controllers, models e views da aplicação. public/ Arquivos públicos. Javascript, CSS, Imagens, etc. Configurações da aplicação: rotas, banco de config/ dados, etc. lib/ Módulos para extensão da aplicação. db/ Migrações do banco de dados. vendor/ Códigos de terceiros. “Gems” estáticas. log/ Arquivos de log da aplicação.
MVC
MVC
Models • Objetos que representam uma entidade no banco de dados $ rails generate model personagem nome:string level:integer exp:integer hp:integer
Models • Objetos que representam uma entidade no banco de dados $ rails generate model personagem nome:string level:integer exp:integer Convenção: Singular hp:integer
Models • Objetos que representam uma entidade no banco de dados $ rails generate model personagem nome:string level:integer exp:integer hp:integer campo : tipo
Models $ rails generate model {identificador} {atributo}:[ integer, boolean, string, text, float, decimal, datetime, timestamp, time, date, binary]
Models • Extendem ActiveRecord::Base class Personagem < ActiveRecord::Base end
Models • Extendem ActiveRecord::Base • Devem gerenciar o comportamento do objeto class Personagem < ActiveRecord::Base   def level_up!     level += 1     save   end end
Models • Criando registros Personagem.create(:nome => "Joselito", :level => 1, :exp => 0, :hp => 100)
Models • Encontrando registros Personagem.where(:level => 10).first Personagem.where(:level => 10).all
MVC
Controllers • Recebem a entrada do usuário • Fazem chamadas aos models • Renderizam uma view $ rails generate controller personagens
Controllers • Recebem a entrada do usuário • Fazem chamadas aos models • Renderizam uma view class PersonagensController < ApplicationController end
Controllers • Recebem a entrada do usuário • Fazem chamadas aos models • Renderizam uma view • Cada método corresponde à uma URL class PersonagensController < ApplicationController     def criar     end end http://localhost:3000/personagens/criar
MVC
Views • HTML / ERB • Interface de usuário
Bora codar?
Material para estudos • http://guides.rubyonrails.org/ • http://railscasts.com/

Ruby on rails gds 2011

  • 1.
    Desenvolvendo Web-Games com Ruby on Rails Game Development School 2011
  • 2.
    Oi • Endel Dreyer •Aluno de Jogos Digitais • Desenvolvedor na Ocapi (ocapi.com.br) • Utiliza Ruby / Rails à 2 anos http://twitter.com/endel http://github.com/endel
  • 3.
    Ruby • Japão, 1993 •Perl / Smalltalk / Lisp • Interpretada • Tipagem dinâmica e forte puts "Hello world!" • Expressiva
  • 4.
  • 5.
  • 6.
    Operadores aritméticos • Soma:+ • Subtração: - • Multiplicação: * • Divisão: / • Módulo: % • Expoente: **
  • 7.
    Operadores lógicos • Igualdade ==, <, <=, >, >= 5 == 4 => false • And && true && false => false • Or || true || false => true • Not ! !false => true Igual: C++, PHP, Java, etc
  • 8.
    Operadores lógicos • Comparativo<=> (retorna 0, -1 ou 1) 7 <=> 5 => 1 • Ternário ? : (5 == 5) ? “Ok” : “Errado” => “Ok”
  • 9.
    Core classes Integer, String,Symbol, Array, Hash, etc.
  • 10.
    Core classes: Integer numero = 5 numero.is_a? Integer # => true numero += 1.2 # => 6.2 numero.is_a? Integer # => false numero.is_a? Float # => true
  • 11.
    Core classes: Integer • 83.odd? # => true • 83.even? # => false • 83.chr # => "S"
  • 12.
    Core classes: String nome = "Joselito" "Oi, meu nome é #{nome}"   # => "Oi, meu nome é Joselito" 'Oi, meu nome é #{nome}' # => "Oi, meu nome é #{nome}"
  • 13.
    Core classes: String string = "Sou uma string bonita" string.length # => 21 string[15..-1] # => "bonita" string[15..-1] = "feiosa!" # => "Sou uma string feiosa!" string.gsub('feiosa!', 'bonitona') #  => "Sou uma string bonitona"
  • 14.
    Core classes: String • “Hello”.upcase # => “HELLO” • “Hello”.reverse # => “olleH” • “Hello” * 5 # => “HelloHelloHelloHelloHello” •“ Hello “.strip # => “Hello”
  • 15.
    Core classes: Symbol • Imutáveis • Únicos em toda a aplicação sym = :simbolo sym.object_id        # => 332668 sym2 = :simbolo sym2.object_id       # => 332668   str = "uma string" str.object_id        # => 2149466880 str2 = "uma string" str2.object_id       # => 2149437560
  • 16.
    Core classes: Array • Armazenam qualquer tipo de objeto • Índices inteiros array1 = [1, 2, 3, 2] array2 = Array.new     # => [] array3 = Array.new(5) # => [nil, nil, nil, nil, nil]
  • 17.
    Core classes: Array array = [1, 2, 3, 2] array << 4 # => [1, 2, 3, 2, 4] array.pop # => 4 array.shift # => 1 array.uniq # => [2,3]
  • 18.
    Core classes: Array notas = [8, 4, 5.9, 9, 4, 10] notas.select {|nota| nota >= 6 } #  => [8, 9, 10] notas.sort # => [4, 4, 5.9, 8, 9, 10] OBS: Blocos podem ser entre {} ou do / end
  • 19.
    Core classes: Hash • Similar ao Array • Armazenam qualquer tipo de objeto • Índices podem ser qualquer tipo de objeto hash = Hash.new hash2 = {1 => 'um', 2 => 'dois'}
  • 20.
    Core classes: Hash hash = {:um => 1, :dois => 2} hash['um'] # => nil hash[:um] # => 1 hash[:tres] = 3 hash.keys # => [:um, :dois, :tres] hash.values # => [1, 2, 3]
  • 21.
    Notação literal • Array array = [1, 2, 3] • Símbolos symbol = :simbolo • Hash hash = {:first => “value”, :second => “Value”} • Expressões Regulares regexp = /[0-9]{8}/
  • 22.
    Tudo é objeto 3.class                  # => Fixnum 3.14.class                # => Float :simbolo.class            # => Symbol [1,2,3].class             # => Array /expressao/i.class       # => Regexp {:key => 'value'}.class # => Hash Array.class               # => Class
  • 23.
    Fluxo: Condicionais • if •unless if condição bloco de código end unless condição bloco de código variavel = 5 if condição end variavel = 5 unless condição
  • 24.
    Fluxo: Case /When nota = 6 case nota when 10 then puts "Excelente!" when 8..9 then puts "Muito bom" when 6..7 then puts "Regular" else puts "Noob!" end
  • 25.
    Fluxo: Loops •begin...end while • enquanto (...) faça (...) begin   alguma_coisa end while (condicao == true)
  • 26.
    Fluxo: Loops •begin...end until • faça (...) até (...) begin   alguma_coisa end until (condicao == true)
  • 27.
  • 28.
    Fluxo: Loops • Hash#each_pair {:first => 1, :second => 2}.each_pair do |key, value| puts "#{key} => #{value}" end
  • 29.
    Fluxo: Loops • Integer#times • Integer#upto • Integer#downto 5.times do |i| 0.upto(10) do |i| puts i puts i end end
  • 30.
    Fluxo: Loops • String#each_line • String#each_char • String#each_byte "Hello world".each_line do |line| puts line end
  • 31.
    Convenções e nomenclaturas • Classes e módulos: CamelCase • Métodos e variáveis locais: com_underlines • Variáveis de instância: @com_arroba • Variáveis de classe: @@duplo_arroba • Constantes: UPPER_CASE • Variáveis globais: $COM_DOLAR
  • 32.
    Convenções e nomenclaturas • Métodos modificadores: finalizam em “!” • Ex: ”string”.upcase! # => ”STRING” [1,2,2,3,2].uniq! # => [1,2,3] • Métodos que retornam Boolean: finalizam em “?” • Ex: [1,2,3].include? 5 # => false 5.is_a? String # => false
  • 33.
    Funções • A últimaexpressão é o retorno da função def soma(n1, n2)     return n1 + n2 end def soma(n1, n2)     n1 + n2 end soma(7, 2) # => 9 soma("Oi", "Tchau") # => "OiTchau"
  • 34.
    Funções • A últimaexpressão é o retorno da função def soma(n1, n2)     return n1 + n2 end def soma(n1, n2)     n1 + n2 end soma 7, 2 # => 9 soma "Oi", "Tchau" # => "OiTchau" Parênteses são opcionais
  • 35.
    Funções • Argumentos default defcumprimentar(nome = "anônimo")     "Olá, #{nome}!" end   cumprimentar            # => "Olá, anônimo!" cumprimentar("pessoal") # => "Olá, pessoal!"
  • 36.
    Funções • Method missing defmethod_missing(name, *args)     "Método '#{name}' não foi definido. Argumentos: # {args.inspect}" end   alguma_coisa(1) # => "Método 'alguma_coisa' não foi definido. Argumentos: [1]"
  • 37.
    Arrays e hashes implícitos array = 1, 2, 3 # => [1, 2, 3] hash = :um => 1, :dois => 2 # => {:um => 1, :dois => 2}
  • 38.
    circle.rb Classes class Circle # constant PI = 3.141592653589793 # getter and setter attr_accessor :id # getters attr_reader :diameter, main.rb :radius require './circle.rb' def initialize(id, radius = nil) circle = Circle.new('My beautiful circle', 7) @id = id circle.area radius = radius unless radius.nil? => 153.93804002589985 end circle.circunference def radius= radius => 43.982297150257104 @radius = radius circle.diameter @diameter = radius * 2 => 14 end Circle::PI => 3.141592653589793 def area PI * (@radius ** 2) end def circunference PI * @diameter end end
  • 39.
  • 40.
    Rails • Padrão MVC(Model-View-Controller) • Convenção sobre configuração (CoC) • Não repita a si mesmo (DRY) • Objeto-relacional (ORM)
  • 41.
  • 42.
    Setup • $ geminstall rails • $ rails new nome_do_projeto
  • 43.
    Estrutura padrão Arquivo/Diretório Finalidade Especifica as dependências de “gems” para a Gemfile aplicação. app/ Controllers, models e views da aplicação. public/ Arquivos públicos. Javascript, CSS, Imagens, etc. Configurações da aplicação: rotas, banco de config/ dados, etc. lib/ Módulos para extensão da aplicação. db/ Migrações do banco de dados. vendor/ Códigos de terceiros. “Gems” estáticas. log/ Arquivos de log da aplicação.
  • 44.
  • 45.
  • 46.
    Models • Objetos querepresentam uma entidade no banco de dados $ rails generate model personagem nome:string level:integer exp:integer hp:integer
  • 47.
    Models • Objetosque representam uma entidade no banco de dados $ rails generate model personagem nome:string level:integer exp:integer Convenção: Singular hp:integer
  • 48.
    Models • Objetos querepresentam uma entidade no banco de dados $ rails generate model personagem nome:string level:integer exp:integer hp:integer campo : tipo
  • 49.
    Models $ rails generatemodel {identificador} {atributo}:[ integer, boolean, string, text, float, decimal, datetime, timestamp, time, date, binary]
  • 50.
    Models • Extendem ActiveRecord::Base class Personagem < ActiveRecord::Base end
  • 51.
    Models • Extendem ActiveRecord::Base •Devem gerenciar o comportamento do objeto class Personagem < ActiveRecord::Base   def level_up!     level += 1     save   end end
  • 52.
    Models • Criando registros Personagem.create(:nome=> "Joselito", :level => 1, :exp => 0, :hp => 100)
  • 53.
    Models • Encontrando registros Personagem.where(:level=> 10).first Personagem.where(:level => 10).all
  • 54.
  • 55.
    Controllers • Recebem aentrada do usuário • Fazem chamadas aos models • Renderizam uma view $ rails generate controller personagens
  • 56.
    Controllers •Recebem a entrada do usuário • Fazem chamadas aos models • Renderizam uma view class PersonagensController < ApplicationController end
  • 57.
    Controllers •Recebem a entrada do usuário • Fazem chamadas aos models • Renderizam uma view • Cada método corresponde à uma URL class PersonagensController < ApplicationController     def criar     end end http://localhost:3000/personagens/criar
  • 58.
  • 59.
    Views • HTML /ERB • Interface de usuário
  • 60.
  • 61.
    Material para estudos • http://guides.rubyonrails.org/ • http://railscasts.com/