minigl 1.3.10 → 2.0.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.
@@ -1,6 +1,6 @@
1
1
  require_relative 'movement'
2
2
 
3
- module AGL
3
+ module MiniGL
4
4
  # This class represents an (optionally animated) image inside the game screen.
5
5
  class Sprite
6
6
  # The index of the current sprite in the spritesheet being drawn.
@@ -32,7 +32,7 @@ module AGL
32
32
  # image is not a spritesheet.
33
33
  # [sprite_rows] The number of rows in the spritesheet. Use +nil+ if the
34
34
  # image is not a spritesheet.
35
- def initialize x, y, img, sprite_cols = nil, sprite_rows = nil
35
+ def initialize(x, y, img, sprite_cols = nil, sprite_rows = nil)
36
36
  @x = x; @y = y
37
37
  @img =
38
38
  if sprite_cols.nil?
@@ -56,7 +56,7 @@ module AGL
56
56
  # [interval] The amount of frames between each change in the image index.
57
57
  # A frame will usually represent 1/60 second (roughly 17
58
58
  # milliseconds).
59
- def animate indices, interval
59
+ def animate(indices, interval)
60
60
  @anim_counter += 1
61
61
  if @anim_counter >= interval
62
62
  @index_index += 1
@@ -85,7 +85,7 @@ module AGL
85
85
  # its center.
86
86
  # [z_index] The z-order to draw the object. Objects with larger z-orders
87
87
  # will be drawn on top of the ones with smaller z-orders.
88
- def draw map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, z_index = 0
88
+ def draw(map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, z_index = 0)
89
89
  color = (alpha << 24) | color
90
90
  if map
91
91
  if angle
@@ -99,6 +99,15 @@ module AGL
99
99
  @img[@img_index].draw @x.round, @y.round, z_index, scale_x, scale_y, color
100
100
  end
101
101
  end
102
+
103
+ # Returns whether this sprite is visible in the given map (i.e., in the
104
+ # viewport determined by the camera of the given map). If no map is given,
105
+ # returns whether the sprite is visible on the screen.
106
+ def visible?(map = nil)
107
+ r = Rectangle.new @x, @y, @img[0].width, @img[0].height
108
+ return Rectangle.new(0, 0, G.window.width, G.window.height).intersect? r if map.nil?
109
+ map.cam.intersect? r
110
+ end
102
111
  end
103
112
 
104
113
  # This class represents an object with a set of properties and methods
@@ -128,7 +137,7 @@ module AGL
128
137
  # image is not a spritesheet.
129
138
  # [mass] The mass of the object. Details on how it is used can be found
130
139
  # in the Movement module.
131
- def initialize x, y, w, h, img, img_gap = nil, sprite_cols = nil, sprite_rows = nil, mass = 1.0
140
+ def initialize(x, y, w, h, img, img_gap = nil, sprite_cols = nil, sprite_rows = nil, mass = 1.0)
132
141
  super x, y, img, sprite_cols, sprite_rows
133
142
  @w = w; @h = h
134
143
  @img_gap =
@@ -139,7 +148,6 @@ module AGL
139
148
  end
140
149
  @mass = mass
141
150
  @speed = Vector.new 0, 0
142
- @min_speed = Vector.new 0.01, 0.01
143
151
  @max_speed = Vector.new 15, 15
144
152
  @stored_forces = Vector.new 0, 0
145
153
  end
@@ -149,7 +157,7 @@ module AGL
149
157
  #
150
158
  # Parameters:
151
159
  # [index] The image index to be set.
152
- def set_animation index
160
+ def set_animation(index)
153
161
  @anim_counter = 0
154
162
  @img_index = index
155
163
  @index_index = 0
@@ -174,7 +182,7 @@ module AGL
174
182
  # its center.
175
183
  # [z_index] The z-order to draw the object. Objects with larger z-orders
176
184
  # will be drawn on top of the ones with smaller z-orders.
177
- def draw map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, z_index = 0
185
+ def draw(map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, z_index = 0)
178
186
  color = (alpha << 24) | color
179
187
  if map
180
188
  if angle
@@ -190,6 +198,15 @@ module AGL
190
198
  @img[@img_index].draw @x.round + @img_gap.x, @y.round + @img_gap.y, z_index, scale_x, scale_y, color
191
199
  end
192
200
  end
201
+
202
+ # Returns whether this object is visible in the given map (i.e., in the
203
+ # viewport determined by the camera of the given map). If no map is given,
204
+ # returns whether the object is visible on the screen.
205
+ def visible?(map = nil)
206
+ r = Rectangle.new @x.round + @img_gap.x, @y.round + @img_gap.y, @img[0].width, @img[0].height
207
+ return Rectangle.new(0, 0, G.window.width, G.window.height).intersect? r if map.nil?
208
+ map.cam.intersect? r
209
+ end
193
210
  end
194
211
 
195
212
  # Represents a visual effect, i.e., a graphic - usually animated - that shows
@@ -222,7 +239,14 @@ module AGL
222
239
  # of the Effect object. If +nil+, it will be set to
223
240
  # <code>@indices.length * interval</code>, i.e., the exact time
224
241
  # needed for one animation cycle to complete.
225
- def initialize x, y, img, sprite_cols = nil, sprite_rows = nil, interval = 10, indices = nil, lifetime = nil
242
+ # [sound] The id of a sound to be played when the effect is created (id must
243
+ # be given in the format specified for the +Res.sound+ method).
244
+ # [sound_ext] Extension of the sound file, if a sound is given. Default is
245
+ # '.wav'.
246
+ # [sound_volume] The volume (from 0 to 1) to play the sound, if any. Default
247
+ # is 1.
248
+ def initialize(x, y, img, sprite_cols = nil, sprite_rows = nil, interval = 10, indices = nil, lifetime = nil,
249
+ sound = nil, sound_ext = '.wav', sound_volume = 1)
226
250
  super x, y, img, sprite_cols, sprite_rows
227
251
  @timer = 0
228
252
  if indices
@@ -236,6 +260,7 @@ module AGL
236
260
  else
237
261
  @lifetime = @indices.length * interval
238
262
  end
263
+ Res.sound(sound, false, sound_ext).play(sound_volume) if sound
239
264
  end
240
265
 
241
266
  # Updates the effect, animating and counting its remaining lifetime.
@@ -247,7 +272,7 @@ module AGL
247
272
  end
248
273
  end
249
274
 
250
- def draw map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, z_index = 0
275
+ def draw(map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil, z_index = 0)
251
276
  super unless @dead
252
277
  end
253
278
  end
data/lib/minigl/global.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'gosu'
2
2
 
3
3
  # The main module of the library, used only as a namespace.
4
- module AGL
4
+ module MiniGL
5
5
  # This class represents a point or vector in a bidimensional space.
6
6
  class Vector
7
7
  # The x coordinate of the vector
@@ -15,7 +15,7 @@ module AGL
15
15
  # Parameters:
16
16
  # [x] The x coordinate of the vector
