line-em-up 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,104 @@
1
+ class GeneralObject
2
+ attr_accessor :time_alive, :x, :y, :health
3
+ LEFT = 'left'
4
+ RIGHT = 'right'
5
+ SCROLLING_SPEED = 4
6
+ MAX_SPEED = 5
7
+
8
+ def get_image
9
+ Gosu::Image.new("#{MEDIA_DIRECTORY}/question.png")
10
+ end
11
+
12
+ def initialize(scale, x = nil, y = nil)
13
+ @scale = scale
14
+ @image = get_image
15
+ @x = x
16
+ @y = y
17
+ @time_alive = 0
18
+ # For objects that don't take damage, they'll never get hit by anything due to having 0 health
19
+ @health = 0
20
+ @image_width = @image.width * @scale
21
+ @image_height = @image.height * @scale
22
+ @image_size = @image_width * @image_height / 2
23
+ @image_radius = (@image_width + @image_height) / 4
24
+ end
25
+
26
+ # If using a different class for ZOrder than it has for model name, or if using subclass (from subclass or parent)
27
+ def get_draw_ordering
28
+ raise "Need to override via subclass: #{self.class.name}"
29
+ nil
30
+ end
31
+
32
+
33
+ def draw
34
+ # Will generate error if class name is not listed on ZOrder
35
+ @image.draw(@x - get_width / 2, @y - get_height / 2, get_draw_ordering, @scale, @scale)
36
+ # @image.draw(@xΩ - @image.width / 2, @y - @image.height / 2, get_draw_ordering)
37
+ end
38
+
39
+ def draw_rot
40
+ # draw_rot(x, y, z, angle, center_x = 0.5, center_y = 0.5, scale_x = 1, scale_y = 1, color = 0xff_ffffff, mode = :default) ⇒ void
41
+ @image.draw_rot(@x, @y, get_draw_ordering, @y, 0.5, 0.5, @scale, @scale)
42
+ end
43
+
44
+ def get_height
45
+ @image_height
46
+ end
47
+
48
+ def get_width
49
+ @image_width
50
+ end
51
+
52
+ def get_size
53
+ @image_size
54
+ end
55
+
56
+ def get_radius
57
+ @image_radius
58
+ end
59
+
60
+ def update width, height, mouse_x = nil, mouse_y = nil, player = nil
61
+ # Inherit, add logic, then call this to calculate whether it's still visible.
62
+ # @time_alive ||= 0 # Temp solution
63
+ @time_alive += 1
64
+ return is_on_screen?(width, height)
65
+ end
66
+
67
+ protected
68
+ def self.get_max_speed
69
+ self::MAX_SPEED
70
+ end
71
+
72
+ def is_on_screen? width, height
73
+ # @image.draw(@x - @image.width / 2, @y - @image.height / 2, ZOrder::Player)
74
+ @y > (0 - get_height) && @y < (height + get_height) && @x > (0 - get_width) && @x < (width + get_width)
75
+ end
76
+
77
+
78
+ def point_is_between_the_ys_of_the_line_segment?(point, a_point_on_polygon, trailing_point_on_polygon)
79
+ (a_point_on_polygon.y <= point.y && point.y < trailing_point_on_polygon.y) ||
80
+ (trailing_point_on_polygon.y <= point.y && point.y < a_point_on_polygon.y)
81
+ end
82
+
83
+ def ray_crosses_through_line_segment?(point, a_point_on_polygon, trailing_point_on_polygon)
84
+ (point.x < (trailing_point_on_polygon.x - a_point_on_polygon.x) * (point.y - a_point_on_polygon.y) /
85
+ (trailing_point_on_polygon.y - a_point_on_polygon.y) + a_point_on_polygon.x)
86
+ end
87
+
88
+ # def is_on_screen?
89
+ # # @image.draw(@x - get_width / 2, @y - get_height / 2, ZOrder::Player)
90
+ # @y > (0 - get_height) && @y < (HEIGHT + get_height) && @x > (0 - get_width) && @x < (WIDTH + get_width)
91
+ # end
92
+
93
+ def calc_angle(point1, point2)
94
+ bearing = (180/Math::PI)*Math.atan2(point1.y-point2.y, point2.x-point1.x)
95
+ return bearing
96
+ end
97
+
98
+ def calc_radian(point1, point2)
99
+ rdn = Math.atan2(point1.y-point2.y, point2.x-point1.x)
100
+ return rdn
101
+ end
102
+
103
+
104
+ end
@@ -0,0 +1,93 @@
1
+ require 'opengl'
2
+ class GLBackground
3
+ # Height map size
4
+ POINTS_X = 7
5
+ POINTS_Y = 7
6
+ # Scrolling speed
7
+ SCROLLS_PER_STEP = 50
8
+ # TEMP USING THIS, CANNOT FIND SCROLLING SPEED
9
+ SCROLLING_SPEED = 4
10
+
11
+ def initialize
12
+ @image = Gosu::Image.new("#{MEDIA_DIRECTORY}/earth.png", :tileable => true)
13
+ @scrolls = 0
14
+ @height_map = Array.new(POINTS_Y) { Array.new(POINTS_X) { rand } }
15
+ end
16
+
17
+ def scroll
18
+ @scrolls += 1
19
+ if @scrolls == SCROLLS_PER_STEP
20
+ @scrolls = 0
21
+ @height_map.shift
22
+ @height_map.push Array.new(POINTS_X) { rand }
23
+ end
24
+ end
25
+
26
+ def draw(z)
27
+ # gl will execute the given block in a clean OpenGL environment, then reset
28
+ # everything so Gosu's rendering can take place again.
29
+ Gosu.gl(z) { exec_gl }
30
+ end
31
+
32
+ private
33
+
34
+ include Gl
35
+
36
+ def exec_gl
37
+ glClearColor(0.0, 0.2, 0.5, 1.0)
38
+ glClearDepth(0)
39
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
40
+
41
+ # Get the name of the OpenGL texture the Image resides on, and the
42
+ # u/v coordinates of the rect it occupies.
43
+ # gl_tex_info can return nil if the image was too large to fit onto
44
+ # a single OpenGL texture and was internally split up.
45
+ info = @image.gl_tex_info
46
+ return unless info
47
+
48
+ # Pretty straightforward OpenGL code.
49
+
50
+ glDepthFunc(GL_GEQUAL)
51
+ glEnable(GL_DEPTH_TEST)
52
+ glEnable(GL_BLEND)
53
+
54
+ glMatrixMode(GL_PROJECTION)
55
+ glLoadIdentity
56
+ glFrustum(-0.10, 0.10, -0.075, 0.075, 1, 100)
57
+
58
+ glMatrixMode(GL_MODELVIEW)
59
+ glLoadIdentity
60
+ glTranslate(0, 0, -4)
61
+
62
+ glEnable(GL_TEXTURE_2D)
63
+ glBindTexture(GL_TEXTURE_2D, info.tex_name)
64
+
65
+ offs_y = 1.0 * @scrolls / SCROLLS_PER_STEP
66
+
67
+ 0.upto(POINTS_Y - 2) do |y|
68
+ 0.upto(POINTS_X - 2) do |x|
69
+ glBegin(GL_TRIANGLE_STRIP)
70
+ z = @height_map[y][x]
71
+ glColor4d(1, 1, 1, z)
72
+ glTexCoord2d(info.left, info.top)
73
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X-1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y-2), z)
74
+
75
+ z = @height_map[y+1][x]
76
+ glColor4d(1, 1, 1, z)
77
+ glTexCoord2d(info.left, info.bottom)
78
+ glVertex3d(-0.5 + (x - 0.0) / (POINTS_X-1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y-2), z)
79
+
80
+ z = @height_map[y][x + 1]
81
+ glColor4d(1, 1, 1, z)
82
+ glTexCoord2d(info.right, info.top)
83
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X-1), -0.5 + (y - offs_y - 0.0) / (POINTS_Y-2), z)
84
+
85
+ z = @height_map[y+1][x + 1]
86
+ glColor4d(1, 1, 1, z)
87
+ glTexCoord2d(info.right, info.bottom)
88
+ glVertex3d(-0.5 + (x + 1.0) / (POINTS_X-1), -0.5 + (y - offs_y + 1.0) / (POINTS_Y-2), z)
89
+ glEnd
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,242 @@
1
+ require_relative 'general_object.rb'
2
+
3
+ class GrapplingHook < GeneralObject
4
+ attr_reader :x, :y, :time_alive, :active, :angle, :end_point_x, :end_point_y
5
+ attr_accessor :active
6
+
7
+ COOLDOWN_DELAY = 45
8
+ # MAX_SPEED = 2
9
+ # STARTING_SPEED = 0.0
10
+ # INITIAL_DELAY = 2
11
+ # SPEED_INCREASE_FACTOR = 0.5
12
+ DAMAGE = 0
13
+
14
+ # MAX_CURSOR_FOLLOW = 15
15
+ MAX_SPEED = 20
16
+
17
+ def initialize(scale, object, mouse_x, mouse_y)
18
+ object.grapple_hook_cooldown_wait = COOLDOWN_DELAY
19
+ @scale = scale
20
+
21
+ # image = Magick::Image::read("#{MEDIA_DIRECTORY}/grappling_hook.png").first.resize(0.1)
22
+ # @image = Gosu::Image.new(image, :tileable => true)
23
+ @image = Gosu::Image.new("#{MEDIA_DIRECTORY}/grappling_hook.png")
24
+
25
+ # chain = Magick::Image::read("#{MEDIA_DIRECTORY}/chain.png").first.resize(0.1)
26
+ # @chain = Gosu::Image.new(chain, :tileable => true)
27
+ @chain = Gosu::Image.new("#{MEDIA_DIRECTORY}/chain.png")
28
+
29
+ @x = object.x - (@image.width / 2 * @scale)
30
+ @y = object.y
31
+ @end_point_x = mouse_x
32
+ @end_point_y = mouse_y
33
+
34
+ @active = true
35
+ @acquired_items = 0
36
+ start_point = OpenStruct.new(:x => @x, :y => @y)
37
+ end_point = OpenStruct.new(:x => @end_point_x, :y => @end_point_y)
38
+ @angle = calc_angle(start_point, end_point)
39
+ # @radian = calc_radian(start_point, end_point)
40
+ @image_angle = @angle
41
+ if @angle < 0
42
+ @angle = 360 - @angle.abs
43
+ end
44
+ @max_length = 7 * @scale
45
+ @max_length_counter = 0
46
+ @reached_end_point = false
47
+ @reached_back_to_player = false
48
+ @reached_max_length = false
49
+ @image_width = @image.width * @scale
50
+ @image_height = @image.height * @scale
51
+ @image_size = @image_width * @image_height / 2
52
+ @image_radius = (@image_width + @image_height) / 4
53
+ @current_speed = (self.class.get_max_speed * @scale).round
54
+ #Chain Image pre-calc
55
+ @chain_height = @chain.width * @scale
56
+ @chain_width = @chain.height * @scale
57
+ @chain_size = @chain_width * @chain_height / 2
58
+ @chain_radius = ((@chain_height + @chain_width) / 4) * @scale
59
+ end
60
+
61
+ def draw player
62
+
63
+ start_point = OpenStruct.new(:x => @x - get_width / 2, :y => @y - get_height / 2)
64
+ # end_point = OpenStruct.new(:x => player.x - (player.get_width / 2) + @chain.width / 2, :y => player.y - (player.get_height / 2))
65
+ end_point = OpenStruct.new(:x => player.x - (player.get_width / 2) + @chain.width, :y => player.y - (player.get_height / 2))
66
+ chain_angle = calc_angle(start_point, end_point)
67
+ if chain_angle < 0
68
+ chain_angle = 360 - chain_angle.abs
69
+ end
70
+
71
+ # @image.draw_rot(@x - get_width / 2 - get_height / 2, @y, ZOrder::Cursor, @image_angle, 0.5, 0.5, @scale, @scale)
72
+ # @image.draw_rot(@x - get_width / 2 - get_height / 2, @y, ZOrder::Cursor, (@angle - 90) * -1, 0.5, 0.5, @scale, @scale)
73
+ @image.draw_rot(@x, @y, ZOrder::Cursor, (@angle - 90) * -1, 0.5, 0.5, @scale, @scale)
74
+
75
+ chain_x = @x# - (get_width / 2) - (@chain.width / 2)
76
+ chain_y = @y# - (get_height / 2) - (@chain.height / 2)
77
+ loop_count = 0
78
+ max_loop_count = 250
79
+ # Subtracting 5, to get close to player coords
80
+ while Gosu.distance(chain_x, chain_y, player.x, player.y) > (@chain_radius + player.get_radius) && loop_count < max_loop_count
81
+ vx = 0
82
+ vy = 0
83
+ vx = 5 * Math.cos(chain_angle * Math::PI / 180)
84
+
85
+ vy = 5 * Math.sin(chain_angle * Math::PI / 180)
86
+ vy = vy * -1
87
+ # Because our y is inverted
88
+ # vy = vy - ((new_speed / 3) * 2)
89
+
90
+ chain_x = chain_x + vx
91
+ chain_y = chain_y + vy
92
+ @chain.draw(chain_x - @chain_width / 2, chain_y - @chain_height / 2, ZOrder::Cursor, @scale, @scale)
93
+ loop_count += 1
94
+ end
95
+ end
96
+
97
+ def get_chain_height
98
+ @chain_height
99
+ end
100
+
101
+ def get_chain_width
102
+ @chain_width
103
+ end
104
+
105
+ def get_chain_size
106
+ @chain_size
107
+ end
108
+
109
+ def get_chain_radius
110
+ @chain_radius
111
+ end
112
+
113
+
114
+ def active
115
+ @active# && @acquired_items == 0
116
+ end
117
+
118
+ def deactivate
119
+ @active = false
120
+ end
121
+
122
+ def activate
123
+ @active = true
124
+ end
125
+
126
+ # def self.get_max_cursor_follow scale
127
+
128
+ # end
129
+
130
+ def update width, height, player = nil
131
+ # puts "GRAP UPDATE:#{@reached_max_length} and #{@max_length_counter}"
132
+ if !@reached_end_point
133
+ current_angle = @angle
134
+ end
135
+ if @reached_end_point || @reached_max_length
136
+ # Recalc back to player
137
+ start_point = OpenStruct.new(:x => @x - get_width / 2, :y => @y - get_height / 2)
138
+ end_point = OpenStruct.new(:x => player.x - (player.get_width / 2), :y => player.y)
139
+ angle = calc_angle(start_point, end_point)
140
+ # radian = calc_radian(start_point, end_point)
141
+ if angle < 0
142
+ angle = 360 - angle.abs
143
+ end
144
+ current_angle = angle
145
+ end
146
+ # new_speed = 0
147
+ # if @time_alive > self.class.get_initial_delay
148
+ new_speed = @current_speed
149
+ new_speed = new_speed.fdiv(@acquired_items + 1) if @acquired_items > 0 && @reached_end_point
150
+ # new_speed = new_speed * @scale
151
+ # end
152
+
153
+ vx = 0
154
+ vy = 0
155
+ if new_speed > 0
156
+ vx = new_speed * Math.cos(current_angle * Math::PI / 180)
157
+
158
+ vy = new_speed * Math.sin(current_angle * Math::PI / 180)
159
+ vy = vy * -1
160
+ # Because our y is inverted
161
+ # vy = vy - ((new_speed / 3) * 2)
162
+ end
163
+
164
+ @x = @x + vx
165
+ @y = @y + vy
166
+
167
+ if !@reached_max_length
168
+ @reached_max_length = true if @max_length_counter >= @max_length
169
+ end
170
+
171
+ if !@reached_max_length
172
+ @max_length_counter += 1
173
+ # Not stopping on the mouse end_point
174
+ # @reached_end_point = true if Gosu.distance(@x - get_width / 2, @y - get_height / 2, @end_point_x, @end_point_y) < self.get_radius * @scale
175
+ end
176
+
177
+ if @reached_end_point || @reached_max_length
178
+ @reached_back_to_player = true if Gosu.distance(@x - get_width / 2, @y - get_height / 2, player.x, player.y) < (self.get_radius * @scale) * 1.2
179
+ end
180
+ # raise "HERE WE GO" if @reached_end_point
181
+
182
+ # After reached target, reverse the angle
183
+
184
+ return !@reached_back_to_player
185
+ end
186
+
187
+
188
+ def collect_pickups(player, pickups)
189
+ pickups.reject! do |pickup|
190
+ # puts "PICKUP GET RADIUS: #{pickup.get_radius}"
191
+ if Gosu.distance(@x, @y, pickup.x, pickup.y) < ((self.get_radius) + (pickup.get_radius)) * 1.2 && pickup.respond_to?(:collected_by_player)
192
+
193
+ pickup.collected_by_player(player)
194
+ if pickup.respond_to?(:get_points)
195
+ player.score += pickup.get_points
196
+ end
197
+ @acquired_items += 1
198
+ true
199
+ else
200
+ false
201
+ end
202
+ end
203
+ end
204
+
205
+
206
+
207
+ def hit_objects(objects)
208
+ drops = []
209
+ objects.each do |object|
210
+ if Gosu.distance(@x, @y, object.x, object.y) < self.get_radius * @scale
211
+ # Missile destroyed
212
+ # @y = -100
213
+ if object.respond_to?(:health) && object.respond_to?(:take_damage)
214
+ object.take_damage(DAMAGE)
215
+ end
216
+
217
+ if object.respond_to?(:is_alive) && !object.is_alive && object.respond_to?(:drops)
218
+ # puts "CALLING THE DROP"
219
+ object.drops.each do |drop|
220
+ drops << drop
221
+ end
222
+ end
223
+
224
+ end
225
+ end
226
+ return {drops: drops, point_value: 0}
227
+ end
228
+
229
+
230
+ # def hit_object(object)
231
+ # return_value = nil
232
+ # if Gosu.distance(@x, @y, object.x, object.y) < 30
233
+ # @y = -50
234
+ # return_value = DAMAGE
235
+ # else
236
+ # return_value = 0
237
+ # end
238
+ # return return_value
239
+ # end
240
+
241
+
242
+ end
@@ -0,0 +1,117 @@
1
+ # require_relative 'general_object.rb'
2
+ # class GuidableTorpedo < GeneralObject
3
+ # attr_reader :x, :y, :time_alive
4
+ # COOLDOWN_DELAY = 30
5
+ # MAX_SPEED = 25
6
+ # # STARTING_SPEED = 0.0
7
+ # # INITIAL_DELAY = 2
8
+ # # SPEED_INCREASE_FACTOR = 0.5
9
+ # DAMAGE = 0
10
+
11
+ # MAX_CURSOR_FOLLOW = 15
12
+
13
+ # def initialize(object)
14
+
15
+ # image = Magick::Image::read("#{MEDIA_DIRECTORY}/missile.png").first.resize(0.3)
16
+ # @image = Gosu::Image.new(image, :tileable => true)
17
+
18
+ # @x = object.get_x - (object.get_width / 2)
19
+ # @y = object.get_y
20
+
21
+ # # @x = mouse_x
22
+ # # @y = mouse_y
23
+ # # @time_alive = 0
24
+ # end
25
+
26
+ # def draw
27
+ # # puts Gosu.milliseconds
28
+ # # puts @animation.size
29
+ # # puts 100 % @animation.size
30
+ # # puts "Gosu.milliseconds / 100 % @animation.size: #{Gosu.milliseconds / 100 % @animation.size}"
31
+ # # img.draw(@x, @y, ZOrder::Projectile, :add)
32
+ # puts "11: #{@x} and #{@y}"
33
+ # @image.draw(@x, @y, ZOrder::Projectile)
34
+ # # img.draw_rect(@x, @y, 25, 25, @x + 25, @y + 25, :add)
35
+ # end
36
+
37
+ # def update mouse_x = nil, mouse_y = nil
38
+ # # mouse_x = @mouse_start_x
39
+ # # mouse_y = @mouse_start_y
40
+ # # if @time_alive > INITIAL_DELAY
41
+ # # new_speed = STARTING_SPEED + (@time_alive * SPEED_INCREASE_FACTOR)
42
+ # # new_speed = MAX_SPEED if new_speed > MAX_SPEED
43
+ # # @y -= new_speed
44
+ # # end
45
+
46
+ # # Cursor is left of the missle, missile needs to go left. @x needs to get smaller. @x is greater than mouse_x
47
+ # if @x > mouse_x
48
+ # difference = @x - mouse_x
49
+ # if difference > MAX_CURSOR_FOLLOW
50
+ # difference = MAX_CURSOR_FOLLOW
51
+ # end
52
+ # @x = @x - difference
53
+ # else
54
+ # # Cursor is right of the missle, missile needs to go right. @x needs to get bigger. @x is smaller than mouse_x
55
+ # difference = mouse_x - @x
56
+ # if difference > MAX_CURSOR_FOLLOW
57
+ # difference = MAX_CURSOR_FOLLOW
58
+ # end
59
+ # @x = @x + difference
60
+ # end
61
+
62
+ # if @y > mouse_y
63
+ # difference = @y - mouse_y
64
+ # if difference > MAX_CURSOR_FOLLOW
65
+ # difference = MAX_CURSOR_FOLLOW
66
+ # end
67
+ # @y = @y - difference
68
+ # else
69
+ # # Cursor is right of the missle, missile needs to go right. @y needs to get bigger. @y is smaller than mouse_y
70
+ # difference = mouse_y - @y
71
+ # if difference > MAX_CURSOR_FOLLOW
72
+ # difference = MAX_CURSOR_FOLLOW
73
+ # end
74
+ # @y = @y + difference
75
+ # end
76
+
77
+ # # Return false when out of screen (gets deleted then)
78
+ # # @time_alive += 1
79
+ # end
80
+
81
+
82
+ # def hit_objects(objects)
83
+ # drops = []
84
+ # objects.each do |object|
85
+ # if Gosu.distance(@x, @y, object.x, object.y) < 30
86
+ # # Missile destroyed
87
+ # # @y = -100
88
+ # if object.respond_to?(:health) && object.respond_to?(:take_damage)
89
+ # object.take_damage(DAMAGE)
90
+ # end
91
+
92
+ # if object.respond_to?(:is_alive) && !object.is_alive && object.respond_to?(:drops)
93
+ # puts "CALLING THE DROP"
94
+ # object.drops.each do |drop|
95
+ # drops << drop
96
+ # end
97
+ # end
98
+
99
+ # end
100
+ # end
101
+ # return drops
102
+ # end
103
+
104
+
105
+ # def hit_object(object)
106
+ # return_value = nil
107
+ # if Gosu.distance(@x, @y, object.x, object.y) < 30
108
+ # @y = -50
109
+ # return_value = DAMAGE
110
+ # else
111
+ # return_value = 0
112
+ # end
113
+ # return return_value
114
+ # end
115
+
116
+
117
+ # end
@@ -0,0 +1,47 @@
1
+ require_relative 'pickup.rb'
2
+
3
+ class HealthPack < Pickup
4
+ attr_reader :x, :y
5
+
6
+ HEALTH_BOOST = 25
7
+
8
+ def initialize(scale, x = nil, y = nil)
9
+ @scale = scale
10
+ @image = Gosu::Image.new("#{MEDIA_DIRECTORY}/health_pack_0.png", :tileable => true)
11
+ @x = x
12
+ @y = y
13
+ @image_width = @image.width * @scale
14
+ @image_height = @image.height * @scale
15
+ @image_size = @image_width * @image_height / 2
16
+ @image_radius = (@image_width + @image_height) / 4
17
+ @current_speed = GLBackground::SCROLLING_SPEED * @scale
18
+ end
19
+
20
+ def draw
21
+ image_rot = (Gosu.milliseconds / 50 % 26)
22
+ if image_rot >= 13
23
+ image_rot = 26 - image_rot
24
+ end
25
+ image_rot = 12 if image_rot == 13
26
+ @image = Gosu::Image.new("#{MEDIA_DIRECTORY}/health_pack_#{image_rot}.png", :tileable => true)
27
+ # @image.draw(@x - get_width / 2, @y - get_height / 2, ZOrder::Pickup)
28
+ super
29
+ end
30
+
31
+
32
+ def update width, height, mouse_x = nil, mouse_y = nil, player = nil
33
+ @y += @current_speed
34
+
35
+ @y < height + get_height
36
+ end
37
+
38
+ def collected_by_player player
39
+ if player.health + HEALTH_BOOST > player.class::MAX_HEALTH
40
+ player.health = player.class::MAX_HEALTH
41
+ else
42
+ player.health += HEALTH_BOOST
43
+ end
44
+ end
45
+
46
+
47
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'menu_item.rb'
2
+ class Menu
3
+ def initialize (window)
4
+ @window = window
5
+ @items = Array.new
6
+ end
7
+
8
+ def add_item (object, x, y, z, callback, hover_image = nil, options = {})
9
+ item = MenuItem.new(@window, object, x, y, z, callback, hover_image, options)
10
+ @items << item
11
+ self
12
+ end
13
+
14
+ def draw
15
+ @items.each do |i|
16
+ i.draw
17
+ end
18
+ end
19
+
20
+ def update
21
+ @items.each do |i|
22
+ i.update
23
+ end
24
+ end
25
+
26
+ def clicked
27
+ @items.each do |i|
28
+ i.clicked
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,74 @@
1
+ class MenuItem
2
+ HOVER_OFFSET = 3
3
+ def initialize (window, image, x, y, z, callback, hover_image = nil, options = {})
4
+ @window = window
5
+ @main_image = image
6
+ @hover_image = hover_image
7
+ @original_x = @x = x
8
+ @original_y = @y = y
9
+ @z = z
10
+ @callback = callback
11
+ # Can also be a font object!
12
+ @active_image = @main_image
13
+ # @text = options[:text]
14
+ # @value = options[:value]
15
+ # @settings_name = options[:settings_name]
16
+ # @config_file = options[:config_file]
17
+ # @type = options[:type]
18
+ end
19
+
20
+ def draw
21
+ if @text
22
+ @active_image.draw(@text, @x, @y, 1, 1.0, 1.0, 0xff_ffff00)
23
+ else
24
+ @active_image.draw(@x, @y, @z)
25
+ end
26
+ end
27
+
28
+ def update
29
+ # @text = @get_value_callback.call(@config_file, @settings_name) if @get_value_callback && @config_file && @settings_name
30
+ if is_mouse_hovering
31
+ if !@hover_image.nil? then
32
+ @active_image = @hover_image
33
+ end
34
+
35
+ @x = @original_x + HOVER_OFFSET
36
+ @y = @original_y + HOVER_OFFSET
37
+ else
38
+ @active_image = @main_image
39
+ @x = @original_x
40
+ @y = @original_y
41
+ end
42
+ end
43
+
44
+ def is_mouse_hovering
45
+ mx = @window.mouse_x
46
+ my = @window.mouse_y
47
+ if @type && @type == 'font'
48
+ local_width = @main_image.text_width(@text)
49
+ local_height = @main_image.height
50
+ else
51
+ local_width = @active_image.width
52
+ local_height = @active_image.height
53
+ end
54
+
55
+ (mx >= @x and my >= @y) and (mx <= @x + local_width) and (my <= @y + local_height)
56
+ end
57
+
58
+ def clicked
59
+ # return_value = nil
60
+ # if is_mouse_hovering && @callback && @value && @config_file && @settings_name
61
+ # return_value = @callback.call(@config_file, @settings_name, @value)
62
+ # end
63
+ if is_mouse_hovering && @callback
64
+ @callback.call
65
+ end
66
+ # if return_value
67
+ # @text = return_value
68
+ # end
69
+ # if @save_callback && @settings_name && @config_file
70
+ # puts "USING SAVE CALLBACK: #{@config_file} and #{@settings_name} and #{return_value}"
71
+ # @save_callback.call(@config_file, @settings_name.to_s, return_value)
72
+ # end
73
+ end
74
+ end