adventure_rl 0.0.1.pre.ld42

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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +47 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +31 -0
  8. data/Rakefile +11 -0
  9. data/adventure_rl.gemspec +48 -0
  10. data/bin/console +7 -0
  11. data/bin/mkaudio +196 -0
  12. data/bin/mkclip +223 -0
  13. data/bin/rdoc +9 -0
  14. data/bin/setup +8 -0
  15. data/bin/vimall +5 -0
  16. data/doc/Mask.md +183 -0
  17. data/doc/Point.md +95 -0
  18. data/doc/Window.md +139 -0
  19. data/lib/AdventureRL/Animation.rb +63 -0
  20. data/lib/AdventureRL/Audio.rb +75 -0
  21. data/lib/AdventureRL/AudioPlayer.rb +65 -0
  22. data/lib/AdventureRL/Button.rb +51 -0
  23. data/lib/AdventureRL/Clip.rb +91 -0
  24. data/lib/AdventureRL/ClipPlayer.rb +187 -0
  25. data/lib/AdventureRL/Deltatime.rb +51 -0
  26. data/lib/AdventureRL/EventHandlers/Buttons.rb +225 -0
  27. data/lib/AdventureRL/EventHandlers/EventHandler.rb +62 -0
  28. data/lib/AdventureRL/EventHandlers/MouseButtons.rb +142 -0
  29. data/lib/AdventureRL/Events/Event.rb +69 -0
  30. data/lib/AdventureRL/Events/Mouse.rb +60 -0
  31. data/lib/AdventureRL/FileGroup.rb +100 -0
  32. data/lib/AdventureRL/FileGroupPlayer.rb +226 -0
  33. data/lib/AdventureRL/Helpers/Error.rb +68 -0
  34. data/lib/AdventureRL/Helpers/MethodHelper.rb +20 -0
  35. data/lib/AdventureRL/Helpers/PipeMethods.rb +26 -0
  36. data/lib/AdventureRL/Image.rb +77 -0
  37. data/lib/AdventureRL/Layer.rb +273 -0
  38. data/lib/AdventureRL/Mask.rb +462 -0
  39. data/lib/AdventureRL/Menu.rb +92 -0
  40. data/lib/AdventureRL/Modifiers/Gravity.rb +60 -0
  41. data/lib/AdventureRL/Modifiers/Inventory.rb +104 -0
  42. data/lib/AdventureRL/Modifiers/Pusher.rb +61 -0
  43. data/lib/AdventureRL/Modifiers/Solid.rb +302 -0
  44. data/lib/AdventureRL/Modifiers/Velocity.rb +163 -0
  45. data/lib/AdventureRL/Point.rb +188 -0
  46. data/lib/AdventureRL/Quadtree.rb +237 -0
  47. data/lib/AdventureRL/Rectangle.rb +62 -0
  48. data/lib/AdventureRL/Settings.rb +80 -0
  49. data/lib/AdventureRL/SolidsManager.rb +170 -0
  50. data/lib/AdventureRL/Textbox.rb +195 -0
  51. data/lib/AdventureRL/TimingHandler.rb +225 -0
  52. data/lib/AdventureRL/Window.rb +152 -0
  53. data/lib/AdventureRL/misc/extensions.rb +80 -0
  54. data/lib/AdventureRL/misc/require_files.rb +45 -0
  55. data/lib/AdventureRL/version.rb +3 -0
  56. data/lib/adventure_rl.rb +22 -0
  57. data/lib/default_settings.yml +20 -0
  58. data/vimrc +4 -0
  59. metadata +237 -0
