Well, finally, here it is, the next installment with the beginning of Classes.
require 'rubygems'
require 'sdl'
# Load the libraries we need.
# We make a new type of object, or a class, that will be used to
# group all information about the player together
class Player
attr_accessor :x # the player has an x position
attr_accessor :y # the player has a y position
attr_accessor :w # the player has a width
attr_accessor :h # the player has a height
attr_accessor :vx # the player has a horizontal speed
attr_accessor :vy # the player has a vertical speed
attr_accessor :color # the player has a color
end
# We make a new type of object, or a class, that will be used to
# group all information about the game together
class Game
attr_accessor :screen # the game has a screen
attr_accessor :done # The game is done or not done.
attr_accessor :color # the game has a background color
end
# We make a new type of object, or a class, that will be used to
# group all information about the grass together
class Grass
attr_accessor :x # the grass has an x position
attr_accessor :y # the grass has a y position
attr_accessor :w # the grass has a width
attr_accessor :h # the grass has a height
attr_accessor :color # the grass has a color
end
# Define a function to handle the input
def handle_input(input, player, game)
intype= input.class
# Intype now contains what class, that is what kind of input we got
if intype == SDL::Event::Quit
# Clicked the close window icon.
game.done = true
# Now, it's over.
elsif intype == SDL::Event::KeyDown
# Someone pressed a key.
key = input.sym
# We get 'te "sum", that is the key sumbol for this input
if key == SDL::Key::ESCAPE
# If someone presses the escape key, we're also done.
game.done = true
elsif key == SDL::Key::LEFT
player.vx = -1
# Pressing left arrow key, so the player should move to the left
# For that, we make the speed of the player negative
elsif key == SDL::Key::RIGHT
player.vx = 1
# Pressing right arrow key, so the player should move to the right
# For that, we make the speed of the player positive
end
elsif intype == SDL::Event::KeyUp
# A key was released
key = input.sym
# Get what key was released
if key == SDL::Key::LEFT
# If the left key was released, the player should stop moving.
player.vx = 0
elsif key == SDL::Key::RIGHT
# If the right key was released, the player should also stop moving.
player.vx = 0
end
end
# Here, we don't need a result.
end
# A function to calculate the new player position
def update_player(player)
player.x = player.x + player.vx
# Set the new position of the player based upon the
# speed of the player
end
# A procedure to draw the screen
def draw_screen(game, player, grass)
screen = game.screen
# Store the game screen temporarily in a variable for ease of use.
screen.fill_rect(0, 0, screen.w, screen.h, game.color)
# Draw the sky on the background.
screen.fill_rect(grass.x, grass.y, grass.w, grass.h, grass.color)
# Draw the grassy floor
screen.fill_rect(player.x, player.y, player.w, player.h, player.color)
# Draw the player as a square
screen.flip
# And display the screen.
end
game = Game.new
player = Player.new
grass = Grass.new
game.screen = SDL::Screen.open(640, 480, 0, 0)
# Open the screen, like usually, and store it in the game.
game.done = false
# The game is not done.
game.color = game.screen.map_rgb(0, 255, 255)
# Set the game's background color.
grass.h = 40
grass.w = game.screen.w
grass.x = 0
grass.y = game.screen.h - grass.h
grass.color = game.screen.map_rgb(0 ,255,0)
# Set the grass's attributes.
player.w = 40
player.h = 40
player.vx = 0
player.x = game.screen.w / 2
player.y = game.screen.h - player.h - grass.h
player.color = game.screen.map_rgb(255,255,0)
# Set up the player's attributes.
while not game.done
# Keep doing the next lines while done is not true
input = SDL::Event.poll
# We ask SDL to get the input event that is occuring
handle_input(input, player, game)
# Process the input in our own function
update_player(player)
# Update the player's position based upon the player's speed.
draw_screen(game, player, grass)
# Display the screen.
end
# End of the while "loop". Everything from while to this end
# will be reprated until the variable done becomes true
What is new about this? Well, remember that in the previous tutorial we had a lot of parameters that were passed from one function to another. To help with that, we make use of objects and classes to group all related data together. What's an object? Well, its a piece of data that contains different elements grouped together, and which you can access by name. What is a class? Well, you can understand a class as being like a cookie cutter, or a template, which you can use to determine what the layout of an object created from that class will be.
So, that's why we first describe the class Player as having certain attributes. Attributes of a class or object are properties of that object in which you can store data. Basically, in ruby, there are two kinds of attributes, namely accessors, and readers. With an accessor, you can look up the data inside an object, and also change it. In Ruby, you define an acessor using attr_accessor. With a reader, you can only look up the data and not change it. In Ruby, toy define a reader using attr_reader. So, by saying attr_accessor :color inside the Player class, we say that a player will have a color that can be changed at will.
Now, to create an object from a class, we simply use the new method of that class. Like that, a class is also acting a bit like a special kind of module. By saying player = Player.new, we create a new object that has all the attributes that we described in the class Player. Thats' why we can do things like player.vx = 0 , we are setting the x direction speed attribute of the player to zero. Like that, th player object contains all data about the player grouped together neatly. This is a big advantage over using loose variables, since in any big program, you'll have many different variables, and it becomes quite messy when you have to keep track of them individually. With classes and objects, you can group related variables together in a neat package, keeping things more structured and neat.