17
17
  # [y] The y coordinate of the vector
18
- def initialize x, y
18
+ def initialize(x = 0, y = 0)
19
19
  @x = x
20
20
  @y = y
21
21
  end
@@ -23,7 +23,7 @@ module AGL
23
23
  # Returns +true+ if both coordinates of this vector are equal to the
24
24
  # corresponding coordinates of +other_vector+, with +precision+ decimal
25
25
  # places of precision.
26
- def == other_vector, precision = 6
26
+ def ==(other_vector, precision = 6)
27
27
  @x.round(precision) == other_vector.x.round(precision) and
28
28
  @y.round(precision) == other_vector.y.round(precision)
29
29
  end
@@ -31,37 +31,37 @@ module AGL
31
31
  # Returns +true+ if at least one coordinate of this vector is different from
32
32
  # the corresponding coordinate of +other_vector+, with +precision+ decimal
33
33
  # places of precision.
34
- def != other_vector, precision = 6
34
+ def !=(other_vector, precision = 6)
35
35
  @x.round(precision) != other_vector.x.round(precision) or
36
36
  @y.round(precision) != other_vector.y.round(precision)
37
37
  end
38
38
 
39
39
  # Sums this vector with +other_vector+, i.e., sums each coordinate of this
40
40
  # vector with the corresponding coordinate of +other_vector+.
41
- def + other_vector
41
+ def +(other_vector)
42
42
  Vector.new @x + other_vector.x, @y + other_vector.y
43
43
  end
44
44
 
45
45
  # Subtracts +other_vector+ from this vector, i.e., subtracts from each
46
46
  # coordinate of this vector the corresponding coordinate of +other_vector+.
47
- def - other_vector
47
+ def -(other_vector)
48
48
  Vector.new @x - other_vector.x, @y - other_vector.y
49
49
  end
50
50
 
51
51
  # Multiplies this vector by a scalar, i.e., each coordinate is multiplied by
52
52
  # the given number.
53
- def * scalar
53
+ def *(scalar)
54
54
  Vector.new @x * scalar, @y * scalar
55
55
  end
56
56
 
57
57
  # Divides this vector by a scalar, i.e., each coordinate is divided by the
58
58
  # given number.
59
- def / scalar
59
+ def /(scalar)
60
60
  Vector.new @x / scalar.to_f, @y / scalar.to_f
61
61
  end
62
62
 
63
63
  # Returns the euclidean distance between this vector and +other_vector+.
64
- def distance other_vector
64
+ def distance(other_vector)
65
65
  dx = @x - other_vector.x
66
66
  dy = @y - other_vector.y
67
67
  Math.sqrt(dx ** 2 + dy ** 2)
@@ -69,14 +69,14 @@ module AGL
69
69
 
70
70
  # Returns a vector corresponding to the rotation of this vector around the
71
71
  # origin (0, 0) by +radians+ radians.
72
- def rotate radians
72
+ def rotate(radians)
73
73
  sin = Math.sin radians
74
74
  cos = Math.cos radians
75
75
  Vector.new cos * @x - sin * @y, sin * @x + cos * @y
76
76
  end
77
77
 
78
78
  # Rotates this vector by +radians+ radians around the origin (0, 0).
79
- def rotate! radians
79
+ def rotate!(radians)
80
80
  sin = Math.sin radians
81
81
  cos = Math.cos radians
82
82
  prev_x = @x
@@ -107,7 +107,7 @@ module AGL
107
107
  # [y] The y-coordinate of the rectangle.
108
108
  # [w] The width of the rectangle.
109
109
  # [h] The height of the rectangle.
110
- def initialize x, y, w, h
110
+ def initialize(x, y, w, h)
111
111
  @x = x; @y = y; @w = w; @h = h
112
112
  end
113
113
 
@@ -115,25 +115,69 @@ module AGL
115
115
  #
116
116
  # Parameters:
117
117
  # [r] The rectangle to check intersection with.
118
- def intersects r
118
+ def intersect?(r)
119
119
  @x < r.x + r.w && @x + @w > r.x && @y < r.y + r.h && @y + @h > r.y
120
120
  end
121
121
  end
122
122
 
123
+ # This module contains references to global objects/constants used by MiniGL.
124
+ module G
125
+ class << self
126
+ # A reference to the game window.
127
+ attr_accessor :window
128
+
129
+ # Gets or sets the value of gravity. See
130
+ # <code>GameWindow#initialize</code> for details.
131
+ attr_accessor :gravity
132
+
133
+ # Gets or sets the value of min_speed. See
134
+ # <code>GameWindow#initialize</code> for details.
135
+ attr_accessor :min_speed
136
+
137
+ # Gets or sets the value of ramp_contact_threshold. See
138
+ # <code>GameWindow#initialize</code> for details.
139
+ attr_accessor :ramp_contact_threshold
140
+
141
+ # Gets or sets the value of ramp_slip_threshold. See
142
+ # <code>GameWindow#initialize</code> for details.
143
+ attr_accessor :ramp_slip_threshold
144
+
145
+ # Gets or sets the value of kb_held_delay. See
146
+ # <code>GameWindow#initialize</code> for details.
147
+ attr_accessor :kb_held_delay
148
+
149
+ # Gets or sets the value of kb_held_interval. See
150
+ # <code>GameWindow#initialize</code> for details.
151
+ attr_accessor :kb_held_interval
152
+
153
+ # Gets or sets the value of double_click_delay. See
154
+ # <code>GameWindow#initialize</code> for details.
155
+ attr_accessor :double_click_delay
156
+ end
157
+ end
158
+
123
159
  # The main class for a MiniGL game, holds references to globally accessible
124
160
  # objects and constants.
125
- class Game
126
- # Initializes a MiniGL game. This method must be called before any feature
127
- # provided by the library can be used.
161
+ class GameWindow < Gosu::Window
162
+ # Creates a game window (initializing a game with all MiniGL features
163
+ # enabled).
128
164
  #
129
165
  # Parameters:
130
- # [window] An instance of a class which inherits from
131
- # <code>Gosu::Window</code>. This will be the game window, used
132
- # to draw everything and capture user input.
166
+ # [scr_w] Width of the window, in pixels.
167
+ # [scr_h] Height of the window, in pixels.
168
+ # [fullscreen] Whether the window must be initialized in full screen mode.
133
169
  # [gravity] A Vector object representing the horizontal and vertical
134
170
  # components of the force of gravity. Essentially, this force
135
171
  # will be applied to every object which calls +move+, from the
136
172
  # Movement module.
173
+ # [min_speed] A Vector with the minimum speed for moving objects, i.e., the
174
+ # value below which the speed will be rounded to zero.
175
+ # [ramp_contact_threshold] The maximum horizontal movement an object can
176
+ # perform in a single frame and keep contact with a
177
+ # ramp when it's above one.
178
+ # [ramp_slip_threshold] The maximum ratio between height and width of a ramp
179
+ # above which the objects will always slip down when
180
+ # trying to 'climb' that ramp.
137
181
  # [kb_held_delay] The number of frames a key must be held by the user
