gosu_extensions 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/core/rotation.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  module Rotation
2
2
 
3
- Half = Math::HalfPI
4
- Quarter = Math::QuarterPI
3
+ Full = 2*Math::PI
4
+ Half = Math::PI
5
+ Third = 2*Math::PI/3
6
+ Quarter = Math::HalfPI
7
+ Eight = Math::QuarterPI
5
8
 
6
9
  end
@@ -0,0 +1,38 @@
1
+ # Holds the things that are drawn.
2
+ #
3
+ class Sprites
4
+
5
+ def initialize elements = []
6
+ @elements = elements
7
+ @to_remove = []
8
+ end
9
+
10
+ def register element
11
+ @elements << element
12
+ end
13
+ def registered? element
14
+ @elements.include? element
15
+ end
16
+
17
+ def move
18
+ @elements.each &:move
19
+ end
20
+
21
+ def draw
22
+ @elements.each &:draw
23
+ end
24
+
25
+ def remove object
26
+ @to_remove << object
27
+ end
28
+
29
+ #
30
+ #
31
+ def remove_marked
32
+ @to_remove.each do |object|
33
+ @elements.delete object
34
+ end
35
+ @to_remove.clear
36
+ end
37
+
38
+ end
@@ -0,0 +1,33 @@
1
+ # Holds the things that can collide, are moved and drawn.
2
+ #
3
+ class Things < Sprites
4
+
5
+ delegate :each, :to => :@elements
6
+
7
+ def initialize environment, elements = []
8
+ @environment = environment
9
+ super elements
10
+ end
11
+
12
+ def register element
13
+ element.add_to @environment
14
+ super element
15
+ end
16
+
17
+ def targeting # TODO
18
+ @elements.select { |m| m.respond_to? :target }.each do |gun|
19
+ gun.target *@elements.select { |m| m.kind_of? Enemy }
20
+ end
21
+ end
22
+
23
+ #
24
+ #
25
+ def remove_marked
26
+ @to_remove.each do |thing|
27
+ @environment.remove thing
28
+ @elements.delete thing # TODO Should the environment be the owner of the things? Probably, yes.
29
+ end
30
+ @to_remove.clear
31
+ end
32
+
33
+ end
data/lib/core/wave.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  #
2
2
  #
3
+ # TODO This is almost a generator.
4
+ #
3
5
  class Wave
4
6
 
5
7
  attr_reader :generated_type, :execution_amount, :positioning_function
@@ -38,7 +40,7 @@ class Wave
38
40
  lambda do
39
41
  self.execution_amount.times do
40
42
  instance = self.generated_type.new window
41
- window.register instance
43
+ instance.show
42
44
  self.positioning_function.call(window, instance)
43
45
  end
44
46
  end
@@ -31,8 +31,9 @@ require 'traits'
31
31
  require 'it_is_a'
32
32
 
33
33
  require 'background'
34
- require 'moveables'
35
- require 'remove_shapes'
34
+ require 'sprites'
35
+ require 'things'
36
+ require 'objects'
36
37
  require 'wave'
37
38
  require 'waves'
38
39
  require 'scheduling'
@@ -2,9 +2,21 @@
2
2
  #
3
3
  module Attachable extend Trait
4
4
 
5
- attr_accessor :relative_position
5
+ Detach = :detach
6
6
 
7
- def move_relative pod
7
+ attr_accessor :relative_position, :pod
8
+
9
+ def detach
10
+ pod.detach self
11
+ end
12
+
13
+ # Callback after detachment.
14
+ #
15
+ def detached; end
16
+
17
+ # Move relative to the pod.
18
+ #
19
+ def move_relative
8
20
  self.position = pod.relative_position self
9
21
  self.rotation = pod.rotation unless self.kind_of? Turnable
10
22
  end
@@ -70,8 +70,8 @@ end
70
70
  #
71
71
  def generate klass
72
72
  generated = klass.new self.window
