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
• Expressiva puts "Hello world!"
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 classesInteger, String, Symbol, Array, Hash, etc.
Core classes: Integer
numero = 5numero.is_a? Integer# => truenumero += 1.2# => 6.2numero.is_a? Integer# => falsenumero.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 = :simbolosym.object_id # => 332668sym2 = :simbolosym2.object_id # => 332668 str = "uma string"str.object_id # => 2149466880str2 = "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 # => 4array.shift # => 1array.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] = 3hash.keys# => [:um, :dois, :tres]
hash.values# => [1, 2, 3]
Notação literal
• Arrayarray = [1, 2, 3]
• Símbolossymbol = :simbolo
• Hashhash = {:first => “value”, :second => “Value”}
• Expressões Regularesregexp = /[0-9]{8}/
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
Tudo é objeto
Fluxo: Condicionais
• if
• unless
if condição bloco de códigoend
variavel = 5 if condição
unless condição bloco de códigoend
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
• begin...end while
• enquanto (...) faça (...)
Fluxo: Loops
begin alguma_coisaend while (condicao == true)
• begin...end until
• faça (...) até (...)
Fluxo: Loops
begin alguma_coisaend until (condicao == true)
• Array#each
Fluxo: Loops
[1,2,3,4].each do |item| puts item end
• Hash#each_pair
Fluxo: Loops
{:first => 1, :second => 2}.each_pair do |key, value| puts "#{key} => #{value}" end
• Integer#times
• Integer#upto
• Integer#downto
Fluxo: Loops
5.times do |i| puts iend
0.upto(10) do |i| puts iend
• String#each_line
• String#each_char
• String#each_byte
Fluxo: Loops
"Hello world".each_line do |line| puts lineend
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 # => false5.is_a? String # => false
Funções• A última expressão é o retorno da função
def soma(n1, n2) return n1 + n2end
def soma(n1, n2) n1 + n2end
soma(7, 2) # => 9soma("Oi", "Tchau") # => "OiTchau"
Funções• A última expressão é o retorno da função
def soma(n1, n2) return n1 + n2end
def soma(n1, n2) n1 + n2end
soma 7, 2 # => 9soma "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}
Classesclass Circle # constant PI = 3.141592653589793 # getter and setter attr_accessor :id # getters attr_reader :diameter, :radius def initialize(id, radius = nil) @id = id radius = radius unless radius.nil? end def radius= radius @radius = radius @diameter = radius * 2 end def area PI * (@radius ** 2) end def circunference PI * @diameter end end
require './circle.rb' circle = Circle.new('My beautiful circle', 7)circle.area=> 153.93804002589985circle.circunference=> 43.982297150257104circle.diameter=> 14Circle::PI=> 3.141592653589793
circle.rb
main.rb
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ãoArquivo/Diretório Finalidade
Gemfile Especifica as dependências de “gems” para a aplicação.
app/ Controllers, models e views da aplicação.
public/ Arquivos públicos. Javascript, CSS, Imagens, etc.
config/ Configurações da aplicação: rotas, banco de 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 \ hp:integerConvenção: Singular
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
integer,boolean,string,text,float,decimal,datetime,timestamp,time,date,binary]
$ rails generate model {identificador} \ {atributo}:[
Models• Extendem ActiveRecord::Base
class Personagem < ActiveRecord::Baseend
Models• Extendem ActiveRecord::Base
• Devem gerenciar o comportamento do objeto
class Personagem < ActiveRecord::Base def level_up! level += 1 save endend
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 < ApplicationControllerend
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 endend
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/
Top Related