138
182
  # before the "held" event (that can be checked with
139
183
  # <code>KB.key_held?</code>) starts to trigger.
@@ -143,242 +187,249 @@ module AGL
143
187
  # [double_click_delay] The maximum interval, in frames, between two
144
188
  # clicks, to trigger the "double click" event
145
189
  # (checked with <code>Mouse.double_click?</code>).
146
- def self.initialize window, gravity = Vector.new(0, 1),
147
- kb_held_delay = 40, kb_held_interval = 5,
148
- double_click_delay = 8
149
- @@window = window
150
- @@gravity = gravity
151
- @@kb_held_delay = kb_held_delay
152
- @@kb_held_interval = kb_held_interval
153
- @@double_click_delay = double_click_delay
154
-
190
+ def initialize(scr_w, scr_h, fullscreen = true,
191
+ gravity = Vector.new(0, 1), min_speed = Vector.new(0.01, 0.01),
192
+ ramp_contact_threshold = 10, ramp_slip_threshold = 1.2,
193
+ kb_held_delay = 40, kb_held_interval = 5, double_click_delay = 8)
194
+ super scr_w, scr_h, fullscreen
195
+ G.window = self
196
+ G.gravity = gravity
197
+ G.min_speed = min_speed
198
+ G.ramp_contact_threshold = ramp_contact_threshold
199
+ G.ramp_slip_threshold = ramp_slip_threshold
200
+ G.kb_held_delay = kb_held_delay
201
+ G.kb_held_interval = kb_held_interval
202
+ G.double_click_delay = double_click_delay
155
203
  KB.initialize
156
204
  Mouse.initialize
157
205
  Res.initialize
158
206
  end
159
207
 
160
- # Returns a reference to the game window.
161
- def self.window; @@window; end
162
-
163
- # Returns a Vector representing the force of gravity. See +initialize+ for
164
- # details.
165
- def self.gravity; @@gravity; end
166
-
167
- # Returns the value of kb_held_delay. See +initialize+ for details.
168
- def self.kb_held_delay; @@kb_held_delay; end
169
-
170
- # Returns the value of kb_held_interval. See +initialize+ for details.
171
- def self.kb_held_interval; @@kb_held_interval; end
208
+ # Draws a rectangle with the size of the entire screen, in the given color.
209
+ #
210
+ # Parameters:
211
+ # [color] Color of the rectangle to be drawn.
212
+ def clear(color)
213
+ draw_quad 0, 0, color,
214
+ width, 0, color,
215
+ width, height, color,
216
+ 0, height, color, 0
217
+ end
172
218
 
173
- # Returns the value of double_click_delay. See +initialize+ for details.
174
- def self.double_click_delay; @@double_click_delay; end
219
+ # def toggle_fullscreen
220
+ # # TODO
221
+ # end
175
222
  end
176
223
 
177
224
  #class JSHelper
178
225
 
179
226
  # Exposes methods for controlling keyboard events.
180
- class KB
181
- # This is called by <code>Game.initialize</code>. Don't call it
182
- # explicitly.
183
- def self.initialize
184
- @@keys = [
185
- Gosu::KbUp, Gosu::KbDown,
186
- Gosu::KbReturn, Gosu::KbEscape,
187
- Gosu::KbLeftControl, Gosu::KbRightControl,
188
- Gosu::KbLeftAlt, Gosu::KbRightAlt,
189
- Gosu::KbA, Gosu::KbB, Gosu::KbC, Gosu::KbD, Gosu::KbE, Gosu::KbF,
190
- Gosu::KbG, Gosu::KbH, Gosu::KbI, Gosu::KbJ, Gosu::KbK, Gosu::KbL,
191
- Gosu::KbM, Gosu::KbN, Gosu::KbO, Gosu::KbP, Gosu::KbQ, Gosu::KbR,
192
- Gosu::KbS, Gosu::KbT, Gosu::KbU, Gosu::KbV, Gosu::KbW, Gosu::KbX,
193
- Gosu::KbY, Gosu::KbZ, Gosu::Kb1, Gosu::Kb2, Gosu::Kb3, Gosu::Kb4,
194
- Gosu::Kb5, Gosu::Kb6, Gosu::Kb7, Gosu::Kb8, Gosu::Kb9, Gosu::Kb0,
195
- Gosu::KbNumpad1, Gosu::KbNumpad2, Gosu::KbNumpad3, Gosu::KbNumpad4,
196
- Gosu::KbNumpad5, Gosu::KbNumpad6, Gosu::KbNumpad7, Gosu::KbNumpad8,
197
- Gosu::KbNumpad9, Gosu::KbNumpad0, Gosu::KbSpace, Gosu::KbBackspace,
198
- Gosu::KbDelete, Gosu::KbLeft, Gosu::KbRight, Gosu::KbHome,
199
- Gosu::KbEnd, Gosu::KbLeftShift, Gosu::KbRightShift, Gosu::KbTab,
200
- Gosu::KbBacktick, Gosu::KbMinus, Gosu::KbEqual, Gosu::KbBracketLeft,
201
- Gosu::KbBracketRight, Gosu::KbBackslash, Gosu::KbApostrophe,
202
- Gosu::KbComma, Gosu::KbPeriod, Gosu::KbSlash
203
- ]
204
- @@down = []
205
- @@prev_down = []
206
- @@held_timer = {}
207
- @@held_interval = {}
208
- end
227
+ module KB
228
+ class << self
229
+ # This is called by <code>GameWindow.initialize</code>. Don't call it
230
+ # explicitly.
231
+ def initialize
232
+ @keys = [
233
+ Gosu::KbUp, Gosu::KbDown,
234
+ Gosu::KbReturn, Gosu::KbEscape,
235
+ Gosu::KbLeftControl, Gosu::KbRightControl,
236
+ Gosu::KbLeftAlt, Gosu::KbRightAlt,
237
+ Gosu::KbA, Gosu::KbB, Gosu::KbC, Gosu::KbD, Gosu::KbE, Gosu::KbF,
238
+ Gosu::KbG, Gosu::KbH, Gosu::KbI, Gosu::KbJ, Gosu::KbK, Gosu::KbL,
239
+ Gosu::KbM, Gosu::KbN, Gosu::KbO, Gosu::KbP, Gosu::KbQ, Gosu::KbR,
240
+ Gosu::KbS, Gosu::KbT, Gosu::KbU, Gosu::KbV, Gosu::KbW, Gosu::KbX,
241
+ Gosu::KbY, Gosu::KbZ, Gosu::Kb1, Gosu::Kb2, Gosu::Kb3, Gosu::Kb4,
242
+ Gosu::Kb5, Gosu::Kb6, Gosu::Kb7, Gosu::Kb8, Gosu::Kb9, Gosu::Kb0,
243
+ Gosu::KbNumpad1, Gosu::KbNumpad2, Gosu::KbNumpad3, Gosu::KbNumpad4,
244
+ Gosu::KbNumpad5, Gosu::KbNumpad6, Gosu::KbNumpad7, Gosu::KbNumpad8,
245
+ Gosu::KbNumpad9, Gosu::KbNumpad0, Gosu::KbSpace, Gosu::KbBackspace,
246
+ Gosu::KbDelete, Gosu::KbLeft, Gosu::KbRight, Gosu::KbHome,
247
+ Gosu::KbEnd, Gosu::KbLeftShift, Gosu::KbRightShift, Gosu::KbTab,
248
+ Gosu::KbBacktick, Gosu::KbMinus, Gosu::KbEqual, Gosu::KbBracketLeft,
249
+ Gosu::KbBracketRight, Gosu::KbBackslash, Gosu::KbApostrophe,
250
+ Gosu::KbComma, Gosu::KbPeriod, Gosu::KbSlash
251
+ ]
252
+ @down = []
253
+ @prev_down = []
254
+ @held_timer = {}
255
+ @held_interval = {}
256
+ end
209
257
 
