graphics 1.0.0b5 → 1.0.0b6

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.
@@ -37,15 +37,6 @@ class Person < Graphics::Body
37
37
  self.m += D_M unless m >= M_M
38
38
  end
39
39
 
40
- def draw
41
- trail.draw
42
-
43
- w.angle x, y, ga, 60, :red
44
-
45
- # the blit looks HORRIBLE when rotated... dunno why
46
- w.blit w.body_img, x, y
47
- end
48
-
49
40
  def turn_towards_goal
50
41
  turn a.relative_angle(ga, D_A)
51
42
  end
@@ -66,6 +57,17 @@ class Person < Graphics::Body
66
57
  self.a = (a + 180).degrees
67
58
  change_goal
68
59
  end
60
+
61
+ class View
62
+ def self.draw w, b
63
+ b.trail.draw
64
+
65
+ w.angle b.x, b.y, b.ga, 60, :red
66
+
67
+ # the blit looks HORRIBLE when rotated... dunno why
68
+ w.blit w.body_img, b.x, b.y
69
+ end
70
+ end
69
71
  end
70
72
 
71
73
  class WalkerSimulation < Graphics::Simulation
@@ -75,6 +77,7 @@ class WalkerSimulation < Graphics::Simulation
75
77
  super 850, 850, 16, "Walker"
76
78
 
77
79
  self.ps = populate Person
80
+ register_bodies ps
78
81
 
79
82
  self.body_img = sprite 20, 20 do
80
83
  circle 10, 10, 5, :white, :filled
@@ -84,14 +87,14 @@ class WalkerSimulation < Graphics::Simulation
84
87
  end
85
88
 
86
89
  def update n
87
- ps.each(&:update)
90
+ super
91
+
88
92
  detect_collisions(ps).each(&:collide)
89
93
  end
90
94
 
91
95
  def draw n
92
- clear
96
+ super
93
97
 
94
- ps.each(&:draw)
95
98
  fps n
96
99
  end
97
100
 
@@ -1,7 +1,5 @@
1
1
  #!/usr/local/bin/ruby -w
2
2
 
3
- # srand 42
4
-
5
3
  require "graphics"
6
4
  require "graphics/trail"
7
5
 
@@ -90,26 +88,6 @@ class Person < Graphics::Body
90
88
  self.m += D_M unless m >= max
91
89
  end
92
90
 
93
- def draw
94
- if debug? and attack? then
95
- w.angle x, y, a-75, VISIBILITY, :yellow
96
- w.angle x, y, a-25, VISIBILITY, :yellow
97
- w.angle x, y, a+25, VISIBILITY, :yellow
98
- w.angle x, y, a+75, VISIBILITY, :yellow
99
- nearby.each do |o|
100
- w.line x, y, o.x, o.y, :yellow
101
- end
102
- # sleep 0.25 unless nearby.empty?
103
- end
104
-
105
- w.angle x, y, a, 20, :green
106
- w.angle x, y, ga, 10, :red
107
-
108
- # the blit looks HORRIBLE when rotated... dunno why
109
- w.blit w.body_img, x, y
110
- w.circle x, y, 5, :red, :filled if attack?
111
- end
112
-
113
91
  def turn_towards_goal
114
92
  turn a.relative_angle(ga, D_A)
115
93
  end
@@ -133,6 +111,30 @@ class Person < Graphics::Body
133
111
  self.a = (a + 180).degrees
134
112
  change_goal
135
113
  end
114
+
115
+ class View
116
+ def self.draw w, b
117
+ x, y, a, ga = b.x, b.y, b.a, b.ga
118
+
119
+ if b.debug? and b.attack? then
120
+ w.angle x, y, a-75, VISIBILITY, :yellow
121
+ w.angle x, y, a-25, VISIBILITY, :yellow
122
+ w.angle x, y, a+25, VISIBILITY, :yellow
123
+ w.angle x, y, a+75, VISIBILITY, :yellow
124
+ b.nearby.each do |o|
125
+ w.line x, y, o.x, o.y, :yellow
126
+ end
127
+ # sleep 0.25 unless nearby.empty?
128
+ end
129
+
130
+ w.angle x, y, a, 20, :green
131
+ w.angle x, y, ga, 10, :red
132
+
133
+ # the blit looks HORRIBLE when rotated... dunno why
134
+ w.blit w.body_img, x, y
135
+ w.circle x, y, 5, :red, :filled if b.attack?
136
+ end
137
+ end
136
138
  end
