Continue with Game development with Ruby
In this post we will continue with game development with Ruby. This time we will focus on UI design with Gosu, a library for game development. Let's go step by step and implement our sokoban game. Game.rb We create a file game.rb with the following content: require 'gosu' # add gosu ...
In this post we will continue with game development with Ruby. This time we will focus on UI design with Gosu, a library for game development. Let's go step by step and implement our sokoban game.
Game.rb
We create a file game.rb with the following content:
require 'gosu' # add gosu gem class GameWindow < Gosu::Window def initialize super 500, 500 self.caption = "Sokoban with Gosu" end end window = GameWindow.new window.show
we initialize a window for game with awidth and height of 500 pixels. The window has title Sokoban with Gosu. Then we create an instance of the window and display it. we get a black screen like this.
We need some ways to record the map of the game and then we translate it to build the UI of the game. Now let's create a file called levels.rb.
Levels.rb
module Levels L1 = [ {x: 0, y: 0, type: :wall}, {x: 50, y: 0, type: :wall}, {x: 100, y: 0, type: :wall}, {x: 150, y: 0, type: :wall}, {x: 200, y: 0, type: :wall}, {x: 0, y: 50, type: :wall}, {x: 200, y: 50, type: :wall}, {x: 250, y: 50, type: :wall}, {x: 300, y: 50, type: :wall}, {x: 0, y: 100, type: :wall}, {x: 300, y: 100, type: :wall}, {x: 350, y: 100, type: :wall}, {x: 400, y: 100, type: :wall}, {x: 450, y: 100, type: :wall}, {x: 0, y: 150, type: :wall}, {x: 50, y: 150, type: :wall}, {x: 150, y: 150, type: :wall}, {x: 200, y: 150, type: :wall}, {x: 450, y: 150, type: :wall}, {x: 0, y: 200, type: :wall}, {x: 450, y: 200, type: :wall}, {x: 0, y: 250, type: :wall}, {x: 450, y: 250, type: :wall}, {x: 0, y: 300, type: :wall}, {x: 50, y: 300, type: :wall}, {x: 100, y: 300, type: :wall}, {x: 250, y: 300, type: :wall}, {x: 300, y: 300, type: :wall}, {x: 350, y: 300, type: :wall}, {x: 400, y: 300, type: :wall}, {x: 450, y: 300, type: :wall}, {x: 100, y: 350, type: :wall}, {x: 250, y: 350, type: :wall}, {x: 100, y: 400, type: :wall}, {x: 150, y: 400, type: :wall}, {x: 200, y: 400, type: :wall}, {x: 250, y: 400, type: :wall}, {x: 100, y: 200, type: :dest}, {x: 150, y: 200, type: :dest}, {x: 200, y: 200, type: :dest}, {x: 250, y: 200, type: :dest}, {x: 150, y: 250, type: :dest}, {x: 150, y: 300, type: :dest}, {x: 100, y: 150, type: :box}, {x: 250, y: 150, type: :box}, {x: 300, y: 150, type: :box}, {x: 200, y: 250, type: :box}, {x: 250, y: 250, type: :box}, {x: 350, y: 250, type: :box}, {x: 100, y: 100, type: :player} ] Stage = [L1] end
Plan.rb
Here we create a level which is an array of hashes, each of which has x, y coordinate and types of object as :box, :wall, :player, :dest (destination). We will create another file called plan.rb to translate each level to reality. But before translation can be realized we need some images. We create an image folder with image of size 50x50 with the name: background.jpg, box.png, player.png, wall.png and destination.png. Now let's create plan.rb to do the translation and draw to the screen.
class Plan attr_accessor :moves #number of moves def initialize @level = @score = @moves = 0 #initialize level, score and moves to 0 #instantiate object for player, background, wall, destination and box @player = Gosu::Image.new("img/player.png") @bg = Gosu::Image.new("img/bg.jpg", :tileable => true) @wall = Gosu::Image.new("img/wall.jpg") @dest = Gosu::Image.new("img/destination.png") @box = Gosu::Image.new("img/box.png") @info = Gosu::Font.new(20) #intantiate object for writing end #load levels in file `levels.rb` into @map object using Marshal load and dump #increment level if we have to go to next level else do nothing, and reset moves number def load_level(next_level = false) @level += 1 if next_level @map = Marshal.load( Marshal.dump(Levels::Stages[@level]) ) # deep copy @moves = 0 end #draw is Gosu method for drawing image and characters to screen #draw has parameters text, x coordinate, y coordinate, z value, x scale, y scale and color def draw @bg.draw(0, 0, 0) @info.draw("Level: #{@level} | Score: #{@score} | Moves: #{@moves}", 10, 480, 1, 1.0, 1.0, 0xff_ff0000) @info.draw("Esc- exit | Space - reset", 280, 480, 1, 1.0, 1.0, 0xff_808080) #The actual translation happens here @map.each do |cell| case cell[:type] when :wall @wall.draw(cell[:x], cell[:y], 0) when :dest @dest.draw(cell[:x], cell[:y], 1) when :box @box.draw(cell[:x], cell[:y], 0) when :player @player.draw(cell[:x], cell[:y], 2) end end end end
We need to require some files in game.rb
require_relative 'levels' require_relative 'plan'
Let run the game again: ruby game.rb we get something like this:
This is quite a lot now. I think we can add some movement in the next post. Hope you enjoy.
Reference
http://dreamingechoes.github.io/game/gosu/ruby/become-a-videogame-developer-master-with-gosu-and-ruby/ https://www.libgosu.org/