210
- # Updates the state of all keys.
211
- def self.update
212
- @@held_timer.each do |k, v|
213
- if v < Game.kb_held_delay; @@held_timer[k] += 1
214
- else
215
- @@held_interval[k] = 0
216
- @@held_timer.delete k
258
+ # Updates the state of all keys.
259
+ def update
260
+ @held_timer.each do |k, v|
261
+ if v < G.kb_held_delay; @held_timer[k] += 1
262
+ else
263
+ @held_interval[k] = 0
264
+ @held_timer.delete k
265
+ end
217
266
  end
218
- end
219
267
 
220
- @@held_interval.each do |k, v|
221
- if v < Game.kb_held_interval; @@held_interval[k] += 1
222
- else; @@held_interval[k] = 0; end
223
- end
268
+ @held_interval.each do |k, v|
269
+ if v < G.kb_held_interval; @held_interval[k] += 1
270
+ else; @held_interval[k] = 0; end
271
+ end
224
272
 
225
- @@prev_down = @@down.clone
226
- @@down.clear
227
- @@keys.each do |k|
228
- if Game.window.button_down? k
229
- @@down << k
230
- @@held_timer[k] = 0 if @@prev_down.index(k).nil?
231
- elsif @@prev_down.index(k)
232
- @@held_timer.delete k
233
- @@held_interval.delete k
273
+ @prev_down = @down.clone
274
+ @down.clear
275
+ @keys.each do |k|
276
+ if G.window.button_down? k
277
+ @down << k
278
+ @held_timer[k] = 0 if @prev_down.index(k).nil?
279
+ elsif @prev_down.index(k)
280
+ @held_timer.delete k
281
+ @held_interval.delete k
282
+ end
234
283
  end
235
284
  end
236
- end
237
285
 
238
- # Returns whether the given key is down in the current frame and was not
239
- # down in the frame before.
240
- #
241
- # Parameters:
242
- # [key] Code of the key to be checked. The available codes are <code>
243
- # Gosu::KbUp, Gosu::KbDown, Gosu::KbReturn, Gosu::KbEscape,
244
- # Gosu::KbLeftControl, Gosu::KbRightControl,
245
- # Gosu::KbLeftAlt, Gosu::KbRightAlt,
246
- # Gosu::KbA, Gosu::KbB, Gosu::KbC, Gosu::KbD, Gosu::KbE, Gosu::KbF,
247
- # Gosu::KbG, Gosu::KbH, Gosu::KbI, Gosu::KbJ, Gosu::KbK, Gosu::KbL,
248
- # Gosu::KbM, Gosu::KbN, Gosu::KbO, Gosu::KbP, Gosu::KbQ, Gosu::KbR,
249
- # Gosu::KbS, Gosu::KbT, Gosu::KbU, Gosu::KbV, Gosu::KbW, Gosu::KbX,
250
- # Gosu::KbY, Gosu::KbZ, Gosu::Kb1, Gosu::Kb2, Gosu::Kb3, Gosu::Kb4,
251
- # Gosu::Kb5, Gosu::Kb6, Gosu::Kb7, Gosu::Kb8, Gosu::Kb9, Gosu::Kb0,
252
- # Gosu::KbNumpad1, Gosu::KbNumpad2, Gosu::KbNumpad3, Gosu::KbNumpad4,
253
- # Gosu::KbNumpad5, Gosu::KbNumpad6, Gosu::KbNumpad7, Gosu::KbNumpad8,
254
- # Gosu::KbNumpad9, Gosu::KbNumpad0, Gosu::KbSpace, Gosu::KbBackspace,
255
- # Gosu::KbDelete, Gosu::KbLeft, Gosu::KbRight, Gosu::KbHome,
256
- # Gosu::KbEnd, Gosu::KbLeftShift, Gosu::KbRightShift, Gosu::KbTab,
257
- # Gosu::KbBacktick, Gosu::KbMinus, Gosu::KbEqual, Gosu::KbBracketLeft,
258
- # Gosu::KbBracketRight, Gosu::KbBackslash, Gosu::KbApostrophe,
259
- # Gosu::KbComma, Gosu::KbPeriod, Gosu::KbSlash</code>.
260
- def self.key_pressed? key
261
- @@prev_down.index(key).nil? and @@down.index(key)
262
- end
286
+ # Returns whether the given key is down in the current frame and was not
287
+ # down in the frame before.
288
+ #
289
+ # Parameters:
290
+ # [key] Code of the key to be checked. The available codes are <code>
291
+ # Gosu::KbUp, Gosu::KbDown, Gosu::KbReturn, Gosu::KbEscape,
292
+ # Gosu::KbLeftControl, Gosu::KbRightControl,
293
+ # Gosu::KbLeftAlt, Gosu::KbRightAlt,
294
+ # Gosu::KbA, Gosu::KbB, Gosu::KbC, Gosu::KbD, Gosu::KbE, Gosu::KbF,
295
+ # Gosu::KbG, Gosu::KbH, Gosu::KbI, Gosu::KbJ, Gosu::KbK, Gosu::KbL,
296
+ # Gosu::KbM, Gosu::KbN, Gosu::KbO, Gosu::KbP, Gosu::KbQ, Gosu::KbR,
297
+ # Gosu::KbS, Gosu::KbT, Gosu::KbU, Gosu::KbV, Gosu::KbW, Gosu::KbX,
298
+ # Gosu::KbY, Gosu::KbZ, Gosu::Kb1, Gosu::Kb2, Gosu::Kb3, Gosu::Kb4,
299
+ # Gosu::Kb5, Gosu::Kb6, Gosu::Kb7, Gosu::Kb8, Gosu::Kb9, Gosu::Kb0,
300
+ # Gosu::KbNumpad1, Gosu::KbNumpad2, Gosu::KbNumpad3, Gosu::KbNumpad4,
301
+ # Gosu::KbNumpad5, Gosu::KbNumpad6, Gosu::KbNumpad7, Gosu::KbNumpad8,
302
+ # Gosu::KbNumpad9, Gosu::KbNumpad0, Gosu::KbSpace, Gosu::KbBackspace,
303
+ # Gosu::KbDelete, Gosu::KbLeft, Gosu::KbRight, Gosu::KbHome,
304
+ # Gosu::KbEnd, Gosu::KbLeftShift, Gosu::KbRightShift, Gosu::KbTab,
305
+ # Gosu::KbBacktick, Gosu::KbMinus, Gosu::KbEqual, Gosu::KbBracketLeft,
306
+ # Gosu::KbBracketRight, Gosu::KbBackslash, Gosu::KbApostrophe,
307
+ # Gosu::KbComma, Gosu::KbPeriod, Gosu::KbSlash</code>.
308
+ def key_pressed?(key)
309
+ @prev_down.index(key).nil? and @down.index(key)
310
+ end
263
311
 