73
- generated.warp self.position
74
- self.window.register generated
73
+ generated.warp self.position * 1.0
74
+ generated.show
75
75
  generated
76
76
  end
77
77
 
data/lib/traits/lives.rb CHANGED
@@ -16,47 +16,44 @@ module Lives extend Trait
16
16
 
17
17
  def self.included target_class
18
18
  target_class.extend IncludeMethods
19
- target_class.send :include, InstanceMethods
20
19
  end
21
20
 
22
21
  module IncludeMethods
23
22
 
24
23
  # Define the amount of lives in the class.
25
24
  #
26
- def lives amount
25
+ def lives amount = 3
26
+ cattr_accessor :prototype_lives
27
+ self.prototype_lives = amount
27
28
  InitializerHooks.register self do
28
29
  self.lives = amount
29
30
  end
30
- attr_reader :lives # override the default
31
31
  end
32
32
 
33
33
  end
34
34
 
35
- module InstanceMethods
36
-
37
- attr_writer :lives
38
-
39
- def lives
40
- 3
41
- end
42
-
43
- # Override to handle killed!
44
- #
45
- def killed!
46
-
47
- end
48
-
49
- # Does three things:
50
- # * Deduct 1 live.
51
- # * Check to see if the amount is 0.
52
- # * Calls #destroy! if yes.
53
- #
54
- def kill!
55
- self.lives -= 1
56
- killed! if self.lives > 0
57
- destroy! if self.lives == 0
58
- end
59
-
35
+ attr_accessor :lives
36
+
37
+ # Override to handle killed!
38
+ #
39
+ def killed!; end
40
+
41
+ # Does three things:
42
+ # * Deduct 1 live.
43
+ # * Check to see if the amount is 0.
44
+ # * Calls #destroy! if yes.
45
+ #
46
+ def kill!
47
+ self.lives -= 1
48
+ killed! if self.lives > 0
49
+ destroy! if self.lives == 0
50
+ end
51
+
52
+ # Revive extension.
53
+ #
54
+ def revive
55
+ self.lives = self.class.prototype_lives
56
+ super
60
57
  end
61
58
 
62
59
  end
@@ -30,55 +30,4 @@ module Moveable extend Trait
30
30
  accelerate -0.5*strength
31
31
  end
32
32
 
33
- # Movement rules
34
- #
35
- # TODO Move to Sprite?
36
- #
37
- # Note: Call in method move.
38
- #
39
- def bounce_off_border_x elasticity = 1.0
40
- if position.x > window.screen_width || position.x < 0
41
- shape.body.v.x = -shape.body.v.x.to_f*elasticity
42
- end
43
- end
44
- def bounce_off_border_y elasticity = 1.0
45
- if position.y > window.screen_height || position.y < 0
46
- shape.body.v.y = -shape.body.v.y.to_f*elasticity
47
- end
48
- end
49
- def bounce_off_border elasticity = 1.0
50
- bounce_off_border_x elasticity
51
- bounce_off_border_y elasticity
52
- end
53
- def wrap_around_border_x
54
- if position.x > window.screen_width
55
- position.x -= window.screen_width
56
- elsif position.x < 0
57
- position.x += window.screen_width
58
- end
59
- end
60
- def wrap_around_border_y
61
- if position.y > window.screen_height
62
- position.y -= window.screen_height
63
- elsif position.y < 0
64
- position.y += window.screen_height
65
- end
66
- end
67
- def wrap_around_border
68
- wrap_around_border_x
69
- wrap_around_border_y
70
- end
71
- def obey_gravity
72
- self.speed += window.gravity_vector
73
- end
74
- def on_hitting_x
75
- yield if block_given? && position.x > window.screen_width || position.x < 0
76
- end
77
- def on_hitting_y
78
- yield if block_given? && position.y > window.screen_height || position.y < 0
79
- end
80
- def rotate_towards_velocity
81
- self.rotation = self.speed.to_angle
82
- end
83
-
84
33
  end