137
139
 
138
140
  class WalkerSimulation < Graphics::Simulation
@@ -142,6 +144,7 @@ class WalkerSimulation < Graphics::Simulation
142
144
  super 850, 850, 16, "Walker"
143
145
 
144
146
  self.ps = populate Person, 2
147
+ register_bodies ps
145
148
 
146
149
  # 5.times do |n|
147
150
  # ps[n].attack = true
@@ -168,7 +171,8 @@ class WalkerSimulation < Graphics::Simulation
168
171
  end
169
172
 
170
173
  def update n
171
- ps.each(&:update)
174
+ super
175
+
172
176
  detect_collisions(ps).each do |a, b|
173
177
  a.collide b
174
178
  end
@@ -177,9 +181,7 @@ class WalkerSimulation < Graphics::Simulation
177
181
  end
178
182
 
179
183
  def draw n
180
- clear
181
-
182
- ps.each(&:draw)
184
+ super
183
185
 
184
186
  debug "#{ps.size}"
185
187
  fps n
@@ -1,7 +1,5 @@
1
1
  #!/usr/local/bin/ruby -w
2
2
 
3
- srand 42
4
-
5
3
  require "graphics"
6
4
 
7
5
  class Entity
@@ -727,6 +727,12 @@ static VALUE Surface_transform(VALUE self, VALUE bgcolor, VALUE angle,
727
727
  return TypedData_Wrap_Struct(cSurface, &_Surface_type, result);
728
728
  }
729
729
 
730
+ static VALUE Surface_save(VALUE self, VALUE path) {
731
+ DEFINE_SELF(Surface, surface, self);
732
+
733
+ return INT2NUM(SDL_SaveBMP(surface, RSTRING_PTR(path)));
734
+ }
735
+
730
736
  //// SDL::TTFFont methods:
731
737
 
732
738
  static void _TTFFont_free(void* font) {
@@ -909,9 +915,10 @@ void Init_sdl() {
909
915
  rb_define_method(cSurface, "w", Surface_w, 0);
910
916
  rb_define_method(cSurface, "[]", Surface_index, 2);
911
917
  rb_define_method(cSurface, "[]=", Surface_index_equals, 3);
912
- rb_define_method(cSurface, "transform", Surface_transform, 5);
913
- rb_define_method(cSurface, "flags", Surface_flags, 0);
914
- rb_define_method(cSurface, "set_alpha", Surface_set_alpha, 2);
918
+ rb_define_method(cSurface, "transform", Surface_transform, 5);
919
+ rb_define_method(cSurface, "save", Surface_save, 1);
920
+ rb_define_method(cSurface, "flags", Surface_flags, 0);
921
+ rb_define_method(cSurface, "set_alpha", Surface_set_alpha, 2);
915
922
 
916
923
  //// SDL::TTFFont methods:
917
924
 
@@ -2514,3 +2514,14 @@ void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16
2514
2514
  sge_AABezierAlpha(surface,x1,y1,x2,y2,x3,y3,x4,y4,level, SDL_MapRGB(surface->format,R,G,B),255);
2515
2515
  }
2516
2516
 
2517
+ //==================================================================================
2518
+ // Added by zenspider:
2519
+ //==================================================================================
2520
+
2521
+ void sge_FastFilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color) {
2522
+ for (Sint16 y = y1; y <= y2; y++) {
2523
+ _HLine(Surface, x1, x2, y, color);
2524
+ }
2525
+
2526
+ sge_UpdateRect(Surface, x1, y1, x2, y2);
2527
+ }
@@ -105,6 +105,9 @@ DECLSPEC void sge_Bezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2,
105
105
  DECLSPEC void sge_BezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
106
106
  DECLSPEC void sge_AABezier(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B);
107
107
  DECLSPEC void sge_AABezierAlpha(SDL_Surface *surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,Sint16 x3, Sint16 y3, Sint16 x4, Sint16 y4, int level, Uint8 R, Uint8 G, Uint8 B, Uint8 alpha);