264
- # Returns whether the given key is down in the current frame.
265
- #
266
- # Parameters:
267
- # [key] Code of the key to be checked. See +key_pressed?+ for details.
268
- def self.key_down? key
269
- @@down.index(key)
270
- end
312
+ # Returns whether the given key is down in the current frame.
313
+ #
314
+ # Parameters:
315
+ # [key] Code of the key to be checked. See +key_pressed?+ for details.
316
+ def key_down?(key)
317
+ @down.index(key)
318
+ end
271
319
 
272
- # Returns whether the given key is not down in the current frame but was
273
- # down in the frame before.
274
- #
275
- # Parameters:
276
- # [key] Code of the key to be checked. See +key_pressed?+ for details.
277
- def self.key_released? key
278
- @@prev_down.index(key) and @@down.index(key).nil?
279
- end
320
+ # Returns whether the given key is not down in the current frame but was
321
+ # down in the frame before.
322
+ #
323
+ # Parameters:
324
+ # [key] Code of the key to be checked. See +key_pressed?+ for details.
325
+ def key_released?(key)
326
+ @prev_down.index(key) and @down.index(key).nil?
327
+ end
280
328
 
281
- # Returns whether the given key is being held down. See
282
- # <code>Game.initialize</code> for details.
283
- #
284
- # Parameters:
285
- # [key] Code of the key to be checked. See +key_pressed?+ for details.
286
- def self.key_held? key
287
- @@held_interval[key] == Game.kb_held_interval
329
+ # Returns whether the given key is being held down. See
330
+ # <code>GameWindow.initialize</code> for details.
331
+ #
332
+ # Parameters:
333
+ # [key] Code of the key to be checked. See +key_pressed?+ for details.
334
+ def key_held?(key)
335
+ @held_interval[key] == G.kb_held_interval
336
+ end
288
337
  end
289
338
  end
290
339
 
291
340
  # Exposes methods for controlling mouse events.
292
- class Mouse
293
- # This is called by <code>Game.initialize</code>. Don't call it
294
- # explicitly.
295
- def self.initialize
296
- @@down = {}
297
- @@prev_down = {}
298
- @@dbl_click = {}
299
- @@dbl_click_timer = {}
300
- end
301
-
302
- # Updates the mouse position and the state of all buttons.
303
- def self.update
304
- @@prev_down = @@down.clone
305
- @@down.clear
306
- @@dbl_click.clear
307
-
308
- @@dbl_click_timer.each do |k, v|
309
- if v < Game.double_click_delay; @@dbl_click_timer[k] += 1
310
- else; @@dbl_click_timer.delete k; end
341
+ module Mouse
342
+ class << self
343
+ # The current x-coordinate of the mouse cursor in the screen.
344
+ attr_reader :x
345
+
346
+ # The current y-coordinate of the mouse cursor in the screen.
347
+ attr_reader :y
348
+
349
+ # This is called by <code>GameWindow.initialize</code>. Don't call it
350
+ # explicitly.
351
+ def initialize
352
+ @down = {}
353
+ @prev_down = {}
354
+ @dbl_click = {}
355
+ @dbl_click_timer = {}
311
356
  end
312
357
 
313
- k1 = [Gosu::MsLeft, Gosu::MsMiddle, Gosu::MsRight]
314
- k2 = [:left, :middle, :right]
315
- for i in 0..2
316
- if Game.window.button_down? k1[i]
317
- @@down[k2[i]] = true
318
- @@dbl_click[k2[i]] = true if @@dbl_click_timer[k2[i]]
319
- @@dbl_click_timer.delete k2[i]
320
- elsif @@prev_down[k2[i]]
321
- @@dbl_click_timer[k2[i]] = 0
322
- end
323
- end
358
+ # Updates the mouse position and the state of all buttons.
359
+ def update
360
+ @prev_down = @down.clone
361
+ @down.clear
362
+ @dbl_click.clear
324
363
 
325
- @@x = Game.window.mouse_x.round
326
- @@y = Game.window.mouse_y.round
327
- end
364
+ @dbl_click_timer.each do |k, v|
365
+ if v < G.double_click_delay; @dbl_click_timer[k] += 1
366
+ else; @dbl_click_timer.delete k; end
367
+ end
328
368
 
329
- # Returns the x-coordinate of the mouse cursor in the screen.
330
- def self.x; @@x; end
369
+ k1 = [Gosu::MsLeft, Gosu::MsMiddle, Gosu::MsRight]
370
+ k2 = [:left, :middle, :right]
371
+ for i in 0..2
372
+ if G.window.button_down? k1[i]
373
+ @down[k2[i]] = true
374
+ @dbl_click[k2[i]] = true if @dbl_click_timer[k2[i]]
375
+ @dbl_click_timer.delete k2[i]
376
+ elsif @prev_down[k2[i]]
377
+ @dbl_click_timer[k2[i]] = 0
378
+ end
379
+ end
331
380
 
332
- # Returns the y-coordinate of the mouse cursor in the screen.
333
- def self.y; @@y; end
381
+ @x = G.window.mouse_x.round
382
+ @y = G.window.mouse_y.round
383
+ end
334
384
 
335
- # Returns whether the given button is down in the current frame and was
336
- # not down in the frame before.
337
- #
338
- # Parameters:
339
- # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
340
- # +:right+
341
- def self.button_pressed? btn
342
- @@down[btn] and not @@prev_down[btn]
343
- end
385
+ # Returns whether the given button is down in the current frame and was
386
+ # not down in the frame before.
387
+ #
388
+ # Parameters:
389
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
390
+ # +:right+
391
+ def button_pressed?(btn)
392
+ @down[btn] and not @prev_down[btn]
393
+ end
344
394
 
345
- # Returns whether the given button is down in the current frame.
346
- #
347
- # Parameters:
348
- # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
349
- # +:right+
350
- def self.button_down? btn
351
- @@down[btn]
352
- end
395
+ # Returns whether the given button is down in the current frame.
396
+ #
397
+ # Parameters:
398
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
399
+ # +:right+
400
+ def button_down?(btn)
401
+ @down[btn]
402
+ end
353
403
 
354
- # Returns whether the given button is not down in the current frame, but
355
- # was down in the frame before.
356
- #
357
- # Parameters:
358
- # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
359
- # +:right+
360
- def self.button_released? btn
361
- @@prev_down[btn] and not @@down[btn]
362
- end
404
+ # Returns whether the given button is not down in the current frame, but
405
+ # was down in the frame before.
406
+ #
407
+ # Parameters:
408
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
409
+ # +:right+
410
+ def button_released?(btn)
411
+ @prev_down[btn] and not @down[btn]
412
+ end
363
413
 
364
- # Returns whether the given button has just been double clicked.
365
- #
366
- # Parameters:
367
- # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
368
- # +:right+
369
- def self.double_click? btn
370
- @@dbl_click[btn]
371
- end
414
+ # Returns whether the given button has just been double clicked.
415
+ #
416
+ # Parameters:
417
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
418
+ # +:right+
419
+ def double_click?(btn)
420
+ @dbl_click[btn]
421
+ end
372
422
 
373
- # Returns whether the mouse cursor is currently inside the given area.
374
- #
375
- # Parameters:
376
- # [x] The x-coordinate of the top left corner of the area.
377
- # [y] The y-coordinate of the top left corner of the area.
378
- # [w] The width of the area.
379
- # [h] The height of the area.
380
- def self.over? x, y, w, h
381
- @@x >= x and @@x < x + w and @@y >= y and @@y < y + h
423
+ # Returns whether the mouse cursor is currently inside the given area.
424
+ #
425
+ # Parameters:
426
+ # [x] The x-coordinate of the top left corner of the area.
427
+ # [y] The y-coordinate of the top left corner of the area.
428
+ # [w] The width of the area.
429
+ # [h] The height of the area.
430
+ def over?(x, y, w, h)
431
+ @x >= x and @x < x + w and @y >= y and @y < y + h
432
+ end
382
433
  end
383
434
  end
384
435
 
@@ -393,178 +444,242 @@ module AGL
393
444
  # resource being loaded and the file name (either as string or as symbol).
394
445
  # There are default extensions for each type of resource, so the extension
395
446
  # must be specified only if the file is in a format other than the default.
396
- class Res
397
- # This is called by <code>Game.initialize</code>. Don't call it
398
- # explicitly.
399
- def self.initialize
400
- @@imgs = Hash.new
401
- @@global_imgs = Hash.new
402
- @@tilesets = Hash.new
403
- @@global_tilesets = Hash.new
404
- @@sounds = Hash.new
405
- @@global_sounds = Hash.new
406
- @@songs = Hash.new
407
- @@global_songs = Hash.new
408
- @@fonts = Hash.new
409
- @@global_fonts = Hash.new
410
- @@prefix = File.expand_path(File.dirname($0)) + '/data/'
411
- end
447
+ module Res
448
+ class << self
449
+ # Get the current prefix for searching data files. This is the directory
450
+ # under which 'img', 'sound', 'song', etc. folders are located.
451
+ attr_reader :prefix
452
+
453
+ # Gets the current path to image files (under +prefix+). Default is 'img'.
454
+ attr_reader :img_dir
455
+
456
+ # Gets the current path to tileset files (under +prefix+). Default is
457
+ # 'tileset'.
458
+ attr_reader :tileset_dir
459
+
460
+ # Gets the current path to sound files (under +prefix+). Default is 'sound'.
461
+ attr_reader :sound_dir
462
+
463
+ # Gets the current path to song files (under +prefix+). Default is 'song'.
464
+ attr_reader :song_dir
465
+
466
+ # Gets the current path to font files (under +prefix+). Default is 'font'.
467
+ attr_reader :font_dir
468
+
469
+ # Gets or sets the character that is currently being used in the +id+
470
+ # parameter of the loading methods as a folder separator. Default is '_'.
471
+ # Note that if you want to use symbols to specify paths, this separator
472
+ # should be a valid character in a Ruby symbol. On the other hand, if you
473
+ # want to use only slashes in Strings, you can specify a 'weird' character
474
+ # that won't appear in any file name.
475
+ attr_accessor :separator
476
+
477
+ # This is called by <code>GameWindow.initialize</code>. Don't call it
478
+ # explicitly.
479
+ def initialize
480
+ @imgs = {}
481
+ @global_imgs = {}
482
+ @tilesets = {}
483
+ @global_tilesets = {}
484
+ @sounds = {}
485
+ @global_sounds = {}
486
+ @songs = {}
487
+ @global_songs = {}
488
+ @fonts = {}
489
+ @global_fonts = {}
490
+
491
+ @prefix = File.expand_path(File.dirname($0)) + '/data/'
492
+ @img_dir = 'img/'
493
+ @tileset_dir = 'tileset/'
494
+ @sound_dir = 'sound/'
495
+ @song_dir = 'song/'
496
+ @font_dir = 'font/'
497
+ @separator = '_'
498
+ end
412
499
 
413
- # Get the current prefix for searching data files. This is the directory
414
- # under which 'img', 'sound', 'song', etc. folders are located.
415
- def self.prefix; @@prefix; end
500
+ # Set a custom prefix for loading resources. By default, the prefix is the
501
+ # directory of the game script. The prefix is the directory under which
502
+ # 'img', 'sound', 'song', etc. folders are located.
503
+ def prefix=(value)
504
+ value += '/' if value[-1] != '/'
505
+ @prefix = value
506
+ end
416
507
 
417
- # Set a custom prefix for loading resources. By default, the prefix is the
418
- # directory of the game script. The prefix is the directory under which
419
- # 'img', 'sound', 'song', etc. folders are located.
420
- def self.prefix= value
421
- value += '/' if value[-1] != '/'
422
- @@prefix = value
423
- end
508
+ # Sets the path to image files (under +prefix+). Default is 'img'.
509
+ def img_dir=(value)
510
+ value += '/' if value[-1] != '/'
511
+ @img_dir = value
512
+ end
424
513
 
425
- # Returns a <code>Gosu::Image</code> object.
426
- #
427
- # Parameters:
428
- # [id] A string or symbol representing the path to the image. If the file
429
- # is inside 'data/img', only the file name is needed. If it's inside
430
- # a subdirectory, the id must be prefixed by each subdirectory name
431
- # followed by an underscore. Example: to load
432
- # 'data/img/sprite/1.png', provide +:sprite_1+ or "sprite_1".
433
- # [global] Set to true if you want to keep the image in memory until the
434
- # game execution is finished. If false, the image will be
435
- # released when you call +clear+.
436
- # [tileable] Whether the image should be loaded in tileable mode, which is
437
- # proper for images that will be used as a tile, i.e., that
438
- # will be drawn repeated times, side by side, forming a
439
- # continuous composition.
440
- # [ext] The extension of the file being loaded. Specify only if it is
441
- # other than ".png".
442
- def self.img id, global = false, tileable = false, ext = ".png"
443
- if global; a = @@global_imgs; else; a = @@imgs; end
444
- return a[id] if a[id]
445
- s = @@prefix + "img/" + id.to_s.split('_').join('/') + ext
446
- img = Gosu::Image.new Game.window, s, tileable
447
- a[id] = img
448
- end
514
+ # Sets the path to tilset files (under +prefix+). Default is 'tileset'.
515
+ def tileset_dir=(value)
516
+ value += '/' if value[-1] != '/'
517
+ @tileset_dir = value
518
+ end
449
519
 
