minigl 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 01d773ef32ca54ed13e397c386708830e7731e8e
4
- data.tar.gz: 810ff8899be10ec787147090c539ac0d7608f603
3
+ metadata.gz: d75703110c27893ced02abaa49767ac4137d1b34
4
+ data.tar.gz: c376306e0d0a7838ebae01863302a418408ce840
5
5
  SHA512:
6
- metadata.gz: 25128512170f5275e48a8baec43555ab0307f246703cde5eeb55a5d2d4a52ffa9dbc055d5bb7933786eac9c7f00e289c03d8acb982d1aed514482127ebe8f952
7
- data.tar.gz: 7e0a5f25b732eaba12c1156e471ea7e1cff6a68774e09be3f3d6e29fbb43903f67420b7aabab0f08640467e34ef24a7a1226d7d05a8f26f17f0c9eaf701db7d1
6
+ metadata.gz: 221538181848507fc1b079eb9ac34d3c80f4740070641e2a1bfaef34ebe34effce282f36680082c4c6d2051eb9261f48af4b4d25a1428ad913c89cbba1694cad
7
+ data.tar.gz: e0f31296045813f211981db2c5c46a8b0fa0a044642072749d9396c14810739f5f6667d5a029d437497217bb605f8fb9cdb2e9302297e4e3bdb6293a98ecb2c0
data/README.md CHANGED
@@ -21,9 +21,8 @@ this [working game example](https://github.com/victords/aventura-do-saber).
21
21
  * The [documentation](https://github.com/victords/minigl/wiki) is under
22
22
  construction.
23
23
 
24
- **Version 1.2.5**
24
+ **Version 1.2.6**
25
25
 
26
- * Added support for "invisible" buttons (for associating actions with clicks
27
- in screen areas).
28
- * Exposed `Button`'s `click` method and `TextField`'s `focus` and `unfocus`
29
- methods.
26
+ * Added support for character restriction in `TextField`.
27
+ * Added `set_position` method to `Button` and `TextField`.
28
+ * Added RDoc documentation.
data/Rakefile CHANGED
@@ -5,3 +5,7 @@ Rake::TestTask.new do |t|
5
5
  t.test_files = FileList['test/*_tests.rb']
6
6
  t.verbose = true
7
7
  end
8
+
9
+ task :doc do |t|
10
+ sh "rdoc lib/minigl/*.rb"
11
+ end
data/lib/minigl/forms.rb CHANGED
@@ -1,7 +1,34 @@
1
1
  require_relative 'global'
2
2
 
3
3
  module AGL
4
+ # This class represents a button.
4
5
  class Button
6
+ # Creates a button.
7
+ # Parameters:
8
+ # [x] The x-coordinate where the button will be drawn in the screen.
9
+ # [y] The y-coordinate where the button will be drawn in the screen.
10
+ # [font] The <code>Gosu::Font</code> object that will be used to draw the
11
+ # button text.
12
+ # [text] The button text. Can be +nil+ or empty.
13
+ # [img] A spritesheet containing three images in a column, representing,
14
+ # from top to bottom, the default state, the hover state (when the
15
+ # mouse is over the button) and the pressed state (when the mouse
16
+ # button is down and the cursor is over the button). If +nil+, the
17
+ # +width+ and +height+ parameters must be provided.
18
+ # [text_color] Color of the button text, in hexadecimal RRGGBB format.
19
+ # [center] Whether the button text should be centered in its area (the
20
+ # area is defined by the image size, when an image is given, or
21
+ # by the +width+ and +height+ parameters, otherwise).
22
+ # [margin_x] The x offset, from the button x-coordinate, to draw the text.
23
+ # This parameter is used only if +center+ is false.
24
+ # [margin_y] The y offset, from the button y-coordinate, to draw the text.
25
+ # This parameter is used only if +center+ is false.
26
+ # [width] Width of the button clickable area. This parameter is used only
27
+ # if +img+ is +nil+.
28
+ # [height] Height of the button clickable area. This parameter is used
29
+ # only if +img+ is +nil+.
30
+ # [action] The block of code executed when the button is clicked (or by
31
+ # calling the +click+ method).
5
32
  def initialize x, y, font, text, img, text_color = 0, center = true, margin_x = 0, margin_y = 0, width = nil, height = nil, &action
6
33
  @x = x
7
34
  @y = y
@@ -30,7 +57,9 @@ module AGL
30
57
  @state = :up
31
58
  @img_index = 0
32
59
  end
33
-
60
+
61
+ # Updates the button, checking the mouse movement and buttons to define
62
+ # the button state.
34
63
  def update
35
64
  mouse_over = Mouse.over? @x, @y, @w, @h
36
65
  mouse_press = Mouse.button_pressed? :left
@@ -69,10 +98,32 @@ module AGL
69
98
  end
70
99
  end
71
100
 
101
+ # Executes the button click action.
72
102
  def click
73
103
  @action.call
74
104
  end
75
105
 
106
+ # Sets the position of the button in the screen.
107
+ # Parameters:
108
+ # [x] The new x-coordinate for the button.
109
+ # [y] The new y-coordinate for the button.
110
+ def set_position x, y
111
+ d_x = x - @x
112
+ d_y = y - @y
113
+ @x = x; @y = y
114
+ if @center
115
+ @text_x = x + @w / 2
116
+ @text_y = y + @h / 2
117
+ else
118
+ @text_x += d_x
119
+ @text_y += d_y
120
+ end
121
+ end
122
+
123
+ # Draws the button in the screen.
124
+ # Parameters:
125
+ # [alpha] The opacity with which the button will be drawn. Allowed values
126
+ # vary between 0 (fully transparent) and 255 (fully opaque).
76
127
  def draw alpha = 0xff
77
128
  color = (alpha << 24) | 0xffffff
78
129
  text_color = (alpha << 24) | @text_color
@@ -87,11 +138,42 @@ module AGL
87
138
  end
88
139
  end
89
140
 
141
+ # This class represents a text field (input).
90
142
  class TextField
143
+ # The current text inside the text field.
91
144
  attr_reader :text
92
145
 
93
- def initialize x, y, font, img, cursor_img = nil, margin_x = 0, margin_y = 0, max_length = 100, active = false,
94
- text = "", text_color = 0, selection_color = 0
146
+ # Creates a new text field.
147
+ # Parameters:
148
+ # [x] The x-coordinate where the text field will be drawn in the screen.
149
+ # [y] The y-coordinate where the text field will be drawn in the screen.
150
+ # [font] The <code>Gosu::Font</code> object that will be used to draw the
151
+ # text inside the field.
152
+ # [img] The image of the text field. For a good result, you would likely
153
+ # want something like a rectangle, horizontally wide, vertically
154
+ # short, and with a color that contrasts with the +text_color+.
155
+ # [cursor_img] An image for the blinking cursor that stands in the point
156
+ # where text will be inserted. If +nil+, a simple black line
157
+ # will be drawn instead.
158
+ # [text_color] Color of the button text, in hexadecimal RRGGBB format.
159
+ # [margin_x] The x offset, from the field x-coordinate, to draw the text.
160
+ # [margin_y] The y offset, from the field y-coordinate, to draw the text.
161
+ # [max_length] The maximum length of the text inside the field.
162
+ # [active] Whether the text field must be focused by default. If +false+,
163
+ # focus can be granted by clicking inside the text field or by
164
+ # calling the +focus+ method.
165
+ # [text] The starting text. Must not be +nil+.
166
+ # [allowed_chars] A string containing all characters that can be typed
167
+ # inside the text field. The complete set of supported
168
+ # characters is given by the string
169
+ # <code>"abcdefghijklmnopqrstuvwxyz1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ'-=/[]\\\\,.;\"_+?{}|<>:!@#$%¨&*()"</code>.
170
+ # [text_color] The color with which the text will be drawn, in hexadecimal
171
+ # RRGGBB format.
172
+ # [selection_color] The color of the rectangle highlighting selected text,
173
+ # in hexadecimal RRGGBB format. The rectangle will
174
+ # always be drawn with 50% of opacity.
175
+ def initialize x, y, font, img, cursor_img = nil, margin_x = 0, margin_y = 0, max_length = 100, active = false, text = "",
176
+ allowed_chars = nil, text_color = 0, selection_color = 0
95
177
  @x = x
96
178
  @y = y
97
179
  @font = font
@@ -128,41 +210,16 @@ module AGL
128
210
  Gosu::KbBracketRight, Gosu::KbBackslash, Gosu::KbApostrophe,
129
211
  Gosu::KbComma, Gosu::KbPeriod, Gosu::KbSlash
130
212
  ]
131
- @chars = "abcdefghijklmnopqrstuvwxyz1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ'-=/[]\\,.;\"_+?{}|<>:!@#$%6&*()"
132
- end
133
-
134
- def text= value
135
- @text = value[0...max_length]
136
- @nodes.clear; @nodes << (@x + @margin_x)
137
- x = @nodes[0]
138
- for char in @text
139
- x += @font.text_width char
140
- @nodes << x
141
- end
142
- @cur_node = @nodes.size - 1
143
- @anchor1 = nil
144
- @anchor2 = nil
145
- set_cursor_visible
146
- end
147
-
148
- def selected_text
149
- return "" if @anchor2.nil?
150
- min = @anchor1 < @anchor2 ? @anchor1 : @anchor2
151
- max = min == @anchor1 ? @anchor2 : @anchor1
152
- @text[min..max]
153
- end
154
-
155
- def focus
156
- @active = true
157
- end
158
-
159
- def unfocus
160
- @anchor1 = @anchor2 = nil
161
- @cursor_visible = false
162
- @cursor_timer = 0
163
- @active = false
213
+ @chars = "abcdefghijklmnopqrstuvwxyz1234567890 ABCDEFGHIJKLMNOPQRSTUVWXYZ'-=/[]\\,.;\"_+?{}|<>:!@#$%¨&*()"
214
+ @allowed_chars =
215
+ if allowed_chars
216
+ allowed_chars
217
+ else
218
+ @chars
219
+ end
164
220
  end
165
221
 
222
+ # Updates the text field, checking for mouse events and keyboard input.
166
223
  def update
167
224
  ################################ Mouse ################################
168
225
  if Mouse.over? @x, @y, @w, @h
@@ -321,6 +378,66 @@ module AGL
321
378
  end
322
379
  end
323
380
 
381
+ # Sets the text of the text field to the specified value.
382
+ # Parameters:
383
+ # [value] The new text to be set. If it's longer than the +max_length+
384
+ # parameter used in the constructor, it will be truncated to
385
+ # +max_length+ characters.
386
+ def text= value
387
+ @text = value[0...max_length]
388
+ @nodes.clear; @nodes << (@x + @margin_x)
389
+ x = @nodes[0]
390
+ for char in @text
391
+ x += @font.text_width char
392
+ @nodes << x
393
+ end
394
+ @cur_node = @nodes.size - 1
395
+ @anchor1 = nil
396
+ @anchor2 = nil
397
+ set_cursor_visible
398
+ end
399
+
400
+ # Returns the currently selected text.
401
+ def selected_text
402
+ return "" if @anchor2.nil?
403
+ min = @anchor1 < @anchor2 ? @anchor1 : @anchor2
404
+ max = min == @anchor1 ? @anchor2 : @anchor1
405
+ @text[min..max]
406
+ end
407
+
408
+ # Grants focus to the text field, so that it allows keyboard input.
409
+ def focus
410
+ @active = true
411
+ end
412
+
413
+ # Removes focus from the text field, so that no keyboard input will be
414
+ # accepted.
415
+ def unfocus
416
+ @anchor1 = @anchor2 = nil
417
+ @cursor_visible = false
418
+ @cursor_timer = 0
419
+ @active = false
420
+ end
421
+
422
+ # Sets the position of the text field in the screen.
423
+ # Parameters:
424
+ # [x] The new x-coordinate for the text field.
425
+ # [y] The new y-coordinate for the text field.
426
+ def set_position x, y
427
+ d_x = x - @x
428
+ d_y = y - @y
429
+ @x = x; @y = y
430
+ @text_x += d_x
431
+ @text_y += d_y
432
+ @nodes.map! do |n|
433
+ n + d_x
434
+ end
435
+ end
436
+
437
+ # Draws the text field in the screen.
438
+ # Parameters:
439
+ # [alpha] The opacity with which the text field will be drawn. Allowed
440
+ # values vary between 0 (fully transparent) and 255 (fully opaque).
324
441
  def draw alpha = 0xff
325
442
  color = (alpha << 24) | 0xffffff
326
443
  text_color = (alpha << 24) | @text_color
@@ -371,6 +488,7 @@ module AGL
371
488
  end
372
489
 
373
490
  def insert_char char
491
+ return unless @allowed_chars.index char
374
492
  if @text.length < @max_length
375
493
  @text.insert @cur_node, char
376
494
  @nodes.insert @cur_node + 1, @nodes[@cur_node] + @font.text_width(char)
@@ -1,10 +1,34 @@
1
1
  require_relative 'movement'
2
2
 
3
3
  module AGL
4
+ # This class represents an (optionally animated) image inside the game screen.
4
5
  class Sprite
6
+ # The index of the current sprite in the spritesheet being drawn.
5
7
  attr_reader :img_index
6
- attr_accessor :x, :y
7
8
 
9
+ # The x-coordinate of the image in the screen.
10
+ attr_accessor :x
11
+
12
+ # The y-coordinate of the image in the screen.
13
+ attr_accessor :y
14
+
15
+ # Creates a new sprite.
16
+ # Parameters:
17
+ # [x] The x-coordinate where the sprite will be drawn in the screen.
18
+ # [y] The y-coordinate where the sprite will be drawn in the screen.
19
+ # [img] The path to a PNG image or spritesheet, following the MiniGL
20
+ # convention: images must be inside a 'data/img' directory, relative
21
+ # to the code file, and you must only provide the file name, without
22
+ # extension, in this case. If the image is inside a subdirectory of
23
+ # 'data/img', you must prefix the file name with each subdirectory
24
+ # name, followed by an underscore (so the file and directories names
25
+ # must not contain underscores). For example, if your image is
26
+ # 'data/img/sprite/1.png', you must provide <code>"sprite_1"</code>
27
+ # or +:sprite_1+.
28
+ # [sprite_cols] The number of columns in the spritesheet. Use +nil+ if the
29
+ # image is not a spritesheet.
30
+ # [sprite_rows] The number of rows in the spritesheet. Use +nil+ if the
31
+ # image is not a spritesheet.
8
32
  def initialize x, y, img, sprite_cols = nil, sprite_rows = nil
9
33
  @x = x; @y = y
10
34
  @img =
@@ -18,6 +42,16 @@ module AGL
18
42
  @index_index = 0
19
43
  end
20
44
 
45
+ # Performs time checking to update the image index according to the
46
+ # sequence of indices and the interval.
47
+ # Parameters:
48
+ # [indices] The sequence of image indices used in the animation. The
49
+ # indices are determined from left to right, and from top to
50
+ # bottom, inside the spritesheet. All indices must be in the
51
+ # interval <code>0..(sprite_cols * sprite_rows)</code>.
52
+ # [interval] The amount of frames between each change in the image index.
53
+ # A frame will usually represent 1/60 second (roughly 17
54
+ # milliseconds).
21
55
  def animate indices, interval
22
56
  @anim_counter += 1
23
57
  if @anim_counter >= interval
@@ -28,6 +62,22 @@ module AGL
28
62
  end
29
63
  end
30
64
 
65
+ # Draws the sprite in the screen
66
+ # Parameters:
67
+ # [map] A Map object, relative to which the sprite will be drawn (the x
68
+ # and y coordinates of the sprite will be changed according to the
69
+ # position of the camera).
70
+ # [scale_x] A scale factor to be applied horizontally to the image.
71
+ # [scale_y] A scale factor to be applied vertically to the image.
72
+ # [alpha] The opacity with which the image will be drawn. Valid values
73
+ # vary from 0 (fully transparent) to 255 (fully opaque).
74
+ # [color] A color filter to apply to the image. A white (0xffffff) filter
75
+ # will keep all colors unchanged, while a black (0x000000) filter
76
+ # will turn all colors to black. A red (0xff0000) filter will keep
77
+ # reddish colors with slight or no change, whereas bluish colors
78
+ # will be darkened, for example.
79
+ # [angle] A rotation, in degrees, to be applied to the image, relative to
80
+ # its center.
31
81
  def draw map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil
32
82
  color = (alpha << 24) | color
33
83
  if map
@@ -43,10 +93,29 @@ module AGL
43
93
  end
44
94
  end
45
95
  end
46
-
96
+
97
+ # This class represents an object with a set of properties and methods
98
+ # commonly used in games. It defines an object with a rectangular bounding
99
+ # box, and having all the attributes required for using the Movement module.
47
100
  class GameObject < Sprite
48
101
  include Movement
49
102
 
103
+ # Creates a new game object.
104
+ # Parameters:
105
+ # [x] The x-coordinate of the object's bounding box.
106
+ # [y] The y-coordinate of the object's bounding box.
107
+ # [w] The width of the object's bounding box.
108
+ # [h] The height of the object's bounding box.
109
+ # [img] The image or spritesheet for the object.
110
+ # [img_gap] A Vector object representing the difference between the top
111
+ # left corner of the bounding box and the coordinates of the
112
+ # image. For example, an object with <code>x = 100</code>,
113
+ # <code>y = 50</code> and <code>img_gap = Vector.new(-5, -5)</code>
114
+ # will be drawn at position (95, 45) of the screen.
115
+ # [sprite_cols] The number of columns in the spritesheet. Use +nil+ if the
116
+ # image is not a spritesheet.
117
+ # [sprite_rows] The number of rows in the spritesheet. Use +nil+ if the
118
+ # image is not a spritesheet.
50
119
  def initialize x, y, w, h, img, img_gap = nil, sprite_cols = nil, sprite_rows = nil
51
120
  super x, y, img, sprite_cols, sprite_rows
52
121
  @w = w; @h = h
@@ -62,17 +131,37 @@ module AGL
62
131
  @stored_forces = Vector.new 0, 0
63
132
  end
64
133
 
134
+ # Resets the animation timer and immediately changes the image index to
135
+ # the specified value.
136
+ # Parameters:
137
+ # [index] The image index to be set.
65
138
  def set_animation index
66
139
  @anim_counter = 0
67
140
  @img_index = index
68
141
  @index_index = 0
69
142
  end
70
143
 
71
- def is_visible map
144
+ def is_visible map # :nodoc:
72
145
  return map.cam.intersects @active_bounds if @active_bounds
73
146
  false
74
147
  end
75
148
 
149
+ # Draws the game object in the screen.
150
+ # Parameters:
151
+ # [map] A Map object, relative to which the object will be drawn (the x
152
+ # and y coordinates of the image will be changed according to the
153
+ # position of the camera).
154
+ # [scale_x] A scale factor to be applied horizontally to the image.
155
+ # [scale_y] A scale factor to be applied vertically to the image.
156
+ # [alpha] The opacity with which the image will be drawn. Valid values
157
+ # vary from 0 (fully transparent) to 255 (fully opaque).
158
+ # [color] A color filter to apply to the image. A white (0xffffff) filter
159
+ # will keep all colors unchanged, while a black (0x000000) filter
160
+ # will turn all colors to black. A red (0xff0000) filter will keep
161
+ # reddish colors with slight or no change, whereas bluish colors
162
+ # will be darkened, for example.
163
+ # [angle] A rotation, in degrees, to be applied to the image, relative to
164
+ # its center.
76
165
  def draw map = nil, scale_x = 1, scale_y = 1, alpha = 0xff, color = 0xffffff, angle = nil
77
166
  color = (alpha << 24) | color
78
167
  if map
@@ -91,6 +180,7 @@ module AGL
91
180
  end
92
181
  end
93
182
 
183
+ # :nodoc: all
94
184
  class Effect < Sprite
95
185
  def initialize x, y, life_time, img, sprite_cols = nil, sprite_rows = nil, indices = nil, interval = 1
96
186
  super x, y, img, sprite_cols, sprite_rows
data/lib/minigl/global.rb CHANGED
@@ -1,21 +1,66 @@
1
1
  require 'gosu'
2
2
 
3
+ # The main module of the library, used only as a namespace.
3
4
  module AGL
5
+ # A Struct with two attributes, x and y (in this order), representing a point
6
+ # in a bidimensional space.
4
7
  Vector = Struct.new :x, :y
5
8
 
9
+ # This class represents a rectangle by its x and y coordinates and width and
10
+ # height.
6
11
  class Rectangle
7
- attr_accessor :x, :y, :w, :h
12
+ # The x-coordinate of the rectangle.
13
+ attr_accessor :x
8
14
 
15
+ # The y-coordinate of the rectangle.
16
+ attr_accessor :y
17
+
18
+ # The width of the rectangle.
19
+ attr_accessor :w
20
+
21
+ # The height of the rectangle.
22
+ attr_accessor :h
23
+
24
+ # Creates a new rectangle.
25
+ # Parameters:
26
+ # [x] The x-coordinate of the rectangle.
27
+ # [y] The y-coordinate of the rectangle.
28
+ # [w] The width of the rectangle.
29
+ # [h] The height of the rectangle.
9
30
  def initialize x, y, w, h
10
31
  @x = x; @y = y; @w = w; @h = h
11
32
  end
12
33
 
34
+ # Returns whether this rectangle intersects another.
35
+ # Parameters:
36
+ # [r] The rectangle to check intersection with.
13
37
  def intersects r
14
38
  @x < r.x + r.w && @x + @w > r.x && @y < r.y + r.h && @y + @h > r.y
15
39
  end
16
40
  end
17
41
 
42
+ # The main class for a MiniGL game, holds references to globally accessible
43
+ # objects and constants.
18
44
  class Game
45
+ # Initializes a MiniGL game. This method must be called before any feature
46
+ # provided by the library can be used.
47
+ # Parameters:
48
+ # [window] An instance of a class which inherits from
49
+ # <code>Gosu::Window</code>. This will be the game window, used
50
+ # to draw everything and capture user input.
51
+ # [gravity] A Vector object representing the horizontal and vertical
52
+ # components of the force of gravity. Essentially, this force
53
+ # will be applied to every object which calls +move+, from the
54
+ # Movement module.
55
+ # [kb_held_delay] The number of frames a key must be held by the user
56
+ # before the "held" event (that can be checked with
57
+ # <code>KB.key_held?</code>) starts to trigger.
58
+ # [kb_held_interval] The interval, in frames, between each triggering of
59
+ # the "held" event, after the key has been held for
60
+ # more than +kb_held_delay+ frames.
61
+ # [double_click_delay] The maximum interval, in frames, between two
62
+ # clicks, to trigger the "double click" event
63
+ # (checked with <code>Mouse.double_click?</code>).
19
64
  def self.initialize window, gravity = Vector.new(0, 1),
20
65
  kb_held_delay = 40, kb_held_interval = 5,
21
66
  double_click_delay = 8
@@ -30,16 +75,29 @@ module AGL
30
75
  Res.initialize
31
76
  end
32
77
 
78
+ # Returns a reference to the game window.
33
79
  def self.window; @@window; end
80
+
81
+ # Returns a Vector representing the force of gravity. See +initialize+ for
82
+ # details.
34
83
  def self.gravity; @@gravity; end
84
+
85
+ # Returns the value of kb_held_delay. See +initialize+ for details.
35
86
  def self.kb_held_delay; @@kb_held_delay; end
87
+
88
+ # Returns the value of kb_held_interval. See +initialize+ for details.
36
89
  def self.kb_held_interval; @@kb_held_interval; end
90
+
91
+ # Returns the value of double_click_delay. See +initialize+ for details.
37
92
  def self.double_click_delay; @@double_click_delay; end
38
93
  end
39
94
 
40
95
  #class JSHelper
41
96
 
97
+ # Exposes methods for controlling keyboard events.
42
98
  class KB
99
+ # This is called by <code>Game.initialize</code>. Don't call it
100
+ # explicitly.
43
101
  def self.initialize
44
102
  @@keys = [
45
103
  Gosu::KbUp, Gosu::KbDown,
@@ -66,6 +124,7 @@ module AGL
66
124
  @@held_interval = {}
67
125
  end
68
126
 
127
+ # Updates the state of all keys.
69
128
  def self.update
70
129
  @@held_timer.each do |k, v|
71
130
  if v < Game.kb_held_delay; @@held_timer[k] += 1
@@ -93,24 +152,58 @@ module AGL
93
152
  end
94
153
  end
95
154
 
155
+ # Returns whether the given key is down in the current frame and was not
156
+ # down in the frame before.
157
+ # Parameters:
158
+ # [key] Code of the key to be checked. The available codes are <code>
159
+ # Gosu::KbUp, Gosu::KbDown, Gosu::KbReturn, Gosu::KbEscape,
160
+ # Gosu::KbLeftControl, Gosu::KbRightControl,
161
+ # Gosu::KbA, Gosu::KbB, Gosu::KbC, Gosu::KbD, Gosu::KbE, Gosu::KbF,
162
+ # Gosu::KbG, Gosu::KbH, Gosu::KbI, Gosu::KbJ, Gosu::KbK, Gosu::KbL,
163
+ # Gosu::KbM, Gosu::KbN, Gosu::KbO, Gosu::KbP, Gosu::KbQ, Gosu::KbR,
164
+ # Gosu::KbS, Gosu::KbT, Gosu::KbU, Gosu::KbV, Gosu::KbW, Gosu::KbX,
165
+ # Gosu::KbY, Gosu::KbZ, Gosu::Kb1, Gosu::Kb2, Gosu::Kb3, Gosu::Kb4,
166
+ # Gosu::Kb5, Gosu::Kb6, Gosu::Kb7, Gosu::Kb8, Gosu::Kb9, Gosu::Kb0,
167
+ # Gosu::KbNumpad1, Gosu::KbNumpad2, Gosu::KbNumpad3, Gosu::KbNumpad4,
168
+ # Gosu::KbNumpad5, Gosu::KbNumpad6, Gosu::KbNumpad7, Gosu::KbNumpad8,
169
+ # Gosu::KbNumpad9, Gosu::KbNumpad0, Gosu::KbSpace, Gosu::KbBackspace,
170
+ # Gosu::KbDelete, Gosu::KbLeft, Gosu::KbRight, Gosu::KbHome,
171
+ # Gosu::KbEnd, Gosu::KbLeftShift, Gosu::KbRightShift,
172
+ # Gosu::KbBacktick, Gosu::KbMinus, Gosu::KbEqual, Gosu::KbBracketLeft,
173
+ # Gosu::KbBracketRight, Gosu::KbBackslash, Gosu::KbApostrophe,
174
+ # Gosu::KbComma, Gosu::KbPeriod, Gosu::KbSlash</code>.
96
175
  def self.key_pressed? key
97
176
  @@prev_down.index(key).nil? and @@down.index(key)
98
177
  end
99
178
 
179
+ # Returns whether the given key is down in the current frame.
180
+ # Parameters:
181
+ # [key] Code of the key to be checked. See +key_pressed?+ for details.
100
182
  def self.key_down? key
101
183
  @@down.index(key)
102
184
  end
103
185
 
186
+ # Returns whether the given key is not down in the current frame but was
187
+ # down in the frame before.
188
+ # Parameters:
189
+ # [key] Code of the key to be checked. See +key_pressed?+ for details.
104
190
  def self.key_released? key
105
191
  @@prev_down.index(key) and @@down.index(key).nil?
106
192
  end
107
193
 
194
+ # Returns whether the given key is being held down. See
195
+ # <code>Game.initialize</code> for details.
196
+ # Parameters:
197
+ # [key] Code of the key to be checked. See +key_pressed?+ for details.
108
198
  def self.key_held? key
109
199
  @@held_interval[key] == Game.kb_held_interval
110
200
  end
111
201
  end
112
202
 
203
+ # Exposes methods for controlling mouse events.
113
204
  class Mouse
205
+ # This is called by <code>Game.initialize</code>. Don't call it
206
+ # explicitly.
114
207
  def self.initialize
115
208
  @@down = {}
116
209
  @@prev_down = {}
@@ -118,6 +211,7 @@ module AGL
118
211
  @@dbl_click_timer = {}
119
212
  end
120
213
 
214
+ # Updates the mouse position and the state of all buttons.
121
215
  def self.update
122
216
  @@prev_down = @@down.clone
123
217
  @@down.clear
@@ -144,31 +238,71 @@ module AGL
144
238
  @@y = Game.window.mouse_y.round
145
239
  end
146
240
 
241
+ # Returns the x-coordinate of the mouse cursor in the screen.
147
242
  def self.x; @@x; end
243
+
244
+ # Returns the y-coordinate of the mouse cursor in the screen.
148
245
  def self.y; @@y; end
149
246
 
247
+ # Returns whether the given button is down in the current frame and was
248
+ # not down in the frame before.
249
+ # Parameters:
250
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
251
+ # +:right+
150
252
  def self.button_pressed? btn
151
253
  @@down[btn] and not @@prev_down[btn]
152
254
  end
153
255
 
256
+ # Returns whether the given button is down in the current frame.
257
+ # Parameters:
258
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
259
+ # +:right+
154
260
  def self.button_down? btn
155
261
  @@down[btn]
156
262
  end
157
263
 
264
+ # Returns whether the given button is not down in the current frame, but
265
+ # was down in the frame before.
266
+ # Parameters:
267
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
268
+ # +:right+
158
269
  def self.button_released? btn
159
270
  @@prev_down[btn] and not @@down[btn]
160
271
  end
161
272
 
273
+ # Returns whether the given button has just been double clicked.
274
+ # Parameters:
275
+ # [btn] Button to be checked. Valid values are +:left+, +:middle+ and
276
+ # +:right+
162
277
  def self.double_click? btn
163
278
  @@dbl_click[btn]
164
279
  end
165
280
 
281
+ # Returns whether the mouse cursor is currently inside the given area.
282
+ # Parameters:
283
+ # [x] The x-coordinate of the top left corner of the area.
284
+ # [y] The y-coordinate of the top left corner of the area.
285
+ # [w] The width of the area.
286
+ # [h] The height of the area.
166
287
  def self.over? x, y, w, h
167
288
  @@x >= x and @@x < x + w and @@y >= y and @@y < y + h
168
289
  end
169
290
  end
170
291
 
292
+ # This class is responsible for resource management. It keeps references to
293
+ # all loaded resources until a call to +clear+ is made. Resources can be
294
+ # loaded as global, so that their references won't be removed even when
295
+ # +clear+ is called.
296
+ #
297
+ # It also provides an easier syntax for loading resources, assuming a
298
+ # particular folder structure. All resources must be inside subdirectories
299
+ # of a 'data' directory, so that you will only need to specify the type of
300
+ # resource being loaded and the file name (either as string or as symbol).
301
+ # There are default extensions for each type of resource, so the extension
302
+ # must be specified only if the file is in a format other than the default.
171
303
  class Res
304
+ # This is called by <code>Game.initialize</code>. Don't call it
305
+ # explicitly.
172
306
  def self.initialize
173
307
  @@imgs = Hash.new
174
308
  @@global_imgs = Hash.new
@@ -176,10 +310,28 @@ module AGL
176
310
  @@global_tilesets = Hash.new
177
311
  @@sounds = Hash.new
178
312
  @@global_sounds = Hash.new
313
+ @@songs = Hash.new
314
+ @@global_songs = Hash.new
179
315
  @@fonts = Hash.new
180
316
  @@global_fonts = Hash.new
181
317
  end
182
318
 
319
+ # Returns a <code>Gosu::Image</code> object.
320
+ # Parameters:
321
+ # [id] A string or symbol representing the path to the image. If the file
322
+ # is inside 'data/img', only the file name is needed. If it's inside
323
+ # a subdirectory, the id must be prefixed by each subdirectory name
324
+ # followed by an underscore. Example: to load
325
+ # 'data/img/sprite/1.png', provide +:sprite_1+ or "sprite_1".
326
+ # [global] Set to true if you want to keep the image in memory until the
327
+ # game execution is finished. If false, the image will be
328
+ # released when you call +clear+.
329
+ # [tileable] Whether the image should be loaded in tileable mode, which is
330
+ # proper for images that will be used as a tile, i.e., that
331
+ # will be drawn repeated times, side by side, forming a
332
+ # continuous composition.
333
+ # [ext] The extension of the file being loaded. Specify only if it is
334
+ # other than ".png".
183
335
  def self.img id, global = false, tileable = false, ext = ".png"
184
336
  if global; a = @@global_imgs; else; a = @@imgs; end
185
337
  return a[id] if a[id]
@@ -188,6 +340,20 @@ module AGL
188
340
  a[id] = img
189
341
  end
190
342
 
343
+ # Returns an array of <code>Gosu::Image</code> objects, using the image as
344
+ # a spritesheet. The image with index 0 will be the top left sprite, and
345
+ # the following indices raise first from left to right and then from top
346
+ # to bottom.
347
+ # Parameters:
348
+ # [id] A string or symbol representing the path to the image. See +img+
349
+ # for details.
350
+ # [sprite_cols] Number of columns in the spritesheet.
351
+ # [sprite_rows] Number of rows in the spritesheet.
352
+ # [global] Set to true if you want to keep the image in memory until the
353
+ # game execution is finished. If false, the image will be
354
+ # released when you call +clear+.
355
+ # [ext] The extension of the file being loaded. Specify only if it is
356
+ # other than ".png".
191
357
  def self.imgs id, sprite_cols, sprite_rows, global = false, ext = ".png"
192
358
  if global; a = @@global_imgs; else; a = @@imgs; end
193
359
  return a[id] if a[id]
@@ -196,6 +362,21 @@ module AGL
196
362
  a[id] = imgs
197
363
  end
198
364
 
365
+ # Returns an array of <code>Gosu::Image</code> objects, using the image as
366
+ # a tileset. Works the same as +imgs+, except you must provide the tile
367
+ # size instead of the number of columns and rows, and that the images will
368
+ # be loaded as tileable.
369
+ # Parameters:
370
+ # [id] A string or symbol representing the path to the image. It must be
371
+ # specified the same way as in +img+, but the base directory is
372
+ # 'data/tileset'.
373
+ # [tile_width] Width of each tile, in pixels.
374
+ # [tile_height] Height of each tile, in pixels.
375
+ # [global] Set to true if you want to keep the image in memory until the
376
+ # game execution is finished. If false, the image will be
377
+ # released when you call +clear+.
378
+ # [ext] The extension of the file being loaded. Specify only if it is
379
+ # other than ".png".
199
380
  def self.tileset id, tile_width = 32, tile_height = 32, global = false, ext = ".png"
200
381
  if global; a = @@global_tilesets; else; a = @@tilesets; end
201
382
  return a[id] if a[id]
@@ -204,6 +385,17 @@ module AGL
204
385
  a[id] = tileset
205
386
  end
206
387
 
388
+ # Returns a <code>Gosu::Sample</code> object. This should be used for
389
+ # simple and short sound effects.
390
+ # Parameters:
391
+ # [id] A string or symbol representing the path to the sound. It must be
392
+ # specified the same way as in +img+, but the base directory is
393
+ # 'data/sound'.
394
+ # [global] Set to true if you want to keep the sound in memory until the
395
+ # game execution is finished. If false, the sound will be
396
+ # released when you call +clear+.
397
+ # [ext] The extension of the file being loaded. Specify only if it is
398
+ # other than ".wav".
207
399
  def self.sound id, global = false, ext = ".wav"
208
400
  if global; a = @@global_sounds; else; a = @@sounds; end
209
401
  return a[id] if a[id]
@@ -212,14 +404,39 @@ module AGL
212
404
  a[id] = sound
213
405
  end
214
406
 
407
+ # Returns a <code>Gosu::Song</code> object. This should be used for the
408
+ # background musics of your game.
409
+ # Parameters:
410
+ # [id] A string or symbol representing the path to the song. It must be
411
+ # specified the same way as in +img+, but the base directory is
412
+ # 'data/song'.
413
+ # [global] Set to true if you want to keep the song in memory until the
414
+ # game execution is finished. If false, the song will be released
415
+ # when you call +clear+.
416
+ # [ext] The extension of the file being loaded. Specify only if it is
417
+ # other than ".ogg".
215
418
  def self.song id, global = false, ext = ".ogg"
216
- if global; a = @@global_sounds; else; a = @@sounds; end
419
+ if global; a = @@global_songs; else; a = @@songs; end
217
420
  return a[id] if a[id]
218
421
  s = "data/song/" + id.to_s.split('_').join('/') + ext
219
422
  song = Gosu::Song.new Game.window, s
220
423
  a[id] = song
221
424
  end
222
425
 
426
+ # Returns a <code>Gosu::Font</code> object. Fonts are needed to draw text
427
+ # and used by MiniGL elements like buttons, text fields and TextHelper
428
+ # objects.
429
+ # Parameters:
430
+ # [id] A string or symbol representing the path to the song. It must be
431
+ # specified the same way as in +img+, but the base directory is
432
+ # 'data/font'.
433
+ # [size] The size of the font, in pixels. This will correspond,
434
+ # approximately, to the height of the tallest character when drawn.
435
+ # [global] Set to true if you want to keep the font in memory until the
436
+ # game execution is finished. If false, the font will be released
437
+ # when you call +clear+.
438
+ # [ext] The extension of the file being loaded. Specify only if it is
439
+ # other than ".ttf".
223
440
  def self.font id, size, global = true, ext = ".ttf"
224
441
  if global; a = @@global_fonts; else; a = @@fonts; end
225
442
  id_size = "#{id}_#{size}"
@@ -229,14 +446,12 @@ module AGL
229
446
  a[id_size] = font
230
447
  end
231
448
 
232
- # def self.text id
233
- # G.texts[G.lang][id.to_sym]
234
- # end
235
-
449
+ # Releases the memory used by all non-global resources.
236
450
  def self.clear
237
451
  @@imgs.clear
238
452
  @@tilesets.clear
239
453
  @@sounds.clear
454
+ @@songs.clear
240
455
  @@fonts.clear
241
456
  end
242
457
  end
data/lib/minigl/map.rb CHANGED
@@ -1,9 +1,28 @@
1
1
  require_relative 'global'
2
2
 
3
3
  module AGL
4
+ # This class provides easy control of a tile map, i.e., a map consisting of
5
+ # a grid of equally sized tiles. It also provides viewport control, through
6
+ # its camera property and methods.
4
7
  class Map
5
- attr_reader :tile_size, :size, :cam
8
+ # A Vector where x is the tile width and y is the tile height.
9
+ attr_reader :tile_size
6
10
 
11
+ # A Vector where x is the horizontal tile count and y the vertical count.
12
+ attr_reader :size
13
+
14
+ # A Rectangle representing the region of the map that is currently
15
+ # visible.
16
+ attr_reader :cam
17
+
18
+ # Creates a new map.
19
+ # Parameters:
20
+ # [t_w] The width of the tiles.
21
+ # [t_h] The height of the tiles.
22
+ # [t_x_count] The horizontal count of tiles in the map.
23
+ # [t_y_count] The vertical count of tiles in the map.
24
+ # [scr_w] Width of the viewport for the map.
25
+ # [scr_h] Height of the viewport for the map.
7
26
  def initialize t_w, t_h, t_x_count, t_y_count, scr_w = 800, scr_h = 600
8
27
  @tile_size = Vector.new t_w, t_h
9
28
  @size = Vector.new t_x_count, t_y_count
@@ -12,38 +31,79 @@ module AGL
12
31
  @max_y = t_y_count * t_h - scr_h
13
32
  end
14
33
 
34
+ # Returns a Vector with the total size of the map, in pixels (x for the
35
+ # width and y for the height).
15
36
  def get_absolute_size
16
37
  Vector.new(@tile_size.x * @size.x, @tile_size.y * @size.y)
17
38
  end
18
39
 
40
+ # Returns a Vector with the coordinates of the center of the map.
19
41
  def get_center
20
42
  Vector.new(@tile_size.x * @size.x / 2, @tile_size.y * @size.y / 2)
21
43
  end
22
44
 
45
+ # Returns the position in the screen corresponding to the given tile
46
+ # indices.
47
+ # Parameters:
48
+ # [map_x] The index of the tile in the horizontal direction. It must be in
49
+ # the interval <code>0..t_x_count</code>.
50
+ # [map_y] The index of the tile in the vertical direction. It must be in
51
+ # the interval <code>0..t_y_count</code>.
23
52
  def get_screen_pos map_x, map_y
24
53
  Vector.new(map_x * @tile_size.x - @cam.x, map_y * @tile_size.y - @cam.y)
25
54
  end
26
55
 
56
+ # Returns the tile in the map that corresponds to the given position in
57
+ # the screen, as a Vector, where x is the horizontal index and y the
58
+ # vertical index.
59
+ # Parameters:
60
+ # [scr_x] The x-coordinate in the screen.
61
+ # [scr_y] The y-coordinate in the screen.
27
62
  def get_map_pos scr_x, scr_y
28
63
  Vector.new((scr_x + @cam.x) / @tile_size.x, (scr_y + @cam.y) / @tile_size.y)
29
64
  end
30
65
 
66
+ # Verifies whether a tile is inside the map.
67
+ # Parameters:
68
+ # [v] A Vector representing the tile, with x as the horizontal index and
69
+ # y as the vertical index.
31
70
  def is_in_map v
32
71
  v.x >= 0 && v.y >= 0 && v.x < @size.x && v.y < @size.y
33
72
  end
34
73
 
74
+ # Sets the top left corner of the viewport to the given position of the
75
+ # map. Note that this is not the position in the screen.
76
+ # Parameters:
77
+ # [cam_x] The x-coordinate inside the map, in pixels (not a tile index).
78
+ # [cam_y] The y-coordinate inside the map, in pixels (not a tile index).
35
79
  def set_camera cam_x, cam_y
36
80
  @cam.x = cam_x
37
81
  @cam.y = cam_y
38
82
  set_bounds
39
83
  end
40
84
 
85
+ # Moves the viewport by the given amount of pixels.
86
+ # Parameters:
87
+ # [x] The amount of pixels to move horizontally. Negative values will
88
+ # cause the camera to move to the left.
89
+ # [y] The amount of pixels to move vertically. Negative values will cause
90
+ # the camera to move up.
41
91
  def move_camera x, y
42
92
  @cam.x += x
43
93
  @cam.y += y
44
94
  set_bounds
45
95
  end
46
96
 
97
+ # Iterates through the currently visible tiles, providing the horizontal
98
+ # tile index, the vertical tile index, the x-coordinate (in pixels) and
99
+ # the y-coordinate (in pixels), of each tile, in that order, to a given
100
+ # block of code.
101
+ #
102
+ # Example:
103
+ #
104
+ # map.foreach do |i, j, x, y|
105
+ # draw_tile tiles[i][j], x, y
106
+ # end
47
107
  def foreach
48
108
  for j in @min_vis_y..@max_vis_y
49
109
  for i in @min_vis_x..@max_vis_x
@@ -1,20 +1,67 @@
1
1
  require_relative 'global'
2
2
 
3
3
  module AGL
4
+ # Represents an object with a rectangular bounding box and the +passable+
5
+ # property. It is the simplest structure that can be passed as an element of
6
+ # the +obst+ array parameter of the +move+ method.
4
7
  class Block
5
- attr_reader :x, :y, :w, :h, :passable
8
+ # The x-coordinate of the top left corner of the bounding box.
9
+ attr_reader :x
6
10
 
11
+ # The y-coordinate of the top left corner of the bounding box.
12
+ attr_reader :y
13
+
14
+ # The width of the bounding box.
15
+ attr_reader :w
16
+
17
+ # The height of the bounding box.
18
+ attr_reader :h
19
+
20
+ # Whether a moving object can pass through this block when coming from
21
+ # below. This is a common feature of platforms in platform games.
22
+ attr_reader :passable
23
+
24
+ # Creates a new block.
25
+ # Parameters:
26
+ # [x] The x-coordinate of the top left corner of the bounding box.
27
+ # [y] The y-coordinate of the top left corner of the bounding box.
28
+ # [w] The width of the bounding box.
29
+ # [h] The height of the bounding box.
30
+ # [passable] Whether a moving object can pass through this block when
31
+ # coming from below. This is a common feature of platforms in platform
32
+ # games.
7
33
  def initialize x, y, w, h, passable
8
34
  @x = x; @y = y; @w = w; @h = h
9
35
  @passable = passable
10
36
  end
11
37
 
38
+ # Returns the bounding box of this block as a Rectangle.
12
39
  def bounds
13
40
  Rectangle.new @x, @y, @w, @h
14
41
  end
15
42
  end
16
43
 
44
+ # Represents a ramp, i.e., an inclined structure which allows walking over
45
+ # it while automatically going up or down. It can be imagined as a right
46
+ # triangle, with a side parallel to the x axis and another one parallel to
47
+ # the y axis. You must provide instances of this class (or derived classes)
48
+ # to the +ramps+ array parameter of the +move+ method.
17
49
  class Ramp
50
+ # Creates a new ramp.
51
+ # Parameters:
52
+ # [x] The x-coordinate of the top left corner of a rectangle that
53
+ # completely (and precisely) encloses the ramp (thought of as a right
54
+ # triangle).
55
+ # [y] The y-coordinate of the top left corner of the rectangle described
56
+ # above.
57
+ # [w] The width of the ramp (which corresponds to the width of the
58
+ # rectangle described above).
59
+ # [h] The height of the ramp (which corresponds to the height of the
60
+ # rectangle described above, and to the difference between the lowest
61
+ # point of the ramp, where it usually meets the floor, and the
62
+ # highest).
63
+ # [left] Whether the height of the ramp increases from left to right. Use
64
+ # +false+ for a ramp that goes down from left to right.
18
65
  def initialize x, y, w, h, left
19
66
  @x = x
20
67
  @y = y
@@ -23,6 +70,24 @@ module AGL
23
70
  @left = left
24
71
  end
25
72
 
73
+ # Checks if an object is in contact with this ramp (standing over it).
74
+ # Parameters:
75
+ # [obj] The object to check contact with. It must have the +x+, +y+, +w+
76
+ # and +h+ accessible attributes determining its bounding box.
77
+ def contact? obj
78
+ obj.x.round(6) == get_x(obj).round(6) && obj.y.round(6) == get_y(obj).round(6)
79
+ end
80
+
81
+ # Checks if an object is intersecting this ramp (inside the corresponding
82
+ # right triangle and at the floor level or above).
83
+ # Parameters:
84
+ # [obj] The object to check intersection with. It must have the +x+, +y+,
85
+ # +w+ and +h+ accessible attributes determining its bounding box.
86
+ def intersects obj
87
+ obj.x + obj.w > @x && obj.x < @x + @w && obj.y > get_y(obj) && obj.y <= @y + @h - obj.h
88
+ end
89
+
90
+ # :nodoc:
26
91
  def can_collide? obj
27
92
  @can_collide = (obj.speed.y >= 0 and not intersects(obj))
28
93
  end
@@ -46,14 +111,6 @@ module AGL
46
111
  end
47
112
  end
48
113
 
49
- def contact? obj
50
- obj.x.round(6) == get_x(obj).round(6) && obj.y.round(6) == get_y(obj).round(6)
51
- end
52
-
53
- def intersects obj
54
- obj.x + obj.w > @x && obj.x < @x + @w && obj.y > get_y(obj) && obj.y <= @y + @h - obj.h
55
- end
56
-
57
114
  def get_x obj
58
115
  return @x + (1.0 * (@y + @h - obj.y - obj.h) * @w / @h) - obj.w if @left
59
116
  @x + (1.0 * (obj.y + obj.h - @y) * @w / @h)
@@ -67,14 +124,66 @@ module AGL
67
124
  end
68
125
  end
69
126
 
127
+ # This module provides objects with physical properties and methods for
128
+ # moving. It allows moving with or without collision checking (based on
129
+ # rectangular bounding boxes), including a method to behave as an elevator,
130
+ # affecting other objects' positions as it moves.
70
131
  module Movement
71
- attr_reader :speed, :w, :h, :passable, :top, :bottom, :left, :right
72
- attr_accessor :x, :y, :stored_forces
73
-
132
+ # A Vector with the current speed of the object (x: horizontal component,
133
+ # y: vertical component).
134
+ attr_reader :speed
135
+
136
+ # Width of the bounding box.
137
+ attr_reader :w
138
+
139
+ # Height of the bounding box.
140
+ attr_reader :h
141
+
142
+ # Whether a moving object can pass through this block when coming from
143
+ # below. This is a common feature of platforms in platform games.
144
+ attr_reader :passable
145
+
146
+ # The object that is making contact with this from above. If there's no
147
+ # contact, returns +nil+.
148
+ attr_reader :top
149
+
150
+ # The object that is making contact with this from below. If there's no
151
+ # contact, returns +nil+.
152
+ attr_reader :bottom
153
+
154
+ # The object that is making contact with this from the left. If there's no
155
+ # contact, returns +nil+.
156
+ attr_reader :left
157
+
158
+ # The object that is making contact with this from the right. If there's
159
+ # no contact, returns +nil+.
160
+ attr_reader :right
161
+
162
+ # The x-coordinate of the top left corner of the bounding box.
163
+ attr_accessor :x
164
+
165
+ # The y-coordinate of the top left corner of the bounding box.
166
+ attr_accessor :y
167
+
168
+ # A Vector with the horizontal and vertical components of a force that
169
+ # be applied in the next time +move+ is called.
170
+ attr_accessor :stored_forces
171
+
172
+ # Returns the bounding box as a Rectangle.
74
173
  def bounds
75
174
  Rectangle.new @x, @y, @w, @h
76
175
  end
77
-
176
+
177
+ # Moves this object, based on the forces being applied to it, and
178
+ # performing collision checking.
179
+ # Parameters:
180
+ # [forces] A Vector where x is the horizontal component of the resulting
181
+ # force and y is the vertical component.
182
+ # [obst] An array of obstacles to be considered in the collision checking.
183
+ # Obstacles must be instances of Block (or derived classes), or
184
+ # objects that <code>include Movement</code>.
185
+ # [ramps] An array of ramps to be considered in the collision checking.
186
+ # Ramps must be instances of Ramp (or derived classes).
78
187
  def move forces, obst, ramps
79
188
  forces.x += Game.gravity.x; forces.y += Game.gravity.y
80
189
  forces.x += @stored_forces.x; forces.y += @stored_forces.y
@@ -173,7 +282,17 @@ module AGL
173
282
  end
174
283
  check_contact obst, ramps
175
284
  end
176
-
285
+
286
+ # Moves this object as an elevator (i.e., potentially carrying other
287
+ # objects) towards a given point.
288
+ # Parameters:
289
+ # [aim] A Vector specifying where the object will move to.
290
+ # [speed] The constant speed at which the object will move. This must be
291
+ # provided as a scalar, not a vector.
292
+ # [obstacles] An array of obstacles to be considered in the collision
293
+ # checking, and carried along when colliding from above.
294
+ # Obstacles must be instances of Block (or derived classes),
295
+ # or objects that <code>include Movement</code>.
177
296
  def move_carrying aim, speed, obstacles
178
297
  x_d = aim.x - @x; y_d = aim.y - @y
179
298
  distance = Math.sqrt(x_d**2 + y_d**2)
@@ -206,7 +325,13 @@ module AGL
206
325
 
207
326
  passengers.each do |p| p.y = @y - p.h end
208
327
  end
209
-
328
+
329
+ # Moves this object, without performing any collision checking, towards
330
+ # the specified point.
331
+ # Parameters:
332
+ # [aim] A Vector specifying where the object will move to.
333
+ # [speed] The constant speed at which the object will move. This must be
334
+ # provided as a scalar, not a vector.
210
335
  def move_free aim, speed
211
336
  x_d = aim.x - @x; y_d = aim.y - @y
212
337
  distance = Math.sqrt(x_d**2 + y_d**2)
@@ -227,7 +352,24 @@ module AGL
227
352
  @y += @speed.y
228
353
  end
229
354
  end
230
-
355
+
356
+ # Causes the object to move in cycles across multiple given points (the
357
+ # method must be called repeatedly, and it returns the value that must be
358
+ # provided to +cur_point+ after the first call). If obstacles are
359
+ # provided, it will behave as an elevator (as in +move_carrying+).
360
+ # Parameters:
361
+ # [points] An array of Vectors representing the path that the object will
362
+ # perform.
363
+ # [cur_point] The index of the point in the path that the object is
364
+ # currently moving to. In the first call, it is a good idea to
365
+ # provide 0, while in the subsequent calls, you must provide
366
+ # the return value of this method.
367
+ # [speed] The constant speed at which the object will move. This must be
368
+ # provided as a scalar, not a vector.
369
+ # [obstacles] An array of obstacles to be considered in the collision
370
+ # checking, and carried along when colliding from above.
371
+ # Obstacles must be instances of Block (or derived classes),
372
+ # or objects that <code>include Movement</code>.
231
373
  def cycle points, cur_point, speed, obstacles = nil
232
374
  if obstacles
233
375
  move_carrying points[cur_point], speed, obstacles
data/lib/minigl/text.rb CHANGED
@@ -1,10 +1,32 @@
1
1
  module AGL
2
+ # This class provides methods for easily drawing one or multiple lines of
3
+ # text, with control over the text alignment and coloring.
2
4
  class TextHelper
5
+ # Creates a TextHelper.
6
+ # Parameters:
7
+ # [font] A <code>Gosu::Font</code> that will be used to draw the text.
8
+ # [line_spacing] When drawing multiple lines, the distance, in pixels,
9
+ # between each line.
3
10
  def initialize font, line_spacing = 0
4
11
  @font = font
5
12
  @line_spacing = line_spacing
6
13
  end
7
-
14
+
15
+ # Draws a single line of text.
16
+ # Parameters:
17
+ # [text] The text to be drawn. No line breaks are allowed.
18
+ # [x] The horizontal reference for drawing the text. If +mode+ is +:left+,
19
+ # all text will be drawn from this point to the right; if +mode+ is
20
+ # +:right+, all text will be drawn from this point to the left; and if
21
+ # +mode+ is +:center+, the text will be equally distributed to the
22
+ # left and to the right of this point.
23
+ # [y] The vertical reference for drawing the text. All text will be drawn
24
+ # from this point down.
25
+ # [mode] The alignment of the text. Valid values are +:left+, +:right+ and
26
+ # +:center+.
27
+ # [color] The color of the text, in hexadecimal RRGGBB format.
28
+ # [alpha] The opacity of the text. Valid values vary from 0 (fully
29
+ # transparent) to 255 (fully opaque).
8
30
  def write_line text, x, y, mode = :left, color = 0, alpha = 0xff
9
31
  color = (alpha << 24) | color
10
32
  rel =
@@ -16,7 +38,23 @@ module AGL
16
38
  end
17
39
  @font.draw_rel text, x, y, 0, rel, 0, 1, 1, color
18
40
  end
19
-
41
+
42
+ # Draws text, breaking lines when needed and when explicitly caused by the
43
+ # "\n" character.
44
+ # Parameters:
45
+ # [text] The text to be drawn. Line breaks are allowed.
46
+ # [x] The horizontal reference for drawing the text. Works like in
47
+ # +write_line+ for the +:left+, +:right+ and +:center+ modes. For the
48
+ # +:justified+ mode, works the same as for +:left+.
49
+ # [y] The vertical reference for drawing the text. All text will be drawn
50
+ # from this point down.
51
+ # [width] The maximum width for the lines of text. Line is broken when
52
+ # this width is exceeded.
53
+ # [mode] The alignment of the text. Valid values are +:left+, +:right+,
54
+ # +:center+ and +:justified+.
55
+ # [color] The color of the text, in hexadecimal RRGGBB format.
56
+ # [alpha] The opacity of the text. Valid values vary from 0 (fully
57
+ # transparent) to 255 (fully opaque).
20
58
  def write_breaking text, x, y, width, mode = :left, color = 0, alpha = 0xff
21
59
  color = (alpha << 24) | color
22
60
  text.split("\n").each do |p|
data/test/game.rb CHANGED
@@ -11,8 +11,8 @@ class MyGame < Gosu::Window
11
11
 
12
12
  @font = Res.font :font1, 20
13
13
  @writer = TextHelper.new @font, 5
14
- @btn = Button.new(10, 560, @font, "Test", :btn, 0x008000, false, 15, 5) {}
15
- @txt = TextField.new 10, 520, @font, :text, nil, 15, 5, 16, false, "", 0, 0x0000ff
14
+ @btn = Button.new(10, 560, @font, "Test", :btn, 0x008000) {}
15
+ @txt = TextField.new 10, 520, @font, :text, nil, 15, 5, 16, false, "", nil, 0, 0x0000ff
16
16
  end
17
17
 
18
18
  def needs_cursor?
@@ -25,6 +25,8 @@ class MyGame < Gosu::Window
25
25
  @obj1.x += 1 if KB.key_down? Gosu::KbRight
26
26
  @obj1.y += 1 if KB.key_held? Gosu::KbDown
27
27
  @obj1.x -= 1 if KB.key_down? Gosu::KbLeft
28
+ @btn.set_position rand(700), rand(550) if KB.key_pressed? Gosu::KbSpace
29
+ @txt.set_position rand(700), rand(550) if KB.key_pressed? Gosu::KbReturn
28
30
 
29
31
  Mouse.update
30
32
  if Mouse.double_click? :left
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minigl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor David Santos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-06 00:00:00.000000000 Z
11
+ date: 2014-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gosu