108
+
109
+ // Added by zenspider
110
+ DECLSPEC void sge_FastFilledRect(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
108
111
  #endif /* sge_C_ONLY */
109
112
 
110
113
 
@@ -2,8 +2,9 @@
2
2
  # The top-level namespace.
3
3
 
4
4
  class Graphics
5
- VERSION = "1.0.0b5" # :nodoc:
5
+ VERSION = "1.0.0b6" # :nodoc:
6
6
  end
7
7
 
8
8
  require "graphics/simulation"
9
9
  require "graphics/body"
10
+ require "graphics/decorators"
@@ -177,18 +177,18 @@ class Graphics::Body
177
177
  max_h, max_w = w.h, w.w
178
178
 
179
179
  if x < 0 then
180
- self.x = 0
180
+ self.x = x.abs
181
181
  return :west
182
182
  elsif x > max_w then
183
- self.x = max_w
183
+ self.x = 2 * max_w - x
184
184
  return :east
185
185
  end
186
186
 
187
187
  if y < 0 then
188
- self.y = 0
188
+ self.y = y.abs
189
189
  return :south
190
190
  elsif y > max_h then
191
- self.y = max_h
191
+ self.y = 2 * max_h - y
192
192
  return :north
193
193
  end
194
194
 
@@ -223,28 +223,13 @@ class Graphics::Body
223
223
 
224
224
  ##
225
225
  # Like clip, keep the body in bounds of the window, but set the
226
- # angle to the angle of reflection. Also slows momentum by 20%.
226
+ # angle to the angle of reflection. Also slows momentum by +friction+%.
227
227
 
228
- def bounce
229
- # TODO: rewrite this using clip + NORMAL to clean it up
230
- max_h, max_w = w.h, w.w
231
- normal = nil
232
-
233
- if x < 0 then
234
- self.x, normal = 0, 0
235
- elsif x > max_w then
236
- self.x, normal = max_w, 180
237
- end
238
-
239
- if y < 0 then
240
- self.y, normal = 0, 90
241
- elsif y > max_h then
242
- self.y, normal = max_h, 270
243
- end
244
-
245
- if normal then
246
- self.a = (2 * normal - 180 - a).degrees
247
- self.m *= 0.8
228
+ def bounce friction = 0.2
229
+ if wall = clip then
230
+ self.a = (2 * NORMAL[wall] - 180 - a).degrees
231
+ self.m *= (1.0 - friction) if friction and friction > 0
232
+ true
248
233
  end
249
234
  end
250
235
 
@@ -0,0 +1,21 @@
1
+ module ShowFPS
2
+ def draw n
3
+ super
4
+ fps n
5
+ end
6
+ end
7
+
8
+ module DrawGrid
9
+ def pre_draw n
10
+ super
11
+
12
+ (0...w).step(self.class::GRID_WIDTH).each do |x|
13
+ hline x, :gray
14
+ vline x, :gray
15
+ end
16
+ end
17
+ end
18
+
19
+ module WhiteBackground
20
+ CLEAR_COLOR = :white
21
+ end
@@ -0,0 +1,128 @@
1
+ class Graphics::Rainbow
2
+ attr_reader :cache
3
+
4
+ def initialize
5
+ @cache = self.cache_colors
6
+ end
7
+
8
+ def clamp d, min, max
9
+ [[min, d].max, max].min
10
+ end
11
+
12
+ ##
13
+ # Takes a value and a range,
14
+ # and scales that range to 0-360
15
+ def scale d, min, max
16
+ range = max - min
17
+ if range != 0
18
+ scaled = (d.to_f / range) * 360
19
+ return clamp(scaled, 0, 360).round
20
+ else
21
+ 0
22
+ end
23
+ end
24
+
25
+ def cache_colors
26
+ # Saves all the colors to a hash
27
+ cache = {}
28
+ (0..360).each do |degree|
29
+ cache[degree] = _color degree
30
+ end
31
+ cache
32
+ end
33
+
34
+ def color d, min=0, max=360
35
+ scaled = scale d, min, max
36
+ @cache[scaled]
37
+ end
38
+
39
+ def _color degree
40
+ raise "Subclass responsibility"
41
+ end
42
+ private :_color
43
+ end
44
+
45
+ ##
46
+ # Black to white gradient
47
+ #
48
+ class Graphics::Greyscale < Graphics::Rainbow
49
+ def initialize
50
+ super
51
+ end
52
+
53
+ def _color degree
54
+ brightness_unit = degree/360.0
55
+ brightness = (brightness_unit*255.0).floor # Scale back to RGB
56
+
57
+ [brightness, brightness, brightness]
58
+ end
59
+ end
60
+
61
+ ##
62
+ # The full RGB spectrum
63
+ #
64
+ class Graphics::Hue < Graphics::Rainbow
65
+
66
+ def initialize
67
+ super
68
+ end
69
+
70
+ def _color degree
71
+ main_color = 1 * 255 # Let chroma (saturation * brightness) always == 1
72
+ second_strongest_color = ((1 - (degree/60.0 % 2 - 1).abs) * 255).floor
73
+
74
+ case degree
75
+ when 0..60
76
+ [main_color, second_strongest_color, 0]
77
+ when 61..120
78
+ [second_strongest_color, main_color, 0]
79
+ when 121..180
80
+ [0, main_color, second_strongest_color]
81
+ when 181..240
82
+ [0, second_strongest_color, main_color]
83
+ when 241..300
84
+ [second_strongest_color, 0, main_color]
85
+ when 301..360
86
+ [main_color, 0, second_strongest_color]
87
+ end
88
+ end
89
+ end
90
+
91
+
92
+ ##
93
+ # Spectrum with linearly increasing brightness
94
+ #
95
+ class Graphics::Cubehelix < Graphics::Rainbow
96
+
97
+ def initialize
98
+ super
99
+ end
100
+
101
+ def _color degree
102
+ d = degree/360.0
103
+ start = 0.5 # Starting position in color space - 0=blue, 1=red, 2=green
104
+ rotations = -1.5 # How many rotations through the rainbow?
105
+ saturation = 1.2
106
+ gamma = 1.0
107
+ fract = d**gamma # Position on the spectrum
108
+
109
+ # Amplitude of the helix
110
+ amp = saturation * fract * (1 - fract) / 2.0
111
+ angle = 2*Math::PI*(start/3.0 + 1.0 + rotations*fract)
112
+ # From the CubeHelix Equations
113
+ r = fract + amp * (-0.14861 * Math.cos(angle) + 1.78277 * Math.sin(angle))
114
+ g = fract + amp * (-0.29227 * Math.cos(angle) - 0.90649 * Math.sin(angle))
115
+ b = fract + amp * (1.97294 * Math.cos(angle))
116
+
117
+ [(r * 255).round, (g * 255).round, (b * 255).round]
118
+ end
119
+ end
120
+
121
+ class Graphics::Simulation
122
+ def initialize_rainbow rainbow, name
123
+ rainbow.cache.each do |degree, color|
124
+ color_name = "#{name}_#{degree}".to_sym
125
+ self.register_color(color_name, *color, 255)
126
+ end
127
+ end
128
+ end
@@ -5,10 +5,12 @@ require "sdl/sdl"
5
5
  module SDL; end # :nodoc: -- stupid rdoc :(
6
6
 
7
7
  ##
8
- # A simulation. This ties everything together and provides a bunch of
9
- # convenience methods to make life easier.
8
+ # An abstract simulation. See Graphics::Simulation and Graphics::Drawing.
10
9
 
11
- class Graphics::Simulation
10
+ class Graphics::AbstractSimulation
11
+
12
+ # The default color to clear the screen.
13
+ CLEAR_COLOR = :black
12
14
 
13
15
  # degrees to radians
14
16
  D2R = Math::PI / 180.0
@@ -19,6 +21,9 @@ class Graphics::Simulation
19
21
  # Call +log+ every N ticks, if +log+ is defined.
20
22
  LOG_INTERVAL = 60
21
23
 
24
+ # Collection of collections of Bodies to auto-update and draw.
25
+ attr_accessor :_bodies
26
+
22
27
  # The window the simulation is drawing in.
23
28
  attr_accessor :screen
24
29
 
@@ -49,6 +54,9 @@ class Graphics::Simulation
49
54
  # Procs registered to handle keydown events.
50
55
  attr_accessor :keydown_handler
51
56
 
57
+ # Is the application done?
58
+ attr_accessor :done
59
+
52
60
  ##
53
61
  # Create a new simulation of a certain width and height. Optionally,
54
62
  # you can set the bits per pixel (0 for current screen settings),
@@ -61,11 +69,13 @@ class Graphics::Simulation
61
69
 
62
70
  full = full ? SDL::FULLSCREEN : 0
63
71
 
72
+ self._bodies = []
73
+
64
74
  self.font = find_font("Menlo", 32)
65
75
 
66
76
  SDL::WM.set_caption name, name
67
77
 
68
- self.screen = SDL::Screen.open w, h, bpp, SDL::HWSURFACE|SDL::DOUBLEBUF|full
78
+ self.screen = SDL::Screen.open w, h, bpp, self.class::SCREEN_FLAGS|full
69
79
  self.w, self.h = screen.w, screen.h
70
80
 
71
81
  self.color = {}
@@ -85,8 +95,8 @@ class Graphics::Simulation
85
95
  # Register default key events. Handles ESC & Q (quit) and P (pause).
86
96
 
87
97
  def initialize_keys
88
- add_keydown_handler("\e") { exit }
89
- add_keydown_handler("q") { exit }
98
+ add_keydown_handler("\e") { self.done = true }
99
+ add_keydown_handler("q") { self.done = true }
90
100
  add_keydown_handler("p") { self.paused = !paused }
91
101
  add_keydown_handler("/") { self.iter_per_tick += 1 }
92
102
  add_keydown_handler("-") { self.iter_per_tick -= 1; self.iter_per_tick = 1 if iter_per_tick < 1 }
@@ -95,10 +105,12 @@ class Graphics::Simulation
95
105
  def initialize_colors # :nodoc:
96
106
  register_color :black, 0, 0, 0
97
107
  register_color :white, 255, 255, 255
108
+ register_color :gray, 127, 127, 127
98
109
  register_color :red, 255, 0, 0
99
110
  register_color :green, 0, 255, 0
100
111
  register_color :blue, 0, 0, 255
101
- register_color :gray, 127, 127, 127
112
+ register_color :cyan, 0, 255, 255
113
+ register_color :magenta, 255, 0, 255
102
114
  register_color :yellow, 255, 255, 0
103
115
  register_color :alpha, 0, 0, 0, 0
104
116
 
@@ -108,6 +120,20 @@ class Graphics::Simulation
108
120
  register_color(("red%02d" % n).to_sym, m, 0, 0)
109
121
  register_color(("green%02d" % n).to_sym, 0, m, 0)
110
122
  register_color(("blue%02d" % n).to_sym, 0, 0, m)
123
+ register_color(("cyan%02d" % n).to_sym, 0, m, m)
124
+ register_color(("magenta%02d" % n).to_sym, m, 0, m)
125
+ register_color(("yellow%02d" % n).to_sym, m, m, 0)
126
+ end
127
+
128
+ (0...256).each do |n|
129
+ m = (256 * n / 255.0).to_i
130
+ register_color(("gray%03d" % n).to_sym, m, m, m)
131
+ register_color(("red%03d" % n).to_sym, m, 0, 0)
132
+ register_color(("green%03d" % n).to_sym, 0, m, 0)
133
+ register_color(("blue%03d" % n).to_sym, 0, 0, m)
134
+ register_color(("cyan%03d" % n).to_sym, 0, m, m)
135
+ register_color(("magenta%03d" % n).to_sym, m, 0, m)
136
+ register_color(("yellow%03d" % n).to_sym, m, m, 0)
111
137
  end
112
138
  end
113
139
 
@@ -127,6 +153,22 @@ class Graphics::Simulation
127
153
  SDL::TTF.open(font, size)
128
154
  end
129
155
 
156
+ ##
157
+ # Register a collection of bodies to be auto-updated and drawn.
158
+
159
+ def register_bodies ary
160
+ _bodies << ary
161
+ ary
162
+ end
163
+
164
+ ##
165
+ # Register a single Body to be auto-updated and drawn.
166
+
167
+ def register_body obj
168
+ _bodies << [obj]
169
+ obj
170
+ end
171
+
130
172
  ##
131
173
  # Name a color w/ rgba values.
132
174
 
@@ -203,6 +245,7 @@ class Graphics::Simulation
203
245
  self.start_time = Time.now
204
246
  n = 0
205
247
  event = nil
248
+ self.done = false
206
249
 
207
250
  logger = respond_to? :log
208
251
  log_interval = self.class::LOG_INTERVAL
@@ -217,6 +260,8 @@ class Graphics::Simulation
217
260
  draw_and_flip n
218
261
 
219
262
  log if logger and n % log_interval == 0
263
+
264
+ break if done
220
265
  end
221
266
  end
222
267
 
@@ -226,25 +271,54 @@ class Graphics::Simulation
226
271
  end
227
272
 
228
273
  ##
229
- # Draw the scene. This is a subclass responsibility and must draw
230
- # the entire window (including calling clear).
274
+ # Draw the scene by clearing the window and drawing all registered
275
+ # bodies. You are free to completely override this or call super and
276
+ # add any extras at the end.
231
277
 
232
278
  def draw n
233
- raise NotImplementedError, "Subclass Responsibility"
279
+ pre_draw n
280
+ post_draw n
281
+ end
282
+
283
+ def pre_draw n
284
+ clear
285
+ end
286
+
287
+ def post_draw n
288
+ _bodies.each do |ary|
289
+ draw_collection ary
290
+ end
291
+ end
292
+
293
+ ##
294
+ # Draw a homogeneous collection of bodies. This assumes that the MVC
295
+ # pattern described on this class is being used.
296
+
297
+ def draw_collection ary
298
+ return if ary.empty?
299
+
300
+ cls = ary.first.class.const_get :View
301
+
302
+ ary.each do |obj|
303
+ cls.draw self, obj
304
+ end
234
305
  end
235
306
 
236
307
  ##
237
- # Update the simulation. This does nothing by default and must be
238
- # overridden by the subclass.
308
+ # Update the simulation by telling all registered bodies to update.
309
+ # You are free to completely override this or call super and add any
310
+ # extras at the end.
239
311
 
240
312
  def update n
241
- # do nothing
313
+ _bodies.each do |ary|
314
+ ary.each(&:update)
315
+ end
242
316
  end
243
317
 
244
318
  ##
245
- # Clear the whole screen
319
+ # Clear the whole screen. Defaults to CLEAR_COLOR.
246
320
 
247
- def clear c = :black
321
+ def clear c = self.class::CLEAR_COLOR
248
322
  fast_rect 0, 0, w, h, c
249
323
  end
250
324
 
@@ -454,6 +528,13 @@ class Graphics::Simulation
454
528
  SDL::Surface.blit img, 0, 0, 0, 0, screen, x-1, h-y-img.h
455
529
  end
456
530
 
531
+ ##
532
+ # Save the current screen to a bmp
533
+
534
+ def save path
535
+ screen.save path
536
+ end
537
+
457
538
  ##
458
539
  # Create a new sprite with a given width and height and yield to a
459
540
  # block with the new sprite as the current screen. All drawing
@@ -477,6 +558,49 @@ class Graphics::Simulation
477
558
  end
478
559
  end
479
560
 
561
+ ##
562
+ # A simulation. This ties everything together and provides a bunch of
563
+ # convenience methods to make life easier.
564
+ #
565
+ # In the Model View Controller (MVC) pattern, the simulation is the
566
+ # Controller and controls both the window and all bodies involved in
567
+ # the simulation. The bodies are the Model and each body class is
568
+ # expected to have an inner View class w/ a #draw class method for the
569
+ # View.
570
+ #
571
+ # For example, in examples/bounce.rb:
572
+ #
573
+ # + BounceSimulation subclasses Graphics::Simulation
574
+ # + BounceSimulation has many Balls
575
+ # + Ball#update maintains all ball movement.
576
+ # + BounceSimulation#draw automatically calls Ball::View.draw on all balls.
577
+ # + Ball::View.draw takes a window and a ball and draws it.
578
+
579
+ class Graphics::Simulation < Graphics::AbstractSimulation
580
+ SCREEN_FLAGS = SDL::HWSURFACE|SDL::DOUBLEBUF
581
+ end
582
+
583
+ ##
584
+ # A drawing. Like a Simulation, but on a canvas that doesn't have
585
+ # double buffering or clearing on each tick.
586
+ #
587
+ # See AbstractSimulation for most methods.
588
+
589
+ class Graphics::Drawing < Graphics::AbstractSimulation
590
+ SCREEN_FLAGS = SDL::HWSURFACE
591
+
592
+ def initialize(*a)
593
+ super
594
+
595
+ clear
596
+ end
597
+
598
+ def draw_and_flip n
599
+ screen.update 0, 0, 0, 0
600
+ # no flip
601
+ end
602
+ end
603
+
480
604
  if $0 == __FILE__ then
481
605
  SDL.init SDL::INIT_EVERYTHING
482
606
  SDL.set_video_mode(640, 480, 16, SDL::SWSURFACE)