rubydraw 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +20 -0
- data/examples/image_ex.rb +27 -0
- data/examples/media/bug.png +0 -0
- data/examples/window_ex.rb +25 -0
- data/lib/rubydraw.rb +32 -0
- data/lib/rubydraw/event_queue.rb +16 -0
- data/lib/rubydraw/events.rb +192 -0
- data/lib/rubydraw/image.rb +53 -0
- data/lib/rubydraw/keys.rb +95 -0
- data/lib/rubydraw/point.rb +22 -0
- data/lib/rubydraw/sdl_error.rb +6 -0
- data/lib/rubydraw/window.rb +120 -0
- metadata +98 -0
data/README
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Rubydraw is a high level game/graphics library, like Gosu or Rubygame, and is written in Ruby.
|
2
|
+
Its only dependency is ruby-sdl-ffi, which it uses to access SDL functions.
|
3
|
+
–––––
|
4
|
+
NOTE: I can't get +ruby-sdl-ffi+ (the library Rubydraw uses to access SDL) to work with +Ruby
|
5
|
+
1.9.2+, so I don't know if it even does. If it does work, and/or you know how to make it work,
|
6
|
+
I would appreciate it if you notify me. So basically, I can't test anything with +1.9.2+. Sorry
|
7
|
+
for the inconvenience!
|
8
|
+
|
9
|
+
HOW TO INSTALL
|
10
|
+
To install this library which isn't on Rubygems.org YET, navigate to this directory in the command
|
11
|
+
line tool and give "rubydraw/build_and_install" permissions to run. Then simply run it. Hooray, it
|
12
|
+
should be working now! Test it in irb with "require 'rubydraw'". Also: I will upload this gem to
|
13
|
+
rubygems when it is actually usable (if it ever is).
|
14
|
+
|
15
|
+
HOW TO USE
|
16
|
+
There isn't a proper guide yet, so just read the comments in the other files. Or you can fire up the
|
17
|
+
gem server and read the RDoc.
|
18
|
+
|
19
|
+
Thanks for checking this little project. I hope it doesn't give you headaches.
|
20
|
+
Have fun!
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubydraw'
|
3
|
+
|
4
|
+
class MyWindow < Rubydraw::Window
|
5
|
+
# Create a new window with an bug image inside it
|
6
|
+
def initialize(width, height)
|
7
|
+
super(width, height)
|
8
|
+
@image = Rubydraw::Image.new(self, "media/bug.png")
|
9
|
+
@max = 100
|
10
|
+
|
11
|
+
register_action(Rubydraw::Events::MouseMove) {|event| puts "Mouse moved! New position: #{event.position.x}, #{event.position.y}"}
|
12
|
+
register_action(Rubydraw::Events::QuitRequest) {close}
|
13
|
+
end
|
14
|
+
|
15
|
+
def mouse_moved(event)
|
16
|
+
new_position = event.position
|
17
|
+
puts "Mouse moved! New position: #{new_position.x}, #{new_position.y}"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Draw the image inside this window.
|
21
|
+
def tick
|
22
|
+
@image.draw(Rubydraw::Point[width / 2, height / 2])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
w = MyWindow.new(300, 300)
|
27
|
+
w.open
|
Binary file
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubydraw'
|
3
|
+
|
4
|
+
class MyWindow < Rubydraw::Window
|
5
|
+
def initialize(width, height)
|
6
|
+
super(width, height)
|
7
|
+
puts "New window created with width: #{@width} and height #{@height}"
|
8
|
+
end
|
9
|
+
def handle_event(event)
|
10
|
+
case event
|
11
|
+
when Rubydraw::Event::Quit
|
12
|
+
close
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
print "Window height: "
|
18
|
+
w = gets.to_i
|
19
|
+
print "Window width: "
|
20
|
+
h = gets.to_i
|
21
|
+
|
22
|
+
window = MyWindow.new(w, h).open
|
23
|
+
|
24
|
+
# Wait for a while to let the user enjoy the window
|
25
|
+
sleep 10
|
data/lib/rubydraw.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# The only dependency
|
2
|
+
require 'ruby-sdl-ffi'
|
3
|
+
|
4
|
+
# Require all the rubydraw files
|
5
|
+
#files = ["window", "image", "sdl_error", "event_queue", "events", "point"]
|
6
|
+
files = %w[
|
7
|
+
window
|
8
|
+
image
|
9
|
+
sdl_error
|
10
|
+
keys
|
11
|
+
event_queue
|
12
|
+
events
|
13
|
+
point]
|
14
|
+
files.each {|f| require("rubydraw/" + f)}
|
15
|
+
|
16
|
+
# Rubydraw is a high level game/graphics library, like Gosu or Rubygame, and is written completely
|
17
|
+
# in Ruby. Its only dependency is ruby-sdl-ffi, which it uses to access SDL functions.
|
18
|
+
#
|
19
|
+
# NOTE: I can't get +ruby-sdl-ffi+ (the library Rubydraw uses to access SDL) to work with +Ruby
|
20
|
+
# 1.9.2,+ so I don't know if it even does. If it does work, and/or you know how to make it work,
|
21
|
+
# I would appreciate it if you notify me. So basically, I can't test anything with +1.9.2+. Sorry
|
22
|
+
# for the inconvenience!
|
23
|
+
module Rubydraw
|
24
|
+
# Initialize SDL.
|
25
|
+
def self.initialize_sdl
|
26
|
+
if SDL::Init(SDL::INIT_EVERYTHING) != 0
|
27
|
+
raise DrawError "Could not initialize SDL"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Rubydraw::initialize_sdl
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Rubydraw
|
2
|
+
# Rubydraw uses an EventQueue to collect SDL events, e.g. mouse movements
|
3
|
+
# keystrokes, and window actions. A new EventQueue is automatically created
|
4
|
+
# when a Rubydraw::Window is initialized. Every tick, the window asks its
|
5
|
+
# event queue (created in Rubydraw::Window#initialize) for the new events
|
6
|
+
class EventQueue
|
7
|
+
# Get all the new events
|
8
|
+
def get_events
|
9
|
+
events = []
|
10
|
+
until((event = SDL::PollEvent()).nil?)
|
11
|
+
events << Events.match(event)
|
12
|
+
end
|
13
|
+
events
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
class Object
|
2
|
+
# Returns false by default. Is overridden in Rubydraw::Events::Event#is_event?
|
3
|
+
def event?
|
4
|
+
false
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Class
|
9
|
+
# Returns all subclasses. Credit goes to http://stackoverflow.com/questions/436159/how-to-get-all-subclasses
|
10
|
+
def all_subclasses
|
11
|
+
result = []
|
12
|
+
ObjectSpace.each_object(Class) { |klass| result << klass if klass < self }
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Rubydraw
|
18
|
+
# A module containing Rubydraw events and their SDL event "bindings".
|
19
|
+
module Events
|
20
|
+
# Translate the given SDL event to its corresponding Rubydraw event, by asking
|
21
|
+
# each event class if it matches the SDL event. No case statements here.
|
22
|
+
def self.match(sdl_event)
|
23
|
+
sdl_event_type = sdl_event.type
|
24
|
+
event_classes = Event.all_subclasses.compact
|
25
|
+
rubydraw_event = UnknownEvent.new
|
26
|
+
event_classes.each { |event| rubydraw_event = event.from_sdl_event(sdl_event) if event.matches?(sdl_event_type) }
|
27
|
+
rubydraw_event
|
28
|
+
end
|
29
|
+
|
30
|
+
# The basic Event class. All events should inherit from this class, otherwise it
|
31
|
+
# won't be recognized as an event and therefore will *not* participate in event
|
32
|
+
# matching.
|
33
|
+
class Event
|
34
|
+
# Just creates a new instance of this class by default. Override this if the subclass
|
35
|
+
# requires parameters in +initialize,+ like Rubydraw::Events::MouseDown::from_sdl_event.
|
36
|
+
def self.from_sdl_event(sdl_event)
|
37
|
+
self.new
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns true if this is the overlaying class for the given SDL event. Override this
|
41
|
+
# for custom matching.
|
42
|
+
def self.matches?(sdl_event)
|
43
|
+
sdl_event == matching_sdl_event
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns true for all event objects. Also see Object#event?
|
47
|
+
def event?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the matching SDL event, override this in subclasses. Returns nil by
|
52
|
+
# default.
|
53
|
+
def self.matching_sdl_event
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# A special event class that is called when no Rubydraw event is matched to an
|
59
|
+
# SDL event.
|
60
|
+
class UnknownEvent < Event
|
61
|
+
end
|
62
|
+
|
63
|
+
# Provides methods used in both Rubydraw::Events::KeyPressed and
|
64
|
+
# Rubydraw::Events::KeyReleased. No instances of this class should be created,
|
65
|
+
# but instances of subclasses are fine.
|
66
|
+
class KeyboardEvent < Event
|
67
|
+
def self.from_sdl_event(sdl_event)
|
68
|
+
self.new(sdl_event.keysym.sym)
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader(:key)
|
72
|
+
|
73
|
+
def initialize(key)
|
74
|
+
unless key.is_a?(Numeric)
|
75
|
+
raise SDLError "Failed to create new event because key is not a number."
|
76
|
+
end
|
77
|
+
|
78
|
+
@key = key
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Created when any keyboard button is pressed, specifying the key.
|
83
|
+
#
|
84
|
+
# @key:: An integer specifying the key, which can be matched with a Rubydraw
|
85
|
+
# button constants.
|
86
|
+
class KeyPressed < KeyboardEvent
|
87
|
+
def self.matching_sdl_event
|
88
|
+
SDL::KEYDOWN
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Created when any keyboard button is released, specifying the key.
|
93
|
+
#
|
94
|
+
# @key:: An integer specifying the key, which can be matched with a Rubydraw
|
95
|
+
# button constants.
|
96
|
+
class KeyReleased < KeyboardEvent
|
97
|
+
def self.matching_sdl_event
|
98
|
+
SDL::KEYUP
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Provides methods used in Rubydraw::Events::MousePressed and Rubydraw::Events::MouseReleased.
|
103
|
+
# No instances of this class should be created, but instances of subclasses are find.
|
104
|
+
class MouseButtonEvent
|
105
|
+
def from_sdl_event(sdl_event)
|
106
|
+
self.new(Point[sdl_event.x, sdl_event.y], sdl_events.button)
|
107
|
+
end
|
108
|
+
|
109
|
+
attr_reader(:position, :button)
|
110
|
+
|
111
|
+
def initialize(position, button)
|
112
|
+
@position, @button = position, button
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Created when a mouse button is down. Note: this event is used for *any* mouse
|
117
|
+
# button.
|
118
|
+
class MousePressed < Event
|
119
|
+
def self.from_sdl_event(sdl_event)
|
120
|
+
self.new(Point[sdl_event.x, sdl_event.y], sdl_event.button)
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.matching_sdl_event
|
124
|
+
SDL::MOUSEBUTTONDOWN
|
125
|
+
end
|
126
|
+
|
127
|
+
attr_reader(:position, :button)
|
128
|
+
|
129
|
+
# Creates a new MousePressed event, specifying where (the position) it happened
|
130
|
+
# and what button was pressed.
|
131
|
+
def initialize(position, button)
|
132
|
+
@position, @button = position, button
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Created when a mouse button is released. Note: this event is used for *any* mouse
|
137
|
+
# button.
|
138
|
+
class MouseReleased < Event
|
139
|
+
def self.from_sdl_event(sdl_event)
|
140
|
+
self.new(Point[sdl_event.x, sdl_event.y], sdl_event.button)
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.matching_sdl_event
|
144
|
+
SDL::MOUSEBUTTONUP
|
145
|
+
end
|
146
|
+
|
147
|
+
attr_reader(:position, :button)
|
148
|
+
|
149
|
+
# Creates a new MouseReleased event, specifying where (the position) it happened and
|
150
|
+
# what button was released.
|
151
|
+
def initialize(position, button)
|
152
|
+
@position, @button = position, button
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Created when the mouse is moved.
|
157
|
+
class MouseMove < Event
|
158
|
+
def self.from_sdl_event(sdl_event)
|
159
|
+
self.new(Point[sdl_event.x, sdl_event.y], Point[sdl_event.xrel, sdl_event.yrel])
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.matching_sdl_event
|
163
|
+
SDL::MOUSEMOTION
|
164
|
+
end
|
165
|
+
|
166
|
+
attr_reader(:position, :relative_position)
|
167
|
+
|
168
|
+
# Create a new MouseMove event with the new mouse position.
|
169
|
+
#
|
170
|
+
# +x+ and +y+: The new position of the cursor.
|
171
|
+
#
|
172
|
+
# +relative_x+ and +relative_y+: The relative movement of the cursor since the last tick.
|
173
|
+
def initialize(position, relative_position)
|
174
|
+
@position, @relative_position = position, relative_position
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Created either when the window gains or loses focus.
|
179
|
+
class WindowFocus
|
180
|
+
def from_sdl_event(sdl_event)
|
181
|
+
self.new(sdl_event.gain)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Created when the user attempts to close the window.
|
186
|
+
class QuitRequest < Event
|
187
|
+
def self.matching_sdl_event
|
188
|
+
SDL::QUIT
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Rubydraw
|
2
|
+
# Image instances can be initialized with Image#new, passing the
|
3
|
+
# window to draw in, and the path to the image file to draw with.
|
4
|
+
# Then to actually draw the image (doesn't happen immediatley;
|
5
|
+
# read the documentation for Image#draw), call it's #draw method
|
6
|
+
# and pass it the +x+ and +y+ coordinates.
|
7
|
+
class Image
|
8
|
+
# Create a new image in the given window and load the image from
|
9
|
+
# +path.+
|
10
|
+
def initialize(window, path)
|
11
|
+
@window = window
|
12
|
+
unless window.is_a?(Rubydraw::Window)
|
13
|
+
raise Rubydraw::SDLError "Window cannot be nil"
|
14
|
+
end
|
15
|
+
# In case program is being run from a different directory,
|
16
|
+
# provide the _full_ path. Nothing relative here.
|
17
|
+
full_path = File.expand_path path
|
18
|
+
@sdl_image = SDL::Image.Load(full_path)
|
19
|
+
if @sdl_image.pointer.null?
|
20
|
+
# SDL couln't load the image; usually happens because it doesn't
|
21
|
+
# exist.
|
22
|
+
raise Rubydraw::SDLError "Failed to load image from: '#{full_path}'"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Blit (copy) into the window at +position+ (see point.rb).
|
27
|
+
# No graphical effects are applied.
|
28
|
+
#
|
29
|
+
# Notice that you don't blit surfaces to other surfaces when using
|
30
|
+
# Rubygame, but instead you draw things.
|
31
|
+
def draw(position)
|
32
|
+
source_rect = SDL::Rect.new([0, 0, width, height])
|
33
|
+
blit_rect = SDL::Rect.new([position.x, position.y, @window.width, @window.height])
|
34
|
+
SDL::BlitSurface(@sdl_image, source_rect, @window.sdl_surface, blit_rect)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the image width
|
38
|
+
def width
|
39
|
+
@sdl_image.w
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the image height
|
43
|
+
def height
|
44
|
+
@sdl_image.h
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the SDL image that was created in Image#initialize.
|
48
|
+
# Rubydraw::Window uses this to draw this Image instance.
|
49
|
+
def sdl_image
|
50
|
+
@sdl_image
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Rubydraw
|
2
|
+
# Keys defines constants which identify with a key integer.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# def handle_event(event)
|
7
|
+
# case event
|
8
|
+
# when Rubydraw::Events::KeyPressed
|
9
|
+
# case event.key
|
10
|
+
# when Rubydraw::Keys::UpArrow
|
11
|
+
# @y -= 5
|
12
|
+
# when Rubydraw::Keys::DownArrow
|
13
|
+
# @y += 5
|
14
|
+
# when Rubydraw::Keys::RightArrow
|
15
|
+
# @x += 1
|
16
|
+
# when Rubydraw::Keys::LeftArrow
|
17
|
+
# @x -= 1
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
module Keys
|
21
|
+
UpArrow = SDL::K_UP
|
22
|
+
DownArrow = SDL::K_DOWN
|
23
|
+
RightArrow = SDL::K_RIGHT
|
24
|
+
LeftArrow = SDL::K_LEFT
|
25
|
+
# Letters
|
26
|
+
A = SDL::K_a
|
27
|
+
B = SDL::K_b
|
28
|
+
C = SDL::K_c
|
29
|
+
D = SDL::K_d
|
30
|
+
E = SDL::K_e
|
31
|
+
F = SDL::K_f
|
32
|
+
G = SDL::K_g
|
33
|
+
H = SDL::K_h
|
34
|
+
I = SDL::K_i
|
35
|
+
J = SDL::K_j
|
36
|
+
K = SDL::K_k
|
37
|
+
L = SDL::K_l
|
38
|
+
M = SDL::K_m
|
39
|
+
N = SDL::K_n
|
40
|
+
O = SDL::K_o
|
41
|
+
P = SDL::K_p
|
42
|
+
Q = SDL::K_q
|
43
|
+
R = SDL::K_r
|
44
|
+
S = SDL::K_s
|
45
|
+
T = SDL::K_t
|
46
|
+
U = SDL::K_u
|
47
|
+
V = SDL::K_v
|
48
|
+
W = SDL::K_w
|
49
|
+
X = SDL::K_x
|
50
|
+
Y = SDL::K_y
|
51
|
+
Z = SDL::K_z
|
52
|
+
# Numbers
|
53
|
+
Num0 = SDL::K_0
|
54
|
+
Num1 = SDL::K_1
|
55
|
+
Num2 = SDL::K_2
|
56
|
+
Num3 = SDL::K_3
|
57
|
+
Num4 = SDL::K_4
|
58
|
+
Num5 = SDL::K_5
|
59
|
+
Num6 = SDL::K_6
|
60
|
+
Num7 = SDL::K_7
|
61
|
+
Num8 = SDL::K_8
|
62
|
+
Num9 = SDL::K_9
|
63
|
+
# Shift
|
64
|
+
LeftShift = SDL::K_LSHIFT
|
65
|
+
RightShift = SDL::K_RSHIFT
|
66
|
+
# Whitespaces
|
67
|
+
Space = SDL::K_SPACE
|
68
|
+
Tab = SDL::K_TAB
|
69
|
+
# Control
|
70
|
+
# Alt/option
|
71
|
+
LeftAlt = SDL::K_LALT
|
72
|
+
RightAlt = SDL::K_RALT
|
73
|
+
LeftOption = LeftAlt
|
74
|
+
RightOption = RightAlt
|
75
|
+
# Function buttons
|
76
|
+
F1 = SDL::K_F1
|
77
|
+
F2 = SDL::K_F2
|
78
|
+
F3 = SDL::K_F3
|
79
|
+
F4 = SDL::K_F4
|
80
|
+
F5 = SDL::K_F5
|
81
|
+
F6 = SDL::K_F6
|
82
|
+
F7 = SDL::K_F7
|
83
|
+
F8 = SDL::K_F8
|
84
|
+
F9 = SDL::K_F9
|
85
|
+
F10 = SDL::K_F10
|
86
|
+
F11 = SDL::K_F11
|
87
|
+
F12 = SDL::K_F12
|
88
|
+
# Other stuff
|
89
|
+
Escape = SDL::K_ESCAPE
|
90
|
+
CapsLock = SDL::K_CAPSLOCK
|
91
|
+
Backspace = SDL::K_BACKSPACE
|
92
|
+
Delete = SDL::K_DELETE
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Rubydraw
|
2
|
+
# Used for specifying x and y positions in one class, instead of by themselves or
|
3
|
+
# arrays. Might look like:
|
4
|
+
#
|
5
|
+
# @image.draw(Point[5, 6])
|
6
|
+
class Point
|
7
|
+
# Shorthand new method
|
8
|
+
def self.[](x, y)
|
9
|
+
self.new(x, y)
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor(:x, :y)
|
13
|
+
|
14
|
+
# Create a new point with the given +x+ and +y+ positions.
|
15
|
+
def initialize(x, y)
|
16
|
+
unless x.is_a?(Numeric) and y.is_a?(Numeric)
|
17
|
+
raise RuntimeError "New Point x and y must be a number."
|
18
|
+
end
|
19
|
+
@x, @y = x, y
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Rubydraw
|
2
|
+
# Instances of Rubydraw::Window can draw themselves on the screen after you open them.
|
3
|
+
# Note: there can only be one window on the screen at a time; it is a limit
|
4
|
+
# of SDL. One important things about instances of Rubydraw::Window: its main loop
|
5
|
+
# (which starts when Rubydraw::Window#open is called) is *not* forked! It will break
|
6
|
+
# when Rubydraw::Window#close is called (as soon as I get around to implementing this).
|
7
|
+
class Window
|
8
|
+
# Create a new window.
|
9
|
+
def initialize(width, height)
|
10
|
+
unless height.is_a?(Numeric) and width.is_a?(Numeric)
|
11
|
+
# Raise an error
|
12
|
+
raise SDLError "Window width and height have to be a number."
|
13
|
+
end
|
14
|
+
|
15
|
+
@width = width
|
16
|
+
@height = height
|
17
|
+
@open = false
|
18
|
+
|
19
|
+
@event_queue = EventQueue.new
|
20
|
+
|
21
|
+
@registered_actions = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
# Call this method to start updating and drawing.
|
25
|
+
def open
|
26
|
+
@open = true
|
27
|
+
# Behold, the main loop. Drumroll!
|
28
|
+
@screen = SDL::SetVideoMode(@width, @height, 0, 0)
|
29
|
+
loop do
|
30
|
+
handle_events
|
31
|
+
if @open
|
32
|
+
tick
|
33
|
+
# Update the screen to show any changes.
|
34
|
+
SDL::UpdateRect(@screen, 0, 0, 0, 0)
|
35
|
+
else
|
36
|
+
# This is where the loop is broken after Rubydraw::Window#close is called.
|
37
|
+
break
|
38
|
+
end
|
39
|
+
# Pause for a bit, so it's not such a tight loop.
|
40
|
+
sleep 0.1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Call this method to tell SDL to quit drawing. The loop (started in
|
45
|
+
# Rubydraw::Window#open) would continue if +close+ only stopped drawing, so
|
46
|
+
# break the loop too.
|
47
|
+
def close
|
48
|
+
break_main_loop
|
49
|
+
SDL.QuitSubSystem(SDL::INIT_VIDEO)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Collect and handle new events by executing blocks in +@regestered_events+. See
|
53
|
+
# Rubydraw::Window#register_action on how to use it.
|
54
|
+
def handle_events
|
55
|
+
events = @event_queue.get_events
|
56
|
+
|
57
|
+
events.each {|event|
|
58
|
+
block = @registered_actions[event.class]
|
59
|
+
block.call(event) unless block.nil?}
|
60
|
+
end
|
61
|
+
|
62
|
+
# Redefine this in a subclass to use custom event handling. Does nothing by
|
63
|
+
# default.
|
64
|
+
def handle_event(event)
|
65
|
+
end
|
66
|
+
|
67
|
+
# This causes the main loop to exit. Use Rubydraw::Window#close to close the
|
68
|
+
# window, not this.
|
69
|
+
def break_main_loop
|
70
|
+
@open = false
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns if this window is open.
|
74
|
+
def open?
|
75
|
+
@open
|
76
|
+
end
|
77
|
+
|
78
|
+
# Return the SDL surface object. Only used in Rubydraw::Image#draw for blitting to
|
79
|
+
# this window.
|
80
|
+
def sdl_surface
|
81
|
+
@screen
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# Redefine Rubydraw::Window#tick with any code you want to be executed
|
86
|
+
# every frame, like drawing functions.
|
87
|
+
#
|
88
|
+
# Does nothing by default.
|
89
|
+
def tick
|
90
|
+
end
|
91
|
+
|
92
|
+
# Return the width of this window.
|
93
|
+
def width
|
94
|
+
@width
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return the height of this window.
|
98
|
+
def height
|
99
|
+
@height
|
100
|
+
end
|
101
|
+
|
102
|
+
# Send +selector+ to +reciever+ when +event+ happens, and include the specific event
|
103
|
+
# instace as a parameter if send_params = true.
|
104
|
+
|
105
|
+
# Execute the given block on the appearance of an instance of +event+.
|
106
|
+
#
|
107
|
+
# Example:
|
108
|
+
# class MyWindow < Rubydraw::Window
|
109
|
+
# def initialize
|
110
|
+
# super(300, 300)
|
111
|
+
#
|
112
|
+
# register_action(Rubydraw::Events::MouseMove) {|event| new_pos = event.position; puts "Mouse moved to #{new_pos.x}, #{new_pos.y}"}
|
113
|
+
# register_action(Rubydraw::Events::QuitRequest) {puts "Goodbye!"; close}
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
def register_action(event, &block)
|
117
|
+
@registered_actions[event] = block
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubydraw
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- J. Wostenberg
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-11-12 00:00:00 -07:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: ruby-sdl-ffi
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 4
|
33
|
+
version: "0.4"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: |-
|
37
|
+
|
38
|
+
Rubydraw is a high level drawing/game library,
|
39
|
+
like Gosu or Rubygame. Its only dependency is
|
40
|
+
ruby-sdl-ffi, which it uses to access SDL
|
41
|
+
functions.
|
42
|
+
email:
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
extra_rdoc_files: []
|
48
|
+
|
49
|
+
files:
|
50
|
+
- README
|
51
|
+
- lib/rubydraw.rb
|
52
|
+
- lib/rubydraw/window.rb
|
53
|
+
- lib/rubydraw/image.rb
|
54
|
+
- lib/rubydraw/sdl_error.rb
|
55
|
+
- lib/rubydraw/keys.rb
|
56
|
+
- lib/rubydraw/event_queue.rb
|
57
|
+
- lib/rubydraw/events.rb
|
58
|
+
- lib/rubydraw/point.rb
|
59
|
+
- examples/window_ex.rb
|
60
|
+
- examples/image_ex.rb
|
61
|
+
- examples/media/bug.png
|
62
|
+
has_rdoc: true
|
63
|
+
homepage: https://github.com/awostenberg/rubydraw
|
64
|
+
licenses: []
|
65
|
+
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
requirements: []
|
91
|
+
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.5.2
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Rubydraw is a high level drawing/graphics library, like Gosu or Rubygame
|
97
|
+
test_files: []
|
98
|
+
|