data/lib/traits/pod.rb CHANGED
@@ -64,13 +64,17 @@ module Pod extend Trait
64
64
  # Detach an instance from this.
65
65
  #
66
66
  def detach attachment
67
- self.attachments.delete attachment if self.attachments
67
+ if self.attachments
68
+ detached = self.attachments.delete attachment
69
+ detached.detached if detached # callback
70
+ end
68
71
  end
69
72
 
70
73
 
71
74
  def materialize attachment
72
75
  attachment.extend Attachable # This is where Ruby shines.
73
- window.register attachment
76
+ attachment.pod = self
77
+ attachment.show
74
78
  end
75
79
 
76
80
  #
@@ -83,7 +87,7 @@ module Pod extend Trait
83
87
  #
84
88
  def move_attachments
85
89
  self.attachments.each do |attachment|
86
- attachment.move_relative self
90
+ attachment.move_relative
87
91
  end
88
92
  end
89
93
 
@@ -10,7 +10,7 @@ module Shooter extend Trait
10
10
  relative_position = CP::Vec2.new x, y
11
11
  relative_length = relative_position.length
12
12
  relative_rotation = relative_position.to_angle
13
- lambda { self.position + (self.rotation - relative_rotation).radians_to_vec2*relative_length }
13
+ lambda { self.position + (self.rotation - relative_rotation).radians_to_vec2 * relative_length }
14
14
  end
15
15
  end
16
16
  module Velocity
data/lib/traits/shot.rb CHANGED
@@ -9,7 +9,7 @@ module Shot extend Trait
9
9
  def shoot_from shooter
10
10
  self.position = shooter.muzzle_position
11
11
  self.originator = shooter
12
- self.window.register self
12
+ self.show
13
13
  self
14
14
  end
15
15
 
data/lib/units/sprite.rb CHANGED
@@ -10,20 +10,33 @@ class Sprite
10
10
  include ItIsA
11
11
  it_is Moveable
12
12
 
13
- attr_reader :window
13
+ attr_reader :window,
14
+ :objects
15
+ attr_accessor :position,
16
+ :speed
14
17
 
15
18
  # Every thing knows the window it is attached to.
16
19
  #
20
+ # Also, it knows who it is managed by.
21
+ #
17
22
  def initialize window
18
- @window = window
19
- self.destroyed = false
23
+ @window = window
24
+ @objects = Thing === self ? window.things : window.sprites
20
25
  after_initialize
21
26
  end
22
27
 
28
+ # Makes the object visible.
29
+ #
30
+ def show
31
+ self.speed = CP::Vec2.new(0,0)
32
+ self.destroyed = false
33
+ objects.register self
34
+ end
35
+
23
36
  # Default layer is Layer::Players.
24
37
  #
25
38
  def layer
26
- Layer::Players
39
+ Layer::Ambient
27
40
  end
28
41
  # Default rotation is upwards.
29
42
  #
@@ -50,7 +63,7 @@ class Sprite
50
63
  end
51
64
  end
52
65
  def random_rotation
53
- rotation { 2*Math::PI*rand }
66
+ rotation { Rotation::Full*rand }
54
67
  end
55
68
 
56
69
  # Plays a random sound of the given sounds.
@@ -65,19 +78,16 @@ class Sprite
65
78
 
66
79
  end
67
80
 
68
- # Override this.
69
- #
70
- def move
71
-
72
- end
73
-
74
81
  # Do something threaded.
75
82
  #
76
83
  # Default is: Instantly, in the next step.
77
84
  #
85
+ # Note: Can also be called with after.
86
+ #
78
87
  def threaded time = 1, &code
79
88
  self.window.threaded time, &code
80
89
  end
90
+ alias after threaded
81
91
 
82
92
  # Some things you can only do every x time units.
83
93
  #
@@ -99,11 +109,15 @@ class Sprite
99
109
  result
100
110
  end
101
111
 
112
+ # A sprite is not added to the physical environment.
102
113
  #
114
+ # Override if you want it to.
103
115
  #
104
- def add_to environment
105
- # A sprite is not added to the physical environment.
106
- end
116
+ def add_to environment; end
117
+
118
+ # Override this method to do stuff after it is destroyed.
119
+ #
120
+ def destroyed!; end
107
121
 
108
122
  # Destroy this thing.
109
123
  #
@@ -111,18 +125,26 @@ class Sprite
111
125
  def destroyed?
112
126
  @destroyed
113
127
  end
114
- def destroyed!
115
- # Override
116
- end
117
128
  def destroy!
118
129
  return if self.destroyed?
119
- self.destroyed!
130
+ self.destroyed! # invoke callback
120
131
  self.destroyed = true
132
+ self.objects.remove self
133
+ # self.window.unregister self # TODO self.owner.unregister self
134
+ end
135
+
136
+ # Revives this thing.
137
+ #
138
+ # TODO Override in Lives.
139
+ #
140
+ def revive
141
+ show unless objects.registered?(self)
121
142
  end
122
143
 
123
144
  # Draws its image.
124
145
  #
125
146
  def draw
147
+ # p [self.class, self.layer, self.drawing_rotation, 0.5, 0.5, *self.current_size] unless self.position
126
148
  self.image.draw_rot self.position.x, self.position.y, self.layer, self.drawing_rotation, 0.5, 0.5, *self.current_size
127
149
  end
128
150
  def current_size
@@ -151,12 +173,75 @@ class Sprite
151
173
 
152
174
  # Movement and Position.
153
175
  #
176
+ # Sprite Movement is not thought of as very realistic (no damping for example).
177
+ # These are just a few simple rules.
178
+ #
179
+ def move
180
+ self.position += self.speed/SUBSTEPS
181
+ moved
182
+ end
183
+
184
+ # Callback where you can make it obey rules.
185
+ #
186
+ def moved; end
154
187
 
155
188
  #
156
189
  #
157
- attr_accessor :position, :speed
158
190
  def rotation= rotation
159
191
  @rotation = rotation % (2*Math::PI)
160
192
  end
161
193
 
194
+ # Movement rules
195
+ #
196
+ # Note: Use these in method move.
197
+ #
198
+ def bounce_off_border_x elasticity = 1.0
199
+ if position.x > window.screen_width || position.x < 0
200
+ self.speed.x = -self.speed.x.to_f*elasticity
201
+ end
202
+ end
203
+ def bounce_off_border_y elasticity = 1.0
204
+ if position.y > window.screen_height || position.y < 0
205
+ self.speed.y = -self.speed.y.to_f*elasticity
206
+ end
207
+ end
208
+ def bounce_off_border elasticity = 1.0
209
+ bounce_off_border_x elasticity
210
+ bounce_off_border_y elasticity
211
+ end
212
+ def wrap_around_border_x
213
+ if position.x > window.screen_width
214
+ position.x -= window.screen_width
215
+ elsif position.x < 0
216
+ position.x += window.screen_width
217
+ end
218
+ end
219
+ def wrap_around_border_y
220
+ if position.y > window.screen_height
221
+ position.y -= window.screen_height
222
+ elsif position.y < 0
223
+ position.y += window.screen_height
224
+ end
225
+ end
226
+ def wrap_around_border
227
+ wrap_around_border_x
228
+ wrap_around_border_y
229
+ end
230
+ def obey_gravity
231
+ self.speed += window.gravity_vector
232
+ end
233
+ def on_hitting_x
234
+ yield if block_given? && position.x > window.screen_width || position.x < 0
235
+ end
236
+ def on_hitting_y
237
+ yield if block_given? && position.y > window.screen_height || position.y < 0
238
+ end
239
+ def on_hitting_border &block
240
+ on_hitting_x &block
241
+ on_hitting_y &block
242
+ end
243
+ def rotate_towards_velocity
244
+ self.rotation = self.speed.to_angle
245
+ end
246
+
162
247
  end