Skip to content

Instantly share code, notes, and snippets.

@girasquid
Created August 19, 2012 17:11
Show Gist options
  • Save girasquid/3396335 to your computer and use it in GitHub Desktop.
Save girasquid/3396335 to your computer and use it in GitHub Desktop.
Rubygame Menu class
require 'rubygame'
class Menu
def initialize screen, font_file, background, menu=[]
@background = background
@default_color = [0, 0, 0]
@selected_color = [255, 255, 255]
@font_size = 24
@selected_index = 0
@x_offset = 25
@y_offset = 5
@mouse_position = nil
@screen = screen
Rubygame::TTF.setup
@font = TTF.new font_file, @font_size
@options = []
menu.each do |options|
self.add_option(options)
end
end
def update(ev)
case ev
when Rubygame::Events::MouseMoved
@mouse_position = ev.pos
# We check if the mouse is colliding with any menu options here, so that our drawing code
# just knows "given this index, show this one as selected."
@options.each_with_index do |attributes, index|
if attributes[:rect] && attributes[:rect].collide_point?(ev.pos[0], ev.pos[1])
@selected_index = index
end
end
# We track pressed AND released so that if you click, but change your mind you can drag
# your mouse off and cancel the selection.
when Rubygame::Events::MousePressed
@options.each_with_index do |attributes, index|
if attributes[:rect] && attributes[:rect].collide_point?(ev.pos[0], ev.pos[1])
@being_pressed = attributes
end
end
when Rubygame::Events::MouseReleased
if @being_pressed[:rect].collide_point?(ev.pos[0], ev.pos[1])
@being_pressed[:action][]
else
@being_pressed = nil
end
when Rubygame::Events::KeyPressed
case ev.key
when :up
if @selected_index > 0
@selected_index -= 1
else
# roll over
@selected_index = @options.length - 1
end
when :down
if @selected_index < (@options.length - 1)
@selected_index += 1
else
# roll over
@selected_index = 0
end
when :space, :return
@options[@selected_index][:action][]
end
end
end
def draw
@background.blit @screen, [0, 0]
@options.each_with_index do |menu_item_attributes, index|
# Index based select
color = index == @selected_index ? menu_item_attributes[:selected_color] : menu_item_attributes[:default_color]
menu_item = @font.render menu_item_attributes[:title], true, color
position = [menu_item_attributes[:x_offset] + @x_offset, menu_item_attributes[:y_offset] + @y_offset + menu_item.h * (index + 1)]
menu_item_attributes[:rect] = menu_item.blit(@screen, position)
end
end
protected
def add_option(options)
menu_item_attributes = {
:x_offset => 0,
:y_offset => 0,
:default_color => @default_color,
:selected_color => @selected_color,
}.merge!(options)
@options << menu_item_attributes
end
end
@font_path = File.expand_path(File.join(File.dirname(__FILE__), '../artwork/abelbecker.ttf'))
@menu = Menu.new(
@screen,
@font_path,
@background,
[
{:title => "New Game", :action => method(:new_game)},
{:title => "Continue", :action => method(:continue)},
{:title => "Exit", :action => method(:exit)},
])
@queue.each do |e| @main_menu.update(e) end
@main_menu.draw
@screen.flip
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment