graphics 1.0.0b5 → 1.0.0b6

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