450
- # Returns an array of <code>Gosu::Image</code> objects, using the image as
451
- # a spritesheet. The image with index 0 will be the top left sprite, and
452
- # the following indices raise first from left to right and then from top
453
- # to bottom.
454
- #
455
- # Parameters:
456
- # [id] A string or symbol representing the path to the image. See +img+
457
- # for details.
458
- # [sprite_cols] Number of columns in the spritesheet.
459
- # [sprite_rows] Number of rows in the spritesheet.
460
- # [global] Set to true if you want to keep the image in memory until the
461
- # game execution is finished. If false, the image will be
462
- # released when you call +clear+.
463
- # [ext] The extension of the file being loaded. Specify only if it is
464
- # other than ".png".
465
- def self.imgs id, sprite_cols, sprite_rows, global = false, ext = ".png"
466
- if global; a = @@global_imgs; else; a = @@imgs; end
467
- return a[id] if a[id]
468
- s = @@prefix + "img/" + id.to_s.split('_').join('/') + ext
469
- imgs = Gosu::Image.load_tiles Game.window, s, -sprite_cols, -sprite_rows, false
470
- a[id] = imgs
471
- end
520
+ # Sets the path to sound files (under +prefix+). Default is 'sound'.
521
+ def sound_dir=(value)
522
+ value += '/' if value[-1] != '/'
523
+ @sound_dir = value
524
+ end
472
525
 
473
- # Returns an array of <code>Gosu::Image</code> objects, using the image as
474
- # a tileset. Works the same as +imgs+, except you must provide the tile
475
- # size instead of the number of columns and rows, and that the images will
476
- # be loaded as tileable.
477
- #
478
- # Parameters:
479
- # [id] A string or symbol representing the path to the image. It must be
480
- # specified the same way as in +img+, but the base directory is
481
- # 'data/tileset'.
482
- # [tile_width] Width of each tile, in pixels.
483
- # [tile_height] Height of each tile, in pixels.
484
- # [global] Set to true if you want to keep the image in memory until the
485
- # game execution is finished. If false, the image will be
486
- # released when you call +clear+.
487
- # [ext] The extension of the file being loaded. Specify only if it is
488
- # other than ".png".
489
- def self.tileset id, tile_width = 32, tile_height = 32, global = false, ext = ".png"
490
- if global; a = @@global_tilesets; else; a = @@tilesets; end
491
- return a[id] if a[id]
492
- s = @@prefix + "tileset/" + id.to_s.split('_').join('/') + ext
493
- tileset = Gosu::Image.load_tiles Game.window, s, tile_width, tile_height, true
494
- a[id] = tileset
495
- end
526
+ # Sets the path to song files (under +prefix+). Default is 'song'.
527
+ def song_dir=(value)
528
+ value += '/' if value[-1] != '/'
529
+ @song_dir = value
530
+ end
496
531
 
497
- # Returns a <code>Gosu::Sample</code> object. This should be used for
498
- # simple and short sound effects.
499
- #
500
- # Parameters:
501
- # [id] A string or symbol representing the path to the sound. It must be
502
- # specified the same way as in +img+, but the base directory is
503
- # 'data/sound'.
504
- # [global] Set to true if you want to keep the sound in memory until the
505
- # game execution is finished. If false, the sound will be
506
- # released when you call +clear+.
507
- # [ext] The extension of the file being loaded. Specify only if it is
508
- # other than ".wav".
509
- def self.sound id, global = false, ext = ".wav"
510
- if global; a = @@global_sounds; else; a = @@sounds; end
511
- return a[id] if a[id]
512
- s = @@prefix + "sound/" + id.to_s.split('_').join('/') + ext
513
- sound = Gosu::Sample.new Game.window, s
514
- a[id] = sound
515
- end
532
+ # Sets the path to font files (under +prefix+). Default is 'font'.
533
+ def font_dir=(value)
534
+ value += '/' if value[-1] != '/'
535
+ @font_dir = value
536
+ end
516
537
 
517
- # Returns a <code>Gosu::Song</code> object. This should be used for the
518
- # background musics of your game.
519
- #
520
- # Parameters:
521
- # [id] A string or symbol representing the path to the song. It must be
522
- # specified the same way as in +img+, but the base directory is
523
- # 'data/song'.
524
- # [global] Set to true if you want to keep the song in memory until the
525
- # game execution is finished. If false, the song will be released
526
- # when you call +clear+.
527
- # [ext] The extension of the file being loaded. Specify only if it is
528
- # other than ".ogg".
529
- def self.song id, global = false, ext = ".ogg"
530
- if global; a = @@global_songs; else; a = @@songs; end
531
- return a[id] if a[id]
532
- s = @@prefix + "song/" + id.to_s.split('_').join('/') + ext
533
- song = Gosu::Song.new Game.window, s
534
- a[id] = song
535
- end
538
+ # Returns a <code>Gosu::Image</code> object.
539
+ #
540
+ # Parameters:
541
+ # [id] A string or symbol representing the path to the image. If the file
542
+ # is inside +prefix+/+img_dir+, only the file name is needed. If it's
543
+ # inside a subdirectory of +prefix+/+img_dir+, the id must be
544
+ # prefixed by each subdirectory name followed by +separator+. Example:
545
+ # to load 'data/img/sprite/1.png', with the default values of +prefix+,
546
+ # +img_dir+ and +separator+, provide +:sprite_1+ or "sprite_1".
547
+ # [global] Set to true if you want to keep the image in memory until the
548
+ # game execution is finished. If false, the image will be
549
+ # released when you call +clear+.
550
+ # [tileable] Whether the image should be loaded in tileable mode, which is
551
+ # proper for images that will be used as a tile, i.e., that
552
+ # will be drawn repeated times, side by side, forming a
553
+ # continuous composition.
554
+ # [ext] The extension of the file being loaded. Specify only if it is
555
+ # other than '.png'.
556
+ def img(id, global = false, tileable = false, ext = '.png')
557
+ if global; a = @global_imgs; else; a = @imgs; end
558
+ return a[id] if a[id]
559
+ s = @prefix + @img_dir + id.to_s.split(@separator).join('/') + ext
560
+ img = Gosu::Image.new G.window, s, tileable
561
+ a[id] = img
562
+ end
536
563
 
