Ruby Shoes Tetris
Fri, Nov 7, 2014I was inspired by a talk from @jasonrclark at this weeks @pdxruby that reminded us that the Shoes project is still alive and well. I had a little free time so I thought I’d make a tiny contribution and take a day to port over one of my simpler javascript games to Shoes.
Shoes is a cross-platform Ruby desktop GUI framework aimed at beginners wanting to get into programming. For those of us who have been in the Ruby community for a while we might have assumed that Shoes died when _why left the community. However, from the shoesrb.com history…
_“Way way back in the day, there was a guy named _why. He created a project known as Hackety Hack to teach programming to everyone. In order to reach all corners of the earth, _why decided to make Hackety Hack work on Windows, Mac OS X, and Linux. This was a lot of work, and so _why decided to share his toolkit with the world. Thus, Shoes was born. Everybody loved Shoes. Many apps were made, and put into The Shoebox, which no longer exists. But, one day, why left. In his memory, Team Shoes assembled, and carried on making Shoes. They released Shoes 3 in late summer 2010.”
… and they are actively working on Shoes4.
So here’s a version of Tetris you can run with Ruby Shoes:
Installing Shoes4
For the most up to date instructions on how to install Shoes4 you should refer to the official project README. You’ll need:
Running Tetris
Once you have JRuby installed, you can clone the tetris-shoes repository and use JRuby to run the Shoes script:
$ git clone https://github.com/jakesgordon/tetris-shoes
$ cd tetris-shoes
$ jruby tetris.rb
NOTE: on OSX, with the current prerelease version of Shoes4, you might need to add the -J-XstartOnFirstThread option, e.g “jruby -J-XstartOnFirstThread tetris.rb”
Porting to Shoes
Porting the game to Shoes involved turning the engine into Ruby and extracting out the GUI specific parts (rendering and event handling) to use Shoes instead of the browser’s Canvas/DOM.
The majority of the engine is pure Ruby, and beyond the scope of this article - you can checkout the source for more details.
The Shoes specific code starts with a Shoes app that contains our game engine:
Shoes.app :title => 'Tetris', :width => WIDTH, :height => HEIGHT do
game = Tetris.new
# ...
end
Then we hook up keyboard event handling:
keypress do |k|
case k
when :left then game.actions << :left
when :right then game.actions << :right
when :down then game.actions << :drop
when :up then game.actions << :rotate
when :escape then quit
end
end
… and use the Shoes #animate
method to create a game loop:
last = now = Time.now
animate = animate FPS do
now = Time.now
game.update(now - last)
# rendering goes here
end
… rendering for a tetris game is really simple, we need to use the Shoes #fill
and #rect
methods to create rectangles:
def block(x, y, color)
fill color
rect(x*DX, y*DY, DX, DY)
end
… and then use that method to render all of the occupied blocks, including the currently active piece:
game.each_occupied_block do |x, y, color|
block(x, y, color)
end
game.current.each_occupied_block do |x,y|
block(x, y, game.current.type[:color])
end
… and finally we need to check if the game has finished:
if game.lost?
banner "Game Over", :align => 'center', :stroke => black
animate.stop
else
subtitle "Score: #{format("%6.6d", game.vscore)}", :stroke => green, :align => 'right'
end
Next up
Shoes is a nice, easy to use platform for building simple desktop applications and that includes simple games as well. It was pretty easy to port an existing game to Ruby and make it fit into the Shoes framework.
I’ll make a pull request to add tetris-shoes as an example in the official shoes4 repository and next time I have some free time I’ll maybe port over some of my other games