line-em-up 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/line-em-up/game_window.rb +118 -104
- data/line-em-up/irb_requirements.rb +5 -6
- data/line-em-up/lib/config_setting.rb +22 -9
- data/line-em-up/lib/difficulty_setting.rb +78 -0
- data/line-em-up/media/mini_missile.png +0 -0
- data/line-em-up/models/bomb.rb +2 -2
- data/line-em-up/models/building.rb +20 -14
- data/line-em-up/models/bullet.rb +3 -34
- data/line-em-up/models/cursor.rb +12 -5
- data/line-em-up/models/dumb_projectile.rb +110 -0
- data/line-em-up/models/enemy_bomb.rb +2 -6
- data/line-em-up/models/enemy_bullet.rb +4 -35
- data/line-em-up/models/enemy_homing_missile.rb +10 -65
- data/line-em-up/models/enemy_player.rb +16 -23
- data/line-em-up/models/general_object.rb +131 -8
- data/line-em-up/models/grappling_hook.rb +16 -20
- data/line-em-up/models/health_pack.rb +4 -18
- data/line-em-up/models/missile.rb +26 -21
- data/line-em-up/models/missile_boat.rb +18 -22
- data/line-em-up/models/mothership.rb +36 -37
- data/line-em-up/models/pickup.rb +8 -16
- data/line-em-up/models/player.rb +38 -57
- data/line-em-up/models/projectile.rb +97 -38
- data/line-em-up/models/small_explosion.rb +7 -3
- data/line-em-up/models/star.rb +7 -10
- data/menu_launcher.rb +9 -2
- metadata +4 -1
@@ -0,0 +1,110 @@
|
|
1
|
+
require_relative 'general_object.rb'
|
2
|
+
|
3
|
+
class DumbProjectile < GeneralObject
|
4
|
+
attr_accessor :x, :y, :time_alive
|
5
|
+
# WARNING THESE CONSTANTS DON'T GET OVERRIDDEN BY SUBCLASSES. NEED GETTER METHODS
|
6
|
+
COOLDOWN_DELAY = 50
|
7
|
+
STARTING_SPEED = 3.0
|
8
|
+
INITIAL_DELAY = 0
|
9
|
+
SPEED_INCREASE_FACTOR = 0.0
|
10
|
+
DAMAGE = 5
|
11
|
+
AOE = 0
|
12
|
+
MAX_CURSOR_FOLLOW = 5 # Do we need this if we have a max speed?
|
13
|
+
ADVANCED_HIT_BOX_DETECTION = false
|
14
|
+
|
15
|
+
|
16
|
+
def get_image
|
17
|
+
puts "override get_image!"
|
18
|
+
Gosu::Image.new("#{MEDIA_DIRECTORY}/question.png")
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(scale, screen_width, screen_height, object, options = {})
|
22
|
+
options[:relative_object] = object
|
23
|
+
super(scale, object.x, object.y, screen_width, screen_height, options)
|
24
|
+
@current_speed = self.class.get_max_speed * @scale
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def update mouse_x = nil, mouse_y = nil, player = nil
|
29
|
+
@y -= @current_speed
|
30
|
+
@y > 0 && @y < @screen_height
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
def get_draw_ordering
|
35
|
+
ZOrder::Projectile
|
36
|
+
end
|
37
|
+
|
38
|
+
def destructable?
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def hit_object(object)
|
43
|
+
return hit_objects([[object]])
|
44
|
+
end
|
45
|
+
|
46
|
+
def hit_objects(object_groups)
|
47
|
+
drops = []
|
48
|
+
points = 0
|
49
|
+
hit_object = false
|
50
|
+
killed = 0
|
51
|
+
object_groups.each do |group|
|
52
|
+
group.each do |object|
|
53
|
+
next if object.nil?
|
54
|
+
break if hit_object
|
55
|
+
if object.health <= 0
|
56
|
+
next
|
57
|
+
end
|
58
|
+
hit_object = Gosu.distance(@x, @y, object.x, object.y) < self.get_radius + object.get_radius
|
59
|
+
if hit_object
|
60
|
+
if object.respond_to?(:health) && object.respond_to?(:take_damage)
|
61
|
+
object.take_damage(self.class.get_damage)
|
62
|
+
end
|
63
|
+
|
64
|
+
if object.respond_to?(:is_alive) && !object.is_alive && object.respond_to?(:drops)
|
65
|
+
|
66
|
+
object.drops.each do |drop|
|
67
|
+
drops << drop
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
if object.respond_to?(:is_alive) && !object.is_alive && object.respond_to?(:get_points)
|
72
|
+
killed += 1
|
73
|
+
points = points + object.get_points
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
@y = @off_screen if hit_object
|
79
|
+
return {drops: drops, point_value: points, killed: killed}
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
def self.get_damage
|
84
|
+
self::DAMAGE
|
85
|
+
end
|
86
|
+
def self.get_aoe
|
87
|
+
self::AOE
|
88
|
+
end
|
89
|
+
def self.get_cooldown_delay
|
90
|
+
self::COOLDOWN_DELAY
|
91
|
+
end
|
92
|
+
def self.get_starting_speed
|
93
|
+
self::STARTING_SPEED
|
94
|
+
end
|
95
|
+
def self.get_starting_speed
|
96
|
+
self::STARTING_SPEED
|
97
|
+
end
|
98
|
+
def self.get_initial_delay
|
99
|
+
self::INITIAL_DELAY
|
100
|
+
end
|
101
|
+
def self.get_speed_increase_factor
|
102
|
+
self::SPEED_INCREASE_FACTOR
|
103
|
+
end
|
104
|
+
def self.get_max_cursor_follow
|
105
|
+
self::MAX_CURSOR_FOLLOW
|
106
|
+
end
|
107
|
+
def self.get_advanced_hit_box_detection
|
108
|
+
self::ADVANCED_HIT_BOX_DETECTION
|
109
|
+
end
|
110
|
+
end
|
@@ -17,15 +17,11 @@ class EnemyBomb < Projectile
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def draw
|
20
|
-
# @image.draw(@x, @y, ZOrder::Projectile, scale_x = 1, scale_y = 1, color = 0xff_ffffff, mode = :default)
|
21
|
-
# @image.draw(@x, @y, ZOrder::Projectile, scale_x = 1, scale_y = 1, color = 0xff_ffffff, mode = :default)
|
22
|
-
# 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
|
23
|
-
# @image.draw_rot(@x, @y, ZOrder::Projectile, @y, 0.5, 0.5, scale, scale)
|
24
20
|
return draw_rot()
|
25
21
|
end
|
26
22
|
|
27
23
|
|
28
|
-
def update
|
24
|
+
def update mouse_x = nil, mouse_y = nil, player = nil
|
29
25
|
vx = (self.class.get_starting_speed * @scale) * Math.cos(@angle * Math::PI / 180)
|
30
26
|
|
31
27
|
vy = (self.class.get_starting_speed * @scale) * Math.sin(@angle * Math::PI / 180)
|
@@ -35,6 +31,6 @@ class EnemyBomb < Projectile
|
|
35
31
|
@x = @x + vx
|
36
32
|
@y = @y + vy
|
37
33
|
|
38
|
-
super(
|
34
|
+
super(mouse_x, mouse_y)
|
39
35
|
end
|
40
36
|
end
|
@@ -1,43 +1,12 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'dumb_projectile.rb'
|
2
2
|
|
3
|
-
class EnemyBullet <
|
3
|
+
class EnemyBullet < DumbProjectile
|
4
4
|
DAMAGE = 5
|
5
5
|
COOLDOWN_DELAY = 30
|
6
|
-
|
6
|
+
# Enemy y speeds are negative
|
7
|
+
MAX_SPEED = -5
|
7
8
|
|
8
9
|
def get_image
|
9
10
|
Gosu::Image.new("#{MEDIA_DIRECTORY}/bullet-mini-reverse.png")
|
10
11
|
end
|
11
|
-
|
12
|
-
def initialize(scale, width, height, object, mouse_x = nil, mouse_y = nil, options = {})
|
13
|
-
@scale = scale
|
14
|
-
@time_alive = 0
|
15
|
-
@image = get_image
|
16
|
-
# @color = Gosu::Color.new(0xff_000000)
|
17
|
-
# @color.red = rand(255 - 40) + 40
|
18
|
-
# @color.green = rand(255 - 40) + 40
|
19
|
-
# @color.blue = rand(255 - 40) + 40
|
20
|
-
if LEFT == options[:side]
|
21
|
-
@x = object.x - (object.get_width / 2)
|
22
|
-
@y = object.y# - player.get_height
|
23
|
-
elsif RIGHT == options[:side]
|
24
|
-
@x = (object.x + object.get_width / 2) - 4
|
25
|
-
@y = object.y# - player.get_height
|
26
|
-
else
|
27
|
-
@x = object.x
|
28
|
-
@y = object.y
|
29
|
-
end
|
30
|
-
@image_width = @image.width * @scale
|
31
|
-
@image_height = @image.height * @scale
|
32
|
-
@image_size = @image_width * @image_height / 2
|
33
|
-
@image_radius = (@image_width + @image_height) / 4
|
34
|
-
@current_speed = self.class.get_max_speed * @scale
|
35
|
-
end
|
36
|
-
|
37
|
-
def update width, height, mouse_x = nil, mouse_y = nil, player = nil
|
38
|
-
@y += @current_speed
|
39
|
-
# Return false when out of screen (gets deleted then)
|
40
|
-
@y > 0 && @y < height
|
41
|
-
# super(mouse_x, mouse_y)
|
42
|
-
end
|
43
12
|
end
|
@@ -13,46 +13,15 @@ class EnemyHomingMissile < Projectile
|
|
13
13
|
# ADVANCED_HIT_BOX_DETECTION = true
|
14
14
|
ADVANCED_HIT_BOX_DETECTION = false
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@health = 5
|
21
|
-
# @mouse_start_x = mouse_x
|
22
|
-
# @mouse_start_y = mouse_y
|
23
|
-
|
24
|
-
if LEFT == options[:side]
|
25
|
-
@x = object.x - (object.get_width / 2)
|
26
|
-
@y = object.y
|
27
|
-
elsif RIGHT == options[:side]
|
28
|
-
@x = (object.x + object.get_width / 2) - 4
|
29
|
-
@y = object.y
|
30
|
-
else
|
31
|
-
@x = object.x
|
32
|
-
@y = object.y
|
33
|
-
end
|
34
|
-
|
35
|
-
if homing_object && homing_object.is_alive
|
36
|
-
|
37
|
-
start_point = OpenStruct.new(:x => @x - width / 2, :y => @y - height / 2)
|
38
|
-
# start_point = GeoPoint.new(@x - WIDTH / 2, @y - HEIGHT / 2)
|
39
|
-
# end_point = OpenStruct.new(:x => @mouse_start_x, :y => @mouse_start_y)
|
40
|
-
end_point = OpenStruct.new(:x => homing_object.x - width / 2, :y => homing_object.y - height / 2)
|
41
|
-
# end_point = GeoPoint.new(@mouse_start_x - WIDTH / 2, @mouse_start_y - HEIGHT / 2)
|
42
|
-
@angle = calc_angle(start_point, end_point)
|
43
|
-
@radian = calc_radian(start_point, end_point)
|
44
|
-
|
16
|
+
def get_image
|
17
|
+
# Gosu::Image.new("#{MEDIA_DIRECTORY}/mini_missile_reverse.png")
|
18
|
+
Gosu::Image.new("#{MEDIA_DIRECTORY}/mini_missile.png")
|
19
|
+
end
|
45
20
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@angle = 280.0
|
51
|
-
end
|
52
|
-
@image_width = @image.width * @scale
|
53
|
-
@image_height = @image.height * @scale
|
54
|
-
@image_size = @image_width * @image_height / 2
|
55
|
-
@image_radius = (@image_width + @image_height) / 4
|
21
|
+
def initialize(scale, screen_width, screen_height, object, homing_object, angle_min, angle_max, angle_init, options = {})
|
22
|
+
options[:relative_object] = object
|
23
|
+
super(scale, screen_width, screen_height, object, homing_object.x, homing_object.y, angle_min, angle_max, angle_init, options)
|
24
|
+
@health = 5
|
56
25
|
end
|
57
26
|
|
58
27
|
def destructable?
|
@@ -68,34 +37,10 @@ class EnemyHomingMissile < Projectile
|
|
68
37
|
@health -= damage
|
69
38
|
end
|
70
39
|
|
71
|
-
def get_image
|
72
|
-
Gosu::Image.new("#{MEDIA_DIRECTORY}/mini_missile_reverse.png")
|
73
|
-
end
|
74
40
|
|
75
|
-
def update
|
41
|
+
def update mouse_x = nil, mouse_y = nil
|
76
42
|
if is_alive
|
77
|
-
|
78
|
-
if @time_alive > self.class.get_initial_delay
|
79
|
-
new_speed = self.class.get_starting_speed + (self.class.get_speed_increase_factor > 0 ? @time_alive * self.class.get_speed_increase_factor : 0)
|
80
|
-
new_speed = self.class.get_max_speed if new_speed > self.class.get_max_speed
|
81
|
-
new_speed = new_speed * @scale
|
82
|
-
end
|
83
|
-
|
84
|
-
vx = 0
|
85
|
-
vy = 0
|
86
|
-
if new_speed > 0
|
87
|
-
vx = ((new_speed / 3)) * Math.cos(@angle * Math::PI / 180)
|
88
|
-
|
89
|
-
vy = ((new_speed / 3)) * Math.sin(@angle * Math::PI / 180)
|
90
|
-
vy = vy * -1
|
91
|
-
# Because our y is inverted
|
92
|
-
vy = vy - ((new_speed / 3) * 2)
|
93
|
-
end
|
94
|
-
|
95
|
-
@x = @x + vx
|
96
|
-
@y = @y - vy
|
97
|
-
|
98
|
-
super(width, height, mouse_x, mouse_y)
|
43
|
+
super(mouse_x, mouse_y)
|
99
44
|
else
|
100
45
|
false
|
101
46
|
end
|
@@ -1,31 +1,24 @@
|
|
1
|
-
require_relative 'player.rb'
|
1
|
+
# require_relative 'player.rb'
|
2
2
|
require_relative 'enemy_bullet.rb'
|
3
3
|
require_relative 'small_explosion.rb'
|
4
4
|
require_relative 'star.rb'
|
5
5
|
|
6
6
|
class EnemyPlayer < GeneralObject
|
7
|
-
|
7
|
+
SPEED = 3
|
8
8
|
MAX_ATTACK_SPEED = 3.0
|
9
9
|
POINT_VALUE_BASE = 10
|
10
10
|
attr_accessor :cooldown_wait, :attack_speed, :health, :armor, :x, :y
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# @beep = Gosu::Sample.new("#{MEDIA_DIRECTORY}/beep.wav")
|
19
|
-
@x = x || rand(width)
|
20
|
-
@y = y || 0
|
12
|
+
def get_image
|
13
|
+
Gosu::Image.new("#{MEDIA_DIRECTORY}/airship1_color1_reverse.png")
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize scale, screen_width, screen_height, x = nil, y = nil, options = {}
|
17
|
+
super(scale, x || rand(screen_width), y || 0, screen_width, screen_height, options)
|
21
18
|
@cooldown_wait = 0
|
22
19
|
@attack_speed = 0.5
|
23
20
|
@health = 15
|
24
21
|
@armor = 0
|
25
|
-
@image_width = @image.width * @scale
|
26
|
-
@image_height = @image.height * @scale
|
27
|
-
@image_size = @image_width * @image_height / 2
|
28
|
-
@image_radius = (@image_width + @image_height) / 4
|
29
22
|
@current_speed = (rand(5) * @scale).round + 1
|
30
23
|
end
|
31
24
|
|
@@ -42,9 +35,9 @@ class EnemyPlayer < GeneralObject
|
|
42
35
|
@health -= damage
|
43
36
|
end
|
44
37
|
|
45
|
-
def attack
|
38
|
+
def attack player
|
46
39
|
return {
|
47
|
-
projectiles: [EnemyBullet.new(@scale,
|
40
|
+
projectiles: [EnemyBullet.new(@scale, @screen_width, @screen_height, self)],
|
48
41
|
cooldown: EnemyBullet::COOLDOWN_DELAY
|
49
42
|
}
|
50
43
|
end
|
@@ -52,8 +45,8 @@ class EnemyPlayer < GeneralObject
|
|
52
45
|
|
53
46
|
def drops
|
54
47
|
[
|
55
|
-
SmallExplosion.new(@scale, @x, @y, @image),
|
56
|
-
Star.new(@scale, @x, @y)
|
48
|
+
SmallExplosion.new(@scale, @screen_width, @screen_height, @x, @y, @image),
|
49
|
+
Star.new(@scale, @screen_width, @screen_height, @x, @y)
|
57
50
|
]
|
58
51
|
end
|
59
52
|
|
@@ -70,7 +63,7 @@ class EnemyPlayer < GeneralObject
|
|
70
63
|
@current_speed
|
71
64
|
end
|
72
65
|
|
73
|
-
def update
|
66
|
+
def update mouse_x = nil, mouse_y = nil, player = nil
|
74
67
|
@cooldown_wait -= 1 if @cooldown_wait > 0
|
75
68
|
if is_alive
|
76
69
|
# Stay above the player
|
@@ -80,7 +73,7 @@ class EnemyPlayer < GeneralObject
|
|
80
73
|
if rand(2).even?
|
81
74
|
@y += get_speed
|
82
75
|
|
83
|
-
@y =
|
76
|
+
@y = @screen_height / 2 if @y > @screen_height / 2
|
84
77
|
else
|
85
78
|
@y -= get_speed
|
86
79
|
|
@@ -89,14 +82,14 @@ class EnemyPlayer < GeneralObject
|
|
89
82
|
end
|
90
83
|
if rand(2).even?
|
91
84
|
@x += get_speed
|
92
|
-
@x =
|
85
|
+
@x = @screen_width if @x > @screen_width
|
93
86
|
else
|
94
87
|
@x -= get_speed
|
95
88
|
@x = 0 + (get_width / 2) if @x < 0 + (get_width / 2)
|
96
89
|
end
|
97
90
|
|
98
91
|
|
99
|
-
@y <
|
92
|
+
@y < @screen_height + (get_height / 2)
|
100
93
|
else
|
101
94
|
false
|
102
95
|
end
|
@@ -9,11 +9,27 @@ class GeneralObject
|
|
9
9
|
Gosu::Image.new("#{MEDIA_DIRECTORY}/question.png")
|
10
10
|
end
|
11
11
|
|
12
|
-
def initialize(scale, x
|
12
|
+
def initialize(scale, x, y, screen_width, screen_height, options = {})
|
13
13
|
@scale = scale
|
14
|
-
@image = get_image
|
15
|
-
|
16
|
-
|
14
|
+
@image = options[:image] || get_image
|
15
|
+
|
16
|
+
|
17
|
+
if options[:relative_object]
|
18
|
+
if LEFT == options[:side]
|
19
|
+
@x = options[:relative_object].x - (options[:relative_object].get_width / 2)
|
20
|
+
@y = options[:relative_object].y
|
21
|
+
elsif RIGHT == options[:side]
|
22
|
+
@x = (options[:relative_object].x + options[:relative_object].get_width / 2) - 4
|
23
|
+
@y = options[:relative_object].y
|
24
|
+
else
|
25
|
+
@x = options[:relative_object].x
|
26
|
+
@y = options[:relative_object].y
|
27
|
+
end
|
28
|
+
else
|
29
|
+
@x = x
|
30
|
+
@y = y
|
31
|
+
end
|
32
|
+
|
17
33
|
@time_alive = 0
|
18
34
|
# For objects that don't take damage, they'll never get hit by anything due to having 0 health
|
19
35
|
@health = 0
|
@@ -21,6 +37,15 @@ class GeneralObject
|
|
21
37
|
@image_height = @image.height * @scale
|
22
38
|
@image_size = @image_width * @image_height / 2
|
23
39
|
@image_radius = (@image_width + @image_height) / 4
|
40
|
+
|
41
|
+
@image_width_half = @image_width / 2
|
42
|
+
@image_height_half = @image_height / 2
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
@screen_width = screen_width
|
47
|
+
@screen_height = screen_height
|
48
|
+
@off_screen = screen_height + screen_height
|
24
49
|
end
|
25
50
|
|
26
51
|
# If using a different class for ZOrder than it has for model name, or if using subclass (from subclass or parent)
|
@@ -57,21 +82,22 @@ class GeneralObject
|
|
57
82
|
@image_radius
|
58
83
|
end
|
59
84
|
|
60
|
-
def update
|
85
|
+
def update mouse_x = nil, mouse_y = nil, player = nil
|
61
86
|
# Inherit, add logic, then call this to calculate whether it's still visible.
|
62
87
|
# @time_alive ||= 0 # Temp solution
|
63
88
|
@time_alive += 1
|
64
|
-
return is_on_screen?
|
89
|
+
return is_on_screen?
|
65
90
|
end
|
66
91
|
|
67
92
|
protected
|
93
|
+
|
68
94
|
def self.get_max_speed
|
69
95
|
self::MAX_SPEED
|
70
96
|
end
|
71
97
|
|
72
|
-
def is_on_screen?
|
98
|
+
def is_on_screen?
|
73
99
|
# @image.draw(@x - @image.width / 2, @y - @image.height / 2, ZOrder::Player)
|
74
|
-
@y > (0 - get_height) && @y < (
|
100
|
+
@y > (0 - get_height) && @y < (@screen_height + get_height) && @x > (0 - get_width) && @x < (@screen_width + get_width)
|
75
101
|
end
|
76
102
|
|
77
103
|
|
@@ -100,5 +126,102 @@ class GeneralObject
|
|
100
126
|
return rdn
|
101
127
|
end
|
102
128
|
|
129
|
+
def add_angles angle1, angle2
|
130
|
+
angle_sum = angle1 + angle2
|
131
|
+
if angle_sum > 360
|
132
|
+
angle_sum = angle_sum - 360
|
133
|
+
end
|
134
|
+
end
|
135
|
+
def subtract_angles angle1, angle2
|
136
|
+
angle_sum = angle1 - angle2
|
137
|
+
if angle_sum < 0
|
138
|
+
angle_sum = angle_sum + 360
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.is_angle_between_two_angles?(angle, min_angle, max_angle)
|
143
|
+
value = false
|
144
|
+
if angle == min_angle
|
145
|
+
value = true
|
146
|
+
elsif angle == max_angle
|
147
|
+
value = true
|
148
|
+
elsif max_angle < min_angle
|
149
|
+
# if max angle is less than min, then it crossed the angle 0/360 barrier
|
150
|
+
if angle == 0
|
151
|
+
value = true
|
152
|
+
elsif angle > 0 && angle < max_angle
|
153
|
+
value = true
|
154
|
+
elsif angle > min_angle
|
155
|
+
value = true
|
156
|
+
else
|
157
|
+
# return false
|
158
|
+
end
|
159
|
+
else
|
160
|
+
# max angle is greater than min, easy case.
|
161
|
+
value = angle < max_angle && angle > min_angle
|
162
|
+
end
|
163
|
+
return value
|
164
|
+
end
|
165
|
+
|
166
|
+
def is_angle_between_two_angles?(angle, min_angle, max_angle)
|
167
|
+
GeneralObject.is_angle_between_two_angles?(angle, min_angle, max_angle)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Which angle is nearest
|
171
|
+
def self.nearest_angle angle, min_angle, max_angle
|
172
|
+
value = nil
|
173
|
+
min_angle_diff = angle - min_angle
|
174
|
+
max_angle_diff = angle - max_angle
|
175
|
+
first_diff = nil
|
176
|
+
if min_angle_diff.abs > max_angle_diff.abs
|
177
|
+
# puts "CASE 1"
|
178
|
+
first_diff = max_angle_diff.abs
|
179
|
+
value = max_angle
|
180
|
+
else
|
181
|
+
# puts "CASE 2"
|
182
|
+
first_diff = min_angle_diff.abs
|
183
|
+
value = min_angle
|
184
|
+
end
|
185
|
+
# puts "VALUE: #{value}"
|
186
|
+
|
187
|
+
alt_value = nil
|
188
|
+
alt_angle = (angle - 360).abs
|
189
|
+
min_angle_diff = alt_angle - min_angle
|
190
|
+
max_angle_diff = alt_angle - max_angle
|
191
|
+
second_diff = nil
|
192
|
+
if min_angle_diff.abs > max_angle_diff.abs
|
193
|
+
# puts "CASE 3"
|
194
|
+
second_diff = max_angle_diff.abs
|
195
|
+
alt_value = max_angle
|
196
|
+
else
|
197
|
+
# puts "CASE 4"
|
198
|
+
second_diff = min_angle_diff.abs
|
199
|
+
alt_value = min_angle
|
200
|
+
end
|
201
|
+
# puts "VALUE: #{value}"
|
202
|
+
|
203
|
+
if first_diff > second_diff
|
204
|
+
# puts "CASE 5"
|
205
|
+
value = alt_value
|
206
|
+
end
|
207
|
+
# puts "VALUE: #{value}"
|
208
|
+
return value
|
209
|
+
end
|
210
|
+
|
211
|
+
def nearest_angle angle, min_angle, max_angle
|
212
|
+
GeneralObject.nearest_angle(angle, min_angle, max_angle)
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
103
226
|
|
104
227
|
end
|
@@ -14,8 +14,12 @@ class GrapplingHook < GeneralObject
|
|
14
14
|
# MAX_CURSOR_FOLLOW = 15
|
15
15
|
MAX_SPEED = 20
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def cooldown_delay
|
18
|
+
COOLDOWN_DELAY
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(scale, screen_width, screen_height, object, mouse_x, mouse_y, options = {})
|
22
|
+
# object.grapple_hook_cooldown_wait = COOLDOWN_DELAY
|
19
23
|
@scale = scale
|
20
24
|
|
21
25
|
# image = Magick::Image::read("#{MEDIA_DIRECTORY}/grappling_hook.png").first.resize(0.1)
|
@@ -40,7 +44,11 @@ class GrapplingHook < GeneralObject
|
|
40
44
|
@image_angle = @angle
|
41
45
|
if @angle < 0
|
42
46
|
@angle = 360 - @angle.abs
|
47
|
+
@image_angle = (@angle - 90) * -1
|
48
|
+
else
|
49
|
+
@image_angle = (@angle - 90) * -1
|
43
50
|
end
|
51
|
+
|
44
52
|
@max_length = 7 * @scale
|
45
53
|
@max_length_counter = 0
|
46
54
|
@reached_end_point = false
|
@@ -56,6 +64,10 @@ class GrapplingHook < GeneralObject
|
|
56
64
|
@chain_width = @chain.height * @scale
|
57
65
|
@chain_size = @chain_width * @chain_height / 2
|
58
66
|
@chain_radius = ((@chain_height + @chain_width) / 4) * @scale
|
67
|
+
|
68
|
+
# @screen_width = screen_width
|
69
|
+
# @screen_height = screen_height
|
70
|
+
# @off_screen = screen_height + screen_height
|
59
71
|
end
|
60
72
|
|
61
73
|
def draw player
|
@@ -70,7 +82,7 @@ class GrapplingHook < GeneralObject
|
|
70
82
|
|
71
83
|
# @image.draw_rot(@x - get_width / 2 - get_height / 2, @y, ZOrder::Cursor, @image_angle, 0.5, 0.5, @scale, @scale)
|
72
84
|
# @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,
|
85
|
+
@image.draw_rot(@x, @y, ZOrder::Cursor, @image_angle, 0.5, 0.5, @scale, @scale)
|
74
86
|
|
75
87
|
chain_x = @x# - (get_width / 2) - (@chain.width / 2)
|
76
88
|
chain_y = @y# - (get_height / 2) - (@chain.height / 2)
|
@@ -127,7 +139,7 @@ class GrapplingHook < GeneralObject
|
|
127
139
|
|
128
140
|
# end
|
129
141
|
|
130
|
-
def update
|
142
|
+
def update player = nil
|
131
143
|
# puts "GRAP UPDATE:#{@reached_max_length} and #{@max_length_counter}"
|
132
144
|
if !@reached_end_point
|
133
145
|
current_angle = @angle
|
@@ -177,9 +189,7 @@ class GrapplingHook < GeneralObject
|
|
177
189
|
if @reached_end_point || @reached_max_length
|
178
190
|
@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
191
|
end
|
180
|
-
# raise "HERE WE GO" if @reached_end_point
|
181
192
|
|
182
|
-
# After reached target, reverse the angle
|
183
193
|
|
184
194
|
return !@reached_back_to_player
|
185
195
|
end
|
@@ -202,8 +212,6 @@ class GrapplingHook < GeneralObject
|
|
202
212
|
end
|
203
213
|
end
|
204
214
|
|
205
|
-
|
206
|
-
|
207
215
|
def hit_objects(objects)
|
208
216
|
drops = []
|
209
217
|
objects.each do |object|
|
@@ -227,16 +235,4 @@ class GrapplingHook < GeneralObject
|
|
227
235
|
end
|
228
236
|
|
229
237
|
|
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
238
|
end
|
@@ -5,16 +5,8 @@ class HealthPack < Pickup
|
|
5
5
|
|
6
6
|
HEALTH_BOOST = 25
|
7
7
|
|
8
|
-
def
|
9
|
-
|
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
|
8
|
+
def get_image
|
9
|
+
Gosu::Image.new("#{MEDIA_DIRECTORY}/health_pack_0.png", :tileable => true)
|
18
10
|
end
|
19
11
|
|
20
12
|
def draw
|
@@ -24,17 +16,11 @@ class HealthPack < Pickup
|
|
24
16
|
end
|
25
17
|
image_rot = 12 if image_rot == 13
|
26
18
|
@image = Gosu::Image.new("#{MEDIA_DIRECTORY}/health_pack_#{image_rot}.png", :tileable => true)
|
27
|
-
|
28
|
-
super
|
19
|
+
@image.draw(@x - get_width / 2, @y - get_height / 2, ZOrder::Pickups)
|
20
|
+
# super
|
29
21
|
end
|
30
22
|
|
31
23
|
|
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
24
|
def collected_by_player player
|
39
25
|
if player.health + HEALTH_BOOST > player.class::MAX_HEALTH
|
40
26
|
player.health = player.class::MAX_HEALTH
|