lib/ruby2d/window.rb in ruby2d-0.9.5 vs lib/ruby2d/window.rb in ruby2d-0.10.0
- old
+ new
@@ -4,24 +4,21 @@
module Ruby2D
class Window
# Event structures
- EventDescriptor = Struct.new(:type, :id)
- MouseEvent = Struct.new(:type, :button, :direction, :x, :y, :delta_x, :delta_y)
- KeyEvent = Struct.new(:type, :key)
+ EventDescriptor = Struct.new(:type, :id)
+ MouseEvent = Struct.new(:type, :button, :direction, :x, :y, :delta_x, :delta_y)
+ KeyEvent = Struct.new(:type, :key)
ControllerEvent = Struct.new(:which, :type, :axis, :value, :button)
ControllerAxisEvent = Struct.new(:which, :axis, :value)
ControllerButtonEvent = Struct.new(:which, :button)
def initialize(args = {})
- # This window instance, stored so it can be called by the class methods
- @@window = self
-
# Title of the window
- @title = args[:title] || "Ruby 2D"
+ @title = args[:title] || "Ruby 2D"
# Window background color
@background = Color.new([0.0, 0.0, 0.0, 1.0])
# Window icon
@@ -49,18 +46,43 @@
@fps = @fps_cap
# Vertical synchronization, set to prevent screen tearing (recommended)
@vsync = args[:vsync] || true
+ # Renderable objects currently in the window, like a linear scene graph
+ @objects = []
+
+ # Entities currently in the window
+ @entities = []
+
# Mouse X and Y position in the window
@mouse_x, @mouse_y = 0, 0
# Controller axis and button mappings file
@controller_mappings = File.expand_path('~') + "/.ruby2d/controllers.txt"
- # Renderable objects currently in the window, like a linear scene graph
- @objects = []
+ # Event stores for class pattern
+ @keys_down = []
+ @keys_held = []
+ @keys_up = []
+ @mouse_buttons_down = []
+ @mouse_buttons_up = []
+ @mouse_scroll_event = false
+ @mouse_scroll_direction = nil
+ @mouse_scroll_delta_x = 0
+ @mouse_scroll_delta_y = 0
+ @mouse_move_event = false
+ @mouse_move_delta_x = 0
+ @mouse_move_delta_y = 0
+ @controller_id = nil
+ @controller_axes_moved = []
+ @controller_axis_left_x = 0
+ @controller_axis_left_y = 0
+ @controller_axis_right_x = 0
+ @controller_axis_right_y = 0
+ @controller_buttons_down = []
+ @controller_buttons_up = []
# Unique ID for the input event being registered
@event_key = 0
# Registered input events
@@ -81,10 +103,18 @@
}
# The window update block
@update_proc = Proc.new {}
+ # The window render block
+ @render_proc = Proc.new {}
+
+ # Detect if window is being used through the DSL or as a class instance
+ unless method(:update).parameters.empty? || method(:render).parameters.empty?
+ @using_dsl = true
+ end
+
# Whether diagnostic messages should be printed
@diagnostics = false
# Console mode, enabled at command line
if RUBY_ENGINE == 'ruby'
@@ -116,47 +146,51 @@
def mouse_y; get(:mouse_y) end
def diagnostics; get(:diagnostics) end
def screenshot(opts = nil); get(:screenshot, opts) end
def get(sym, opts = nil)
- @@window.get(sym, opts)
+ DSL.window.get(sym, opts)
end
def set(opts)
- @@window.set(opts)
+ DSL.window.set(opts)
end
def on(event, &proc)
- @@window.on(event, &proc)
+ DSL.window.on(event, &proc)
end
def off(event_descriptor)
- @@window.off(event_descriptor)
+ DSL.window.off(event_descriptor)
end
def add(o)
- @@window.add(o)
+ DSL.window.add(o)
end
def remove(o)
- @@window.remove(o)
+ DSL.window.remove(o)
end
def clear
- @@window.clear
+ DSL.window.clear
end
def update(&proc)
- @@window.update(&proc)
+ DSL.window.update(&proc)
end
+ def render(&proc)
+ DSL.window.render(&proc)
+ end
+
def show
- @@window.show
+ DSL.window.show
end
def close
- @@window.close
+ DSL.window.close
end
end
# Public instance methods
@@ -217,10 +251,12 @@
# Add an object to the window
def add(o)
case o
when nil
raise Error, "Cannot add '#{o.class}' to window!"
+ when Entity
+ @entities.push(o)
when Array
o.each { |x| add_object(x) }
else
add_object(o)
end
@@ -230,29 +266,37 @@
def remove(o)
if o == nil
raise Error, "Cannot remove '#{o.class}' from window!"
end
- if i = @objects.index(o)
- @objects.delete_at(i)
+ collection = o.class.ancestors.include?(Ruby2D::Entity) ? @entities : @objects
+ if i = collection.index(o)
+ collection.delete_at(i)
true
else
false
end
end
# Clear all objects from the window
def clear
@objects.clear
+ @entities.clear
end
- # Set an update callback
+ # Set the update callback
def update(&proc)
@update_proc = proc
true
end
+ # Set the render callback
+ def render(&proc)
+ @render_proc = proc
+ true
+ end
+
# Generate a new event key (ID)
def new_event_key
@event_key = @event_key.next
end
@@ -269,10 +313,25 @@
# Remove an event handler
def off(event_descriptor)
@events[event_descriptor.type].delete(event_descriptor.id)
end
+ # Key down event method for class pattern
+ def key_down(key)
+ @keys_down.include? key
+ end
+
+ # Key held event method for class pattern
+ def key_held(key)
+ @keys_held.include? key
+ end
+
+ # Key up event method for class pattern
+ def key_up(key)
+ @keys_up.include? key
+ end
+
# Key callback method, called by the native and web extentions
def key_callback(type, key)
key = key.downcase
# All key events
@@ -281,51 +340,128 @@
end
case type
# When key is pressed, fired once
when :down
+ # For class pattern
+ unless @using_dsl
+ unless @keys_down.include? key
+ @keys_down << key
+ end
+ end
+
+ # Call event handler
@events[:key_down].each do |id, e|
e.call(KeyEvent.new(type, key))
end
# When key is being held down, fired every frame
when :held
+ # For class pattern
+ unless @using_dsl
+ unless @keys_held.include? key
+ @keys_held << key
+ end
+ end
+
+ # Call event handler
@events[:key_held].each do |id, e|
e.call(KeyEvent.new(type, key))
end
# When key released, fired once
when :up
+ # For class pattern
+ unless @using_dsl
+ unless @keys_up.include? key
+ @keys_up << key
+ end
+ end
+
+ # Call event handler
@events[:key_up].each do |id, e|
e.call(KeyEvent.new(type, key))
end
end
end
+ # Mouse down event method for class pattern
+ def mouse_down(btn)
+ @mouse_buttons_down.include? btn
+ end
+
+ # Mouse up event method for class pattern
+ def mouse_up(btn)
+ @mouse_buttons_up.include? btn
+ end
+
+ # Mouse scroll event method for class pattern
+ def mouse_scroll
+ @mouse_scroll_event
+ end
+
+ # Mouse move event method for class pattern
+ def mouse_move
+ @mouse_move_event
+ end
+
# Mouse callback method, called by the native and web extentions
def mouse_callback(type, button, direction, x, y, delta_x, delta_y)
# All mouse events
@events[:mouse].each do |id, e|
e.call(MouseEvent.new(type, button, direction, x, y, delta_x, delta_y))
end
case type
# When mouse button pressed
when :down
+ # For class pattern
+ unless @using_dsl
+ unless @mouse_buttons_down.include? button
+ @mouse_buttons_down << button
+ end
+ end
+
+ # Call event handler
@events[:mouse_down].each do |id, e|
e.call(MouseEvent.new(type, button, nil, x, y, nil, nil))
end
# When mouse button released
when :up
+ # For class pattern
+ unless @using_dsl
+ unless @mouse_buttons_up.include? button
+ @mouse_buttons_up << button
+ end
+ end
+
+ # Call event handler
@events[:mouse_up].each do |id, e|
e.call(MouseEvent.new(type, button, nil, x, y, nil, nil))
end
# When mouse motion / movement
when :scroll
+ # For class pattern
+ unless @using_dsl
+ @mouse_scroll_event = true
+ @mouse_scroll_direction = direction
+ @mouse_scroll_delta_x = delta_x
+ @mouse_scroll_delta_y = delta_y
+ end
+
+ # Call event handler
@events[:mouse_scroll].each do |id, e|
e.call(MouseEvent.new(type, nil, direction, nil, nil, delta_x, delta_y))
end
# When mouse scrolling, wheel or trackpad
when :move
+ # For class pattern
+ unless @using_dsl
+ @mouse_move_event = true
+ @mouse_move_delta_x = delta_x
+ @mouse_move_delta_y = delta_y
+ end
+
+ # Call event handler
@events[:mouse_move].each do |id, e|
e.call(MouseEvent.new(type, nil, nil, x, y, delta_x, delta_y))
end
end
end
@@ -335,40 +471,104 @@
if File.exist? @controller_mappings
ext_add_controller_mappings(@controller_mappings)
end
end
+ # Controller axis event method for class pattern
+ def controller_axis(axis)
+ @controller_axes_moved.include? axis
+ end
+
+ # Controller button down event method for class pattern
+ def controller_button_down(btn)
+ @controller_buttons_down.include? btn
+ end
+
+ # Controller button up event method for class pattern
+ def controller_button_up(btn)
+ @controller_buttons_up.include? btn
+ end
+
# Controller callback method, called by the native and web extentions
def controller_callback(which, type, axis, value, button)
# All controller events
@events[:controller].each do |id, e|
e.call(ControllerEvent.new(which, type, axis, value, button))
end
case type
# When controller axis motion, like analog sticks
when :axis
+
+ # For class pattern
+ unless @using_dsl
+ @controller_id = which
+
+ unless @controller_axes_moved.include? axis
+ @controller_axes_moved << axis
+ end
+
+ case axis
+ when :left_x
+ @controller_axis_left_x = value
+ when :left_y
+ @controller_axis_left_y = value
+ when :right_x
+ @controller_axis_right_x = value
+ when :right_y
+ @controller_axis_right_y = value
+ end
+ end
+
+ # Call event handler
@events[:controller_axis].each do |id, e|
e.call(ControllerAxisEvent.new(which, axis, value))
end
# When controller button is pressed
when :button_down
+ # For class pattern
+ unless @using_dsl
+ @controller_id = which
+ unless @controller_buttons_down.include? button
+ @controller_buttons_down << button
+ end
+ end
+
+ # Call event handler
@events[:controller_button_down].each do |id, e|
e.call(ControllerButtonEvent.new(which, button))
end
# When controller button is released
when :button_up
+ # For class pattern
+ unless @using_dsl
+ @controller_id = which
+ unless @controller_buttons_up.include? button
+ @controller_buttons_up << button
+ end
+ end
+
+ # Call event handler
@events[:controller_button_up].each do |id, e|
e.call(ControllerButtonEvent.new(which, button))
end
end
end
# Update callback method, called by the native and web extentions
def update_callback
+ unless @using_dsl
+ update
+ end
+
@update_proc.call
+ # Run update method on all entities
+ @entities.each do |e|
+ e.update
+ end
+
# Accept and eval commands if in console mode
if @console
if STDIN.ready?
cmd = STDIN.gets
begin
@@ -383,9 +583,36 @@
STDOUT.flush
end
end
end
+ # Clear inputs if using class pattern
+ unless @using_dsl
+ @keys_down.clear
+ @keys_held.clear
+ @keys_up.clear
+ @mouse_buttons_down.clear
+ @mouse_buttons_up.clear
+ @mouse_scroll_event = false
+ @mouse_move_event = false
+ @controller_axes_moved.clear
+ @controller_buttons_down.clear
+ @controller_buttons_up.clear
+ end
+ end
+
+ # Render callback method, called by the native and web extentions
+ def render_callback
+ unless @using_dsl
+ render
+ end
+
+ @render_proc.call
+
+ # Run render method on all entities
+ @entities.each do |e|
+ e.render
+ end
end
# Show the window
def show
ext_show