data/doc/Mask.md ADDED
@@ -0,0 +1,183 @@
1
+ # `AdventureRL::Mask`
2
+ The mask is a two dimensional area.
3
+ It has a `position`, `size`, and `origin`.
4
+
5
+ The mask should make collision checking and the like easier.
6
+
7
+ __Table of Contents__
8
+ - [Methods](#methods)
9
+ - [`initialize`](#initialize)
10
+ - [`assign_to`](#assign_to)
11
+ - [`get_mask`](#get_mask)
12
+ - [`get_point`](#get_point)
13
+ - [`get_position`](#get_position)
14
+ - [`get_size`](#get_size)
15
+ - [`get_origin`](#get_origin)
16
+ - [`get_corner`](#get_corner)
17
+ - [`get_side`](#get_side)
18
+ - [`get_sides`](#get_sides)
19
+ - [`get_center`](#get_center)
20
+ - [`collides_with?`](#collides_with)
21
+
22
+ ## Methods
23
+ ### `initialize`
24
+ ```ruby
25
+ def initialize args = {}
26
+ end
27
+ ```
28
+ The mask has the following attributes,
29
+ which should be passed as a hash on initialization:
30
+
31
+ - `position`
32
+ The starting position of the mask, relative to its `origin`.
33
+ This can be a hash with the keys `x` and `y`, or a `AdventureRL::Point`.
34
+
35
+ - `size`
36
+ The size of the mask. It is passed as a hash with the keys
37
+ `width` and `height`.
38
+
39
+ - `origin`
40
+ The origin of the mask is where the `position` is located on the mask.
41
+ It is passed as a hash with the keys `x` and `y`, and their values can be:
42
+ - for `:x` - `:left`
43
+ - for `:x` - `:right`
44
+ - for `:y` - `:top`
45
+ - for `:y` - `:bottom`
46
+ - for `:x` or `:y` - `center`
47
+
48
+ Usually, if you only use the mask's methods, the origin position should be
49
+ irrelevant to you, and you can ommit it. The only method which's output
50
+ it effects, is `#get_position`, as it will give you the point you initially
51
+ passed, which is the point where the origin position is.
52
+
53
+ - `assign_to`
54
+ You can pass any object as `assign_to`'s value. This will make it possible
55
+ for the assigned object to have access to all of mask's methods directly.
56
+ This defines a `#method_missing` method which pipes any missing methods to
57
+ the mask. So you could _not_ create a reference to the mask _(no variable)_
58
+ and just initialize the mask, assign your object, and it will have access
59
+ to all of its mask's methods.
60
+
61
+ If any or all of the above values are not passed, the defaults are used:
62
+ ```ruby
63
+ {
64
+ position: {
65
+ x: 0,
66
+ y: 0
67
+ },
68
+ size: {
69
+ width: 64,
70
+ height: 64
71
+ },
72
+ origin: {
73
+ x: :left,
74
+ y: :top
75
+ },
76
+ assign_to: nil
77
+ }
78
+ ```
79
+
80
+ ### `assign_to`
81
+ ```ruby
82
+ def assign_to object
83
+ end
84
+ ```
85
+ Assigns the object to the mask. The same method is called if you pass
86
+ the `:assign_to` key with a object in `#initialize`.
87
+
88
+ ### `get_mask`
89
+ ```ruby
90
+ def get_mask
91
+ end
92
+ ```
93
+ Returns self. Objects which this mask was assigned to _(see #initialize)_
94
+ have a way of getting the actual mask with this method.
95
+
96
+ ### `get_point`
97
+ ```ruby
98
+ def get_point
99
+ end
100
+ ```
101
+ Returns the point with the positions passed to it initially.
102
+
103
+ ### `get_position`
104
+ ```ruby
105
+ def get_position target = :all
106
+ end
107
+ ```
108
+ Returns its position, same as `get_point.get_position`.
109
+
110
+ ### `get_size`
111
+ ```ruby
112
+ def get_size target = :all
113
+ end
114
+ ```
115
+ Returns its size, similar to `#get_position`,
116
+ only with its sides, `width` and `height`.
117
+
118
+ ### `get_origin`
119
+ ```ruby
120
+ def get_origin
121
+ end
122
+ ```
123
+ Returns its size, similar to `#get_position`,
124
+ only with its origin axes, `x` and `y`.
125
+
126
+ ### `get_corner`
127
+ ```ruby
128
+ def get_corner side_x, side_y
129
+ end
130
+ ```
131
+ Returns a point with the corner position of the given `side_x` and `side_y`.
132
+ For example:
133
+ ```ruby
134
+ mask = AdventureRL::Mask.new( ... )
135
+ mask.get_corner :left, :top # => Returns point with top-left corner position.
136
+ mask.get_corner :right, :bottom # => Returns point with botton-right corner position.
137
+ mask.get_corner :center, :center # => Returns center point - same
138
+ ```
139
+
140
+ ### `get_side`
141
+ ```ruby
142
+ def get_side target
143
+ end
144
+ ```
145
+ Returns an integer of the axis for the given target side.
146
+ For example:
147
+ ```ruby
148
+ mask = AdventureRL::Mask.new( ... )
149
+ mask.get_side :left # => Returns x axis of the left mask edge.
150
+ mask.get_side :top # => Returns y axis of the top mask edge.
151
+ ```
152
+
153
+ ### `get_sides`
154
+ ```ruby
155
+ def get_sides
156
+ end
157
+ ```
158
+ Returns a hash with all side positions. Example return value:
159
+ ```ruby
160
+ {
161
+ left: 10,
162
+ right: 60,
163
+ top: 20,
164
+ bottom: 70
165
+ }
166
+ ```
167
+
168
+ ### `get_center`
169
+ ```ruby
170
+ def get_center target = :all
171
+ end
172
+ ```
173
+ If target is `:all`, returns a new point with the center position of the mask.
174
+ Otherwise, if target is `:x` or `:y`, returns an integer representing
175
+ the center of the target's axis.
176
+
177
+ ### `collides_with?`
178
+ ```ruby
179
+ def collides_with? point_or_mask
180
+ end
181
+ ```
182
+ This method checks if it is in collision / overlapping with
183
+ a `AdventureRL::Point` or `Adventure::Mask`; the argument accepts both.
data/doc/Point.md ADDED
@@ -0,0 +1,95 @@
1
+ # `AdventureRL::Point`
2
+ A point is a two dimensional vector.
3
+ it has an `x` axis and a `y` axis.
4
+ It should be pretty straight-forward and self-explanatory.
5
+
6
+ __Table of Contents__
7
+ - [Methods](#methods)
8
+ - [`initialize`](#initialize)
9
+ - [`assign_to`](#assign_to)
10
+ - [`get_point`](#get_point)
11
+ - [`x`](#x)
12
+ - [`y`](#y)
13
+ - [`get_position`](#get_position)
14
+ - [`set_position`](#set_position)
15
+ - [`collides_with?`](#collides_with)
16
+ - [`keys`](#keys)
17
+ - [`values`](#values)
18
+
19
+ ## Methods
20
+ ### `initialize`
21
+ ```ruby
22
+ def initialize x, y, args = {}
23
+ end
24
+ ```
25
+ Create a new point with `x` and `y` axes.
26
+ You can pass the key `:assign_to` with the value of an object with args
27
+ to make all point methods available directly through the object.
28
+
29
+ ### `assign_to`
30
+ ```ruby
31
+ def assign_to object
32
+ end
33
+ ```
34
+ Assigns the object to the point.
35
+ Same as using the key `:assign_to` in `#initialize`.
36
+
37
+ ### `get_point`
38
+ ```ruby
39
+ def get_point
40
+ end
41
+ ```
42
+ Returns self.
43
+ Useful for using from objects where the point was assigned to them.
44
+
45
+ ### `x`
46
+ ```ruby
47
+ def x
48
+ end
49
+ ```
50
+ Returns the integer for its `x` axis.
51
+
52
+ ### `y`
53
+ ```ruby
54
+ def y
55
+ end
56
+ ```
57
+ Returns the integer for its `y` axis.
58
+
59
+ ### `get_position`
60
+ ```ruby
61
+ def get_position target = :all
62
+ end
63
+ ```
64
+ Returns either both axes as a hash if target is `:all` or is ommited,
65
+ or returns the value of target's axis.
66
+
67
+ ### `set_position`
68
+ ```ruby
69
+ def set_position
70
+ end
71
+ ```
72
+
73
+ ### `collides_with?`
74
+ ```ruby
75
+ def collides_with? point_or_mask
76
+ end
77
+ ```
78
+ This method checks if it is in collision / overlapping with
79
+ a `AdventureRL::Point` or `Adventure::Mask`; the argument accepts both.
80
+
81
+ ### `keys`
82
+ ```ruby
83
+ def keys
84
+ end
85
+ ```
86
+ Returns the symbols `:x` and `:y` in an array, respectively.
87
+ Based on `Hash#keys`.
88
+
89
+ ### `values`
90
+ ```ruby
91
+ def values
92
+ end
93
+ ```
94
+ Returns the `:x` and `:y` axes in an array, respectively.
95
+ Based on `Hash#values`.
data/doc/Window.md ADDED
@@ -0,0 +1,139 @@
1
+ # `AdventureRL::Window`
2
+ This class inherits from `Gosu::Window`.
3
+ It is responsible for the actual window updating and drawing.
4
+
5
+ __Table of Contents__
6
+ - [Methods](#methods)
7
+ - [`initialize`](#initialize)
8
+ - [`setup`](#setup)
9
+ - [`get_fps`](#get_fps)
10
+ - [`get_deltatime`](#get_deltatime)
11
+ - [`get_tick`](#get_tick)
12
+ - [Gosu Methods](#gosu-methods)
13
+ - [`update` and `draw`](#update-and-draw)
14
+ - [Example Window Initialization](#example-window-initialization)
15
+
16
+ ## Methods
17
+ ### `initialize`
18
+ ```ruby
19
+ def initialize args = {}
20
+ end
21
+ ```
22
+ Unlike with Gosu, the `#initialize` method should _not_ be overwritten.
23
+ Instead, define the method `#setup`, which will be called after `#initialize`.
24
+ You should pass a hash of settings to `#initialize`,
25
+ which will also be passed to `#setup`, if `#setup` takes an argument.
26
+ An example hash for `args`:
27
+ ```ruby
28
+ AdventureRL::Window.new({
29
+ size: {
30
+ width: 960,
31
+ height: 540
32
+ },
33
+ caption: 'My AdventureRL Game!'
34
+ })
35
+ ```
36
+ You can pass anything you want in the hash and use it in your `#setup` method.
37
+ For any mandatory hashes you don't pass _(such as `:size`)_ the defaults
38
+ will be used, which is defined in the gem's root in `default_settings.yml`.
39
+
40
+ ### `setup`
41
+ ```ruby
42
+ def setup args
43
+ end
44
+ ```
45
+ As mentioned above, this method is supposed to be overwritten by the developer.
46
+ It will be called after `#initialize` has finished.
47
+ You do not have to define it with taking an argument, but if you don't
48
+ the arguments you passed to `#initialize` (`.new`) will not be available to you
49
+ in `#setup`.
50
+
51
+ ### `get_fps`
52
+ ```ruby
53
+ def get_fps
54
+ end
55
+ ```
56
+ Returns current frame rate. This is just a wrapper method for `Gosu.fps`.
57
+ I decided to add this just to follow the design pattern with `get_*` methods.
58
+
59
+ ### `get_deltatime`
60
+ ```ruby
61
+ def get_deltatime
62
+ end
63
+ ```
64
+ This method returns a float, representing the time difference in seconds
65
+ to the last call to update. Using deltatime you can prevent your game from
66
+ running at a different speed on slower computers.
67
+ Read more about __deltatime__ at [gamedev.stackexchange.com][gamedev-deltatime-url].
68
+
69
+ ### `get_tick`
70
+ ```ruby
71
+ def get_tick
72
+ end
73
+ ```
74
+ This method returns an integer, which is increased by one
75
+ everytime `#update` is called. __*__
76
+
77
+ > __Attention__
78
+ > Methods marked with an asterisk _(*)_ are only available
79
+ > if you call `super` at the end of `#update`.
80
+
81
+ ## Gosu Methods
82
+ The following methods come from the gosu gem's `Gosu::Window` class,
83
+ as `AdventureRL::Window` inherits from `Gosu::Window`,
84
+ all of gosu's window methods are available to you.
85
+ Here are some examples of useful/necessary `Gosu::Window` methods.
86
+
87
+ ### `update` and `draw`
88
+ ```ruby
89
+ def update
90
+ # This method is called every frame.
91
+ # You're supposed to do handle any calculations your game does here,
92
+ # such as player movement, mouse clicks, etc.
93
+ end
94
+ def draw
95
+ # This method is also called every frame, after the #update method.
96
+ # Here, you are supposed to handle the drawing of your images, textures, etc.
97
+ end
98
+ ```
99
+ You should call `super` at the end of `#update`.
100
+ If you don't, you will not be able to use a lot of methods
101
+ and features provided by AdventureRL, such as `#get_deltatime` or `#get_tick`.
102
+
103
+ Check out [Gosu's documentation][gosu-window-doc] for a list of available methods.
104
+
105
+ ## Example Window Initialization
106
+ ```ruby
107
+ class MyGame < AdventureRL::Window
108
+ def setup args
109
+ self.caption = 'I prefer this window title!'
110
+ @my_settings = AdventureRL::Settings.new 'path/to/my_settings.yml'
111
+ @font = Gosu::Font.new 24
112
+ # ...
113
+ end
114
+
115
+ private
116
+
117
+ def update
118
+ puts "Current tick: #{get_tick}" # Prints the current tick to stdout.
119
+ super # Call the parent's #update method to have access to a lot of useful methods.
120
+ end
121
+
122
+ def draw
123
+ center_point = get_center
124
+ @font.draw_rel(
125
+ "Delta-Time:\n#{get_deltatime}",
126
+ center_point.x, center_point.y, 0,
127
+ 0.5, 0.5, 1, 1,
128
+ 0xff_00ff00
129
+ )
130
+ end
131
+ end
132
+
133
+ my_game = MyGame.new
134
+ my_game.show # Actually open and render the window
135
+ # and start your game loops #update and #draw.
136
+ ```
137
+
138
+ [gamedev-deltatime-url]: https://gamedev.stackexchange.com/questions/1589/when-should-i-use-a-fixed-or-variable-time-step
139
+ [gosu-window-doc]: https://www.rubydoc.info/github/gosu/gosu/Gosu/Window
@@ -0,0 +1,63 @@
1
+ module AdventureRL
2
+ class Animation < Image
3
+ DEFAULT_SETTINGS = Settings.new(
4
+ files: ['DEFAULT_ANIMATION_FILE.png'],
5
+ intervals: [0.5] # Image switch intervals in seconds.
6
+ )
7
+
8
+ def initialize settings = {}
9
+ @settings = DEFAULT_SETTINGS.merge settings
10
+ image_settings = @settings.get
11
+ image_settings[:dont_create_image] = true
12
+ super image_settings
13
+ @images = get_images_from [@settings.get(:files)].flatten
14
+ @animation_intervals = [@settings.get(:intervals)].flatten
15
+ @timing_handler = TimingHandler.new
16
+ @timeout_id = :next_image_timeout
17
+ @current_image_index = -1
18
+ next_image
19
+ end
20
+
21
+ def update_animation
22
+ @timing_handler.update
23
+ end
24
+
25
+ # Call this (or #update_animation) every frame, to ensure that the animation is playing.
26
+ def update
27
+ update_animation
28
+ end
29
+
30
+ def next_image
31
+ @current_image_index += 1
32
+ @current_image_index = 0 if (@current_image_index >= @images.size)
33
+ @image = @images[@current_image_index]
34
+ set_timeout
35
+ end
36
+
37
+ def set_timeout
38
+ current_interval = get_current_interval
39
+ @timing_handler.set_timeout(
40
+ id: @timeout_id,
41
+ seconds: get_current_interval,
42
+ method: method(:next_image)
43
+ ) if (current_interval)
44
+ end
45
+
46
+ private
47
+
48
+ def get_images_from files
49
+ return files.map do |file|
50
+ next get_image_from(file)
51
+ end
52
+ end
53
+
54
+ def get_current_interval
55
+ intervals_size = @animation_intervals.size
56
+ if (@current_image_index < intervals_size)
57
+ return @animation_intervals[@current_image_index]
58
+ else
59
+ return @animation_intervals[@current_image_index - (intervals_size * (@current_image_index / intervals_size).floor)]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,75 @@
1
+ module AdventureRL
2
+ class Audio < FileGroup
3
+ AUDIO_FILENAME_REGEX = /\A\d+\.(flac|wav|ogg)\z/i
4
+ INTERNAL_DEFAULT_SETTINGS = Settings.new({
5
+ name: :audio_name,
6
+ directory: nil,
7
+ fps: 24,
8
+ volume: 1.0
9
+ })
10
+ @@default_settings = nil
11
+ @@root_directory = Pathname.new($0).dirname
12
+
13
+ class << self
14
+ # Set the root directory for the audio files directory.
15
+ # All settings 'directory' values will be relative to this.
16
+ # Defaults to the entry scripts (the script that was called, <tt>$0</tt>) directory.
17
+ # Pass either a String with the directory path, or an instance of Pathname.
18
+ def set_root_directory directory
19
+ directory = Pathname.new directory unless (directory.is_a? Pathname)
20
+ @@root_directory = Pathname.new directory
21
+ end
22
+ alias_method :root=, :set_root_directory
23
+
24
+ # Returns the currently set root audio files directory.
25
+ def get_root_directory
26
+ return @@root_directory
27
+ end
28
+ alias_method :root, :get_root_directory
29
+
30
+ # Set the default Settings.
31
+ # Pass either String to a YAML settings file,
32
+ # or a Hash with your default settings.
33
+ def set_default_settings settings
34
+ default_settings = nil
35
+ if ([String, Pathname].include? settings.class)
36
+ filepath = settings
37
+ filepath = Pathname.new filepath unless (filepath.is_a? Pathname)
38
+ if (filepath.absolute?)
39
+ default_settings = Settings.new filepath
40
+ else
41
+ if (File.file?(filepath))
42
+ default_settings = Settings.new filepath
43
+ else
44
+ default_settings = Settings.new get_root_directory.join(filepath)
45
+ end
46
+ end
47
+ elsif (settings.is_a? Hash)
48
+ default_settings = Settings.new settings
49
+ end
50
+ @@default_settings = default_settings
51
+ end
52
+ alias_method :default_settings=, :set_default_settings
53
+ end
54
+
55
+
56
+ # Initialize with either a path to a YAML settings file as a String,
57
+ # or a Hash containing your settings.
58
+ def initialize settings
59
+ super
60
+ end
61
+
62
+ private
63
+
64
+ # Returns this class' specific INTERNAL_DEFAULT_SETTINGS.
65
+ def get_default_settings
66
+ return INTERNAL_DEFAULT_SETTINGS.merge @@default_settings if (@@default_settings)
67
+ return INTERNAL_DEFAULT_SETTINGS
68
+ end
69
+
70
+ # Should return the regex which must match the filenames.
71
+ def get_filename_regex
72
+ return AUDIO_FILENAME_REGEX
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,65 @@
1
+ module AdventureRL
2
+ class AudioPlayer < FileGroupPlayer
3
+ # Default settings for AudioPlayer.
4
+ # Are superseded by settings passed to #new.
5
+ DEFAULT_SETTINGS = Settings.new({
6
+ speed: 1.0,
7
+ loop: false,
8
+ max_speed: 10.0
9
+ })
10
+
11
+ # Pass settings Hash or Settings as argument.
12
+ # Supersedes DEFAULT_SETTINGS.
13
+ def initialize settings = {}
14
+ super
15
+ end
16
+
17
+ # Returns the currently active Audio.
18
+ # Wrapper for FileGroupPlayer#get_filegroup
19
+ alias_method :get_audio, :get_filegroup
20
+
21
+ # Overwrite FileGroupPlayer#update to set
22
+ # a max speed limit. Don't play anymore once
23
+ # it it greater than the max speed.
24
+ # <tt>:max_speed</tt> can be passed to #new,
25
+ # to overwrite the default.
26
+ def update
27
+ return if (above_max_speed?)
28
+ super
29
+ end
30
+
31
+ private
32
+
33
+ # Returns true if the current playback speed is
34
+ # above the max speed limit.
35
+ def above_max_speed?
36
+ return get_speed > get_settings(:max_speed)
37
+ end
38
+
39
+ # (Stops the last audio file,) -- Gosu cannot stop a Gosu::Sample, and that's what we're using.
40
+ # Loads the new audio file <tt>file</tt>,
41
+ # and play it right away.
42
+ def load_file file
43
+ get_current_channel.stop if (get_current_channel)
44
+ sample = Gosu::Sample.new(file)
45
+ set_current_channel sample.play(
46
+ get_audio.get_settings(:volume),
47
+ @speed,
48
+ !:loop
49
+ )
50
+ end
51
+
52
+ # Returns this class' DEFAULT_SETTINGS.
53
+ def get_default_settings
54
+ return DEFAULT_SETTINGS
55
+ end
56
+
57
+ # Returns the current Gosu::Channel.
58
+ # Wrapper for FileGroupPlayer#get_current_file
59
+ alias_method :get_current_channel, :get_current_file
60
+
61
+ # Set a new current Gosu::Channel.
62
+ # Wrapper for FileGroupPlayer#set_current_file
63
+ alias_method :set_current_channel, :set_current_file
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ module AdventureRL
2
+ class Button < Textbox
3
+ DEFAULT_SETTINGS = Settings.new(
4
+ active_color: 0xff_cc8822,
5
+ hover_colow: 0xff_888888,
6
+ pressable: false,
7
+ click_on_mouse_up: false
8
+ )
9
+
10
+ def initialize settings = {}
11
+ @settings = DEFAULT_SETTINGS.merge settings
12
+ super @settings
13
+ @colors = {
14
+ active: @settings.get(:active_color),
15
+ hover: @settings.get(:hover_colow),
16
+ }
17
+ @pressable ||= @settings.get :pressable
18
+ @click_on_mouse_up ||= @settings.get :click_on_mouse_up
19
+ @click_on_mouse_up ||= false if (@pressable)
20
+ end
21
+
22
+ def get_menu
23
+ layer = get_layer
24
+ return layer if (layer.is_a? Menu)
25
+ return nil
26
+ end
27
+
28
+ def on_mouse_down
29
+ return if (is_pressable?)
30
+ set_color @colors[:active]
31
+ click if (!@click_on_mouse_up && methods.include?(:click))
32
+ end
33
+
34
+ def on_mouse_up
35
+ return if (is_pressable?)
36
+ reset_color
37
+ click if (@click_on_mouse_up && methods.include?(:click))
38
+ end
39
+
40
+ def on_mouse_press
41
+ return unless (is_pressable?)
42
+ set_temporary_color @colors[:active]
43
+ end
44
+
45
+ private
46
+
47
+ def is_pressable?
48
+ return !!@pressable
49
+ end
50
+ end
51
+ end