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.
- checksums.yaml +4 -4
- data/README.md +15 -9
- data/lib/minigl/forms.rb +382 -30
- data/lib/minigl/game_object.rb +35 -10
- data/lib/minigl/global.rb +498 -383
- data/lib/minigl/map.rb +21 -21
- data/lib/minigl/movement.rb +100 -55
- data/lib/minigl/text.rb +37 -9
- data/test/data/img/barbg.png +0 -0
- data/test/data/img/barbg.svg +73 -0
- data/test/data/img/barfg.png +0 -0
- data/test/data/img/barfg.svg +106 -0
- data/test/data/img/barfgl.png +0 -0
- data/test/data/img/barfgl.svg +127 -0
- data/test/data/img/barfgr.png +0 -0
- data/test/data/img/barfgr.svg +135 -0
- data/test/data/img/square.png +0 -0
- data/test/data/img/square.svg +66 -0
- data/test/data/sound/1.wav +0 -0
- data/test/game.rb +49 -17
- data/test/game_object_tests.rb +35 -5
- data/test/iso_game.rb +2 -2
- data/test/map_tests.rb +1 -1
- data/test/mov_game.rb +72 -0
- data/test/movement_tests.rb +2 -3
- data/test/res_tests.rb +17 -3
- data/test/vector_tests.rb +1 -1
- metadata +26 -2
data/lib/minigl/game_object.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'movement'
|
2
2
|
|
3
|
-
module
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
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
|
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
|
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 ==
|
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 !=
|
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 +
|
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 -
|
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 *
|
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 /
|
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
|
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
|
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!
|
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
|
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
|
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
|
126
|
-
#
|
127
|
-
#
|
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
|
-
# [
|
131
|
-
#
|
132
|
-
#
|
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
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
-
#
|
161
|
-
|
162
|
-
|
163
|
-
#
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
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
|
-
#
|
174
|
-
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
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
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
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
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
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
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
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
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
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
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
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
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
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
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
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
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
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
|
-
|
326
|
-
|
327
|
-
|
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
|
-
|
330
|
-
|
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
|
-
|
333
|
-
|
381
|
+
@x = G.window.mouse_x.round
|
382
|
+
@y = G.window.mouse_y.round
|
383
|
+
end
|
334
384
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
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
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
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
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
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
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
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
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
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
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
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
|
-
|
414
|
-
|
415
|
-
|
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
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
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
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
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
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
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
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
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
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
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
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
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
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
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
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
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
|