537
- # Returns a <code>Gosu::Font</code> object. Fonts are needed to draw text
538
- # and used by MiniGL elements like buttons, text fields and TextHelper
539
- # objects.
540
- #
541
- # Parameters:
542
- # [id] A string or symbol representing the path to the song. It must be
543
- # specified the same way as in +img+, but the base directory is
544
- # 'data/font'.
545
- # [size] The size of the font, in pixels. This will correspond,
546
- # approximately, to the height of the tallest character when drawn.
547
- # [global] Set to true if you want to keep the font in memory until the
548
- # game execution is finished. If false, the font will be released
549
- # when you call +clear+.
550
- # [ext] The extension of the file being loaded. Specify only if it is
551
- # other than ".ttf".
552
- def self.font id, size, global = true, ext = ".ttf"
553
- if global; a = @@global_fonts; else; a = @@fonts; end
554
- id_size = "#{id}_#{size}"
555
- return a[id_size] if a[id_size]
556
- s = @@prefix + "font/" + id.to_s.split('_').join('/') + ext
557
- font = Gosu::Font.new Game.window, s, size
558
- a[id_size] = font
559
- end
564
+ # Returns an array of <code>Gosu::Image</code> objects, using the image as
565
+ # a spritesheet. The image with index 0 will be the top left sprite, and
566
+ # the following indices raise first from left to right and then from top
567
+ # to bottom.
568
+ #
569
+ # Parameters:
570
+ # [id] A string or symbol representing the path to the image. See +img+
571
+ # for details.
572
+ # [sprite_cols] Number of columns in the spritesheet.
573
+ # [sprite_rows] Number of rows in the spritesheet.
574
+ # [global] Set to true if you want to keep the image in memory until the
575
+ # game execution is finished. If false, the image will be
576
+ # released when you call +clear+.
577
+ # [ext] The extension of the file being loaded. Specify only if it is
578
+ # other than ".png".
579
+ def imgs(id, sprite_cols, sprite_rows, global = false, ext = '.png')
580
+ if global; a = @global_imgs; else; a = @imgs; end
581
+ return a[id] if a[id]
582
+ s = @prefix + @img_dir + id.to_s.split(@separator).join('/') + ext
583
+ imgs = Gosu::Image.load_tiles G.window, s, -sprite_cols, -sprite_rows, false
584
+ a[id] = imgs
585
+ end
560
586
 
561
- # Releases the memory used by all non-global resources.
562
- def self.clear
563
- @@imgs.clear
564
- @@tilesets.clear
565
- @@sounds.clear
566
- @@songs.clear
567
- @@fonts.clear
587
+ # Returns an array of <code>Gosu::Image</code> objects, using the image as
588
+ # a tileset. Works the same as +imgs+, except you must provide the tile
589
+ # size instead of the number of columns and rows, and that the images will
590
+ # be loaded as tileable.
591
+ #
592
+ # Parameters:
593
+ # [id] A string or symbol representing the path to the image. It must be
594
+ # specified the same way as in +img+, but the base directory is
595
+ # +prefix+/+tileset_dir+.
596
+ # [tile_width] Width of each tile, in pixels.
597
+ # [tile_height] Height of each tile, in pixels.
598
+ # [global] Set to true if you want to keep the image in memory until the
599
+ # game execution is finished. If false, the image will be
600
+ # released when you call +clear+.
601
+ # [ext] The extension of the file being loaded. Specify only if it is
602
+ # other than ".png".
603
+ def tileset(id, tile_width = 32, tile_height = 32, global = false, ext = '.png')
604
+ if global; a = @global_tilesets; else; a = @tilesets; end
605
+ return a[id] if a[id]
606
+ s = @prefix + @tileset_dir + id.to_s.split(@separator).join('/') + ext
607
+ tileset = Gosu::Image.load_tiles G.window, s, tile_width, tile_height, true
608
+ a[id] = tileset
609
+ end
610
+
611
+ # Returns a <code>Gosu::Sample</code> object. This should be used for
612
+ # simple and short sound effects.
613
+ #
614
+ # Parameters:
615
+ # [id] A string or symbol representing the path to the sound. It must be
616
+ # specified the same way as in +img+, but the base directory is
617
+ # +prefix+/+sound_dir+.
618
+ # [global] Set to true if you want to keep the sound in memory until the
619
+ # game execution is finished. If false, the sound will be
620
+ # released when you call +clear+.
621
+ # [ext] The extension of the file being loaded. Specify only if it is
622
+ # other than ".wav".
623
+ def sound(id, global = false, ext = '.wav')
624
+ if global; a = @global_sounds; else; a = @sounds; end
625
+ return a[id] if a[id]
626
+ s = @prefix + @sound_dir + id.to_s.split(@separator).join('/') + ext
627
+ sound = Gosu::Sample.new G.window, s
628
+ a[id] = sound
629
+ end
630
+
631
+ # Returns a <code>Gosu::Song</code> object. This should be used for the
632
+ # background musics of your game.
633
+ #
634
+ # Parameters:
635
+ # [id] A string or symbol representing the path to the song. It must be
636
+ # specified the same way as in +img+, but the base directory is
637
+ # +prefix+/+song_dir+.
638
+ # [global] Set to true if you want to keep the song in memory until the
639
+ # game execution is finished. If false, the song will be released
640
+ # when you call +clear+.
641
+ # [ext] The extension of the file being loaded. Specify only if it is
642
+ # other than ".ogg".
643
+ def song(id, global = false, ext = '.ogg')
644
+ if global; a = @global_songs; else; a = @songs; end
645
+ return a[id] if a[id]
646
+ s = @prefix + @song_dir + id.to_s.split(@separator).join('/') + ext
647
+ song = Gosu::Song.new G.window, s
648
+ a[id] = song
649
+ end
650
+
651
+ # Returns a <code>Gosu::Font</code> object. Fonts are needed to draw text
652
+ # and used by MiniGL elements like buttons, text fields and TextHelper
653
+ # objects.
654
+ #
655
+ # Parameters:
656
+ # [id] A string or symbol representing the path to the song. It must be
657
+ # specified the same way as in +img+, but the base directory is
658
+ # +prefix+/+font_dir+.
659
+ # [size] The size of the font, in pixels. This will correspond,
660
+ # approximately, to the height of the tallest character when drawn.
661
+ # [global] Set to true if you want to keep the font in memory until the
662
+ # game execution is finished. If false, the font will be released
663
+ # when you call +clear+.
664
+ # [ext] The extension of the file being loaded. Specify only if it is
665
+ # other than ".ttf".
666
+ def font(id, size, global = true, ext = '.ttf')
667
+ if global; a = @global_fonts; else; a = @fonts; end
668
+ id_size = "#{id}_#{size}"
669
+ return a[id_size] if a[id_size]
670
+ s = @prefix + @font_dir + id.to_s.split(@separator).join('/') + ext
671
+ font = Gosu::Font.new G.window, s, size
672
+ a[id_size] = font
673
+ end
674
+
675
+ # Releases the memory used by all non-global resources.
676
+ def clear
677
+ @imgs.clear
678
+ @tilesets.clear
679
+ @sounds.clear
680
+ @songs.clear
681
+ @fonts.clear
682
+ end
568
683
  end
569
684
  end
570
685
  end