gosu_extensions 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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