graphics 1.0.0b1

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.
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##
4
+ # A simple "trail" class, that draws the path of a in a particular hue.
5
+ #
6
+ # # ... in initialize
7
+ # self.trail = Trail.new self, 100, :white
8
+ #
9
+ # # ... in Body#update
10
+ # trail << body
11
+ #
12
+ # # ... in Body#draw
13
+ # trail.draw
14
+
15
+ class Graphics::Trail
16
+ @@c = {}
17
+
18
+ ##
19
+ # The array of x/y coordinates of the trail.
20
+
21
+ attr_accessor :a
22
+
23
+ ##
24
+ # The windowing system we're drawing in.
25
+
26
+ attr_accessor :w
27
+
28
+ ##
29
+ # The maximum number of segments to keep in the trail.
30
+
31
+ attr_accessor :max
32
+
33
+ ##
34
+ # The hues to draw in the trail.
35
+
36
+ attr_accessor :c
37
+
38
+ ##
39
+ # Create a Trail with +max+ length and of a particular +color+ hue.
40
+
41
+ def initialize w, max, color = :green
42
+ self.w = w
43
+ self.a = []
44
+ self.max = max
45
+ unless @@c[color] then
46
+ @@c[color] ||= (0..99).map { |n| ("%s%02d" % [color, n]).to_sym }.reverse
47
+ end
48
+ self.c = @@c[color]
49
+ end
50
+
51
+ ##
52
+ # Draw the trail and taper off the color as we go.
53
+
54
+ def draw
55
+ m = 100.0 / max
56
+ a.reverse_each.each_cons(2).with_index do |((x1, y1), (x2, y2)), i|
57
+ w.line x1, y1, x2, y2, c[(i*m).round] || :black
58
+ end
59
+ end
60
+
61
+ ##
62
+ # Add another segment to the trail, and remove a segment if needed.
63
+
64
+ def << body
65
+ a << [body.x, body.y]
66
+ a.shift if a.size > max
67
+ nil
68
+ end
69
+ end
@@ -0,0 +1,71 @@
1
+ ##
2
+ # Simple and fast 2 dimensional vector
3
+
4
+ class V
5
+ # x coordinate accessors -- preferably float
6
+ attr_accessor :x
7
+ # y coordinate accessors -- preferably float
8
+ attr_accessor :y
9
+
10
+ class << self
11
+ alias :[] :new # :nodoc:
12
+ end
13
+
14
+ ##
15
+ # Create a new vector with x & y coordinates.
16
+
17
+ def initialize x, y
18
+ @x = x
19
+ @y = y
20
+ end
21
+
22
+ # zero vector
23
+ ZERO = V[0.0, 0.0]
24
+
25
+ # one vector
26
+ ONE = V[1.0, 1.0]
27
+
28
+ ##
29
+ # Add two vectors, returning a new vector.
30
+
31
+ def + v
32
+ V[x+v.x, y+v.y]
33
+ end
34
+
35
+ ##
36
+ # Subtract two vectors, returning a new vector.
37
+
38
+ def - v
39
+ V[x-v.x, y-v.y]
40
+ end
41
+
42
+ ##
43
+ # Multiply a vector by a scalar, returning a new vector.
44
+
45
+ def * s
46
+ V[x*s, y*s]
47
+ end
48
+
49
+ ##
50
+ # Divide a vector by a scalar, returning a new vector.
51
+
52
+ def / s
53
+ V[x/s, y/s]
54
+ end
55
+
56
+ def == other # :nodoc:
57
+ x == other.x && y == other.y
58
+ end
59
+
60
+ ##
61
+ # Return the length of the vector from the origin.
62
+
63
+ def magnitude
64
+ Math.sqrt(x*x + y*y)
65
+ end
66
+
67
+ def inspect # :nodoc:
68
+ "#{self.class.name}[%.2f, %.2f]" % [x, y]
69
+ end
70
+ alias to_s inspect # :nodoc:
71
+ end
Binary file
@@ -0,0 +1,34 @@
1
+ #!/bin/sh
2
+
3
+ brew uninstall libogg
4
+ brew uninstall libvorbis
5
+ brew uninstall libpng
6
+
7
+ brew uninstall sdl
8
+ brew uninstall sdl_ttf
9
+ brew uninstall sdl_mixer
10
+ brew uninstall sdl_image
11
+ brew uninstall sge
12
+
13
+ # brew update
14
+
15
+ brew install libogg
16
+ brew install libvorbis
17
+ brew install libpng
18
+
19
+ brew install sdl
20
+ brew install sdl_mixer -- --with-libvorbis
21
+ brew install sdl_ttf
22
+ brew install sdl_image
23
+
24
+ gem uninstall -ax rsdl
25
+ gem uninstall -ax rubysdl
26
+
27
+ gem install rsdl
28
+ gem install rubysdl -- --enable-bundled-sge
29
+
30
+ ruby -r sdl -e 'p [:ttf, SDL.constants.include?(:TTF)]'
31
+ ruby -r sdl -e 'p [:mixer, SDL.constants.include?(:Mixer)]'
32
+ ruby -r sdl -e 'p [:sge, SDL.respond_to?(:auto_lock)]'
33
+
34
+ rsdl -r sdl -e 'SDL.init(SDL::INIT_EVERYTHING); SDL.set_video_mode(640, 480, 16, SDL::SWSURFACE); sleep(1)'
@@ -0,0 +1,408 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "minitest/autorun"
4
+
5
+ $: << File.expand_path("~/Work/p4/zss/src/minitest-focus/dev/lib")
6
+ require "minitest/focus"
7
+
8
+ require "graphics"
9
+
10
+ class TestBody < Minitest::Test
11
+ attr_accessor :w, :b
12
+
13
+ FakeSimulation = Struct.new(:w, :h)
14
+
15
+ def assert_body x, y, m, a, ga, b
16
+ assert_in_delta x, b.x, 0.001, "x"
17
+ assert_in_delta y, b.y, 0.001, "y"
18
+ assert_in_delta m, b.m, 0.001, "m"
19
+ assert_in_delta a, b.a, 0.001, "a"
20
+ assert_in_delta ga, b.ga, 0.001, "ga"
21
+ end
22
+
23
+ def setup
24
+ self.w = FakeSimulation.new(100, 100)
25
+ self.b = Graphics::Body.new w
26
+
27
+ b.x = 50
28
+ b.y = 50
29
+ b.m = 10
30
+ b.a = 0
31
+ end
32
+
33
+ def test_conversions_readers
34
+ assert_equal V[50, 50], b.position
35
+ assert_equal V[10, 0], b.velocity
36
+ end
37
+
38
+ def test_conversions_pos
39
+ b.position = V[50, 40]
40
+ assert_in_delta 50, b.x
41
+ assert_in_delta 40, b.y
42
+ end
43
+
44
+ def test_conversions_vel_0
45
+ b.velocity = V[10, 0]
46
+ assert_in_delta 10, b.m, 0.001, "magnitude"
47
+ assert_in_delta 0, b.a, 0.001, "angle"
48
+ assert_equal V[10, 0], b.velocity
49
+ end
50
+
51
+ def test_conversions_vel_90
52
+ b.velocity = V[0, 10]
53
+ assert_in_delta 10, b.m, 0.001, "magnitude"
54
+ assert_in_delta 90, b.a, 0.001, "angle"
55
+ end
56
+
57
+ def test_conversions_vel_180
58
+ b.velocity = V[-10, 0]
59
+ assert_in_delta 10, b.m, 0.001, "magnitude"
60
+ assert_in_delta 180, b.a, 0.001, "angle"
61
+ end
62
+
63
+ def test_conversions_vel_270
64
+ b.velocity = V[0, -10]
65
+ assert_in_delta 10, b.m, 0.001, "magnitude"
66
+ assert_in_delta(-90, b.a, 0.001, "angle")
67
+ end
68
+
69
+ def test_conversions_vel_45
70
+ b.velocity = V[10, 10]
71
+ assert_in_delta 10, b.velocity.x
72
+ assert_in_delta 10, b.velocity.y
73
+
74
+ assert_in_delta 14.142, b.m, 0.001, "magnitude"
75
+ assert_in_delta 45, b.a, 0.001, "angle"
76
+ end
77
+
78
+ def test_dx_dy
79
+ exp = 14.142
80
+
81
+ b.velocity = V[10, 10]
82
+
83
+ assert_in_delta 45, b.a
84
+ assert_in_delta exp, b.m
85
+
86
+ assert_in_delta 10, b.dx_dy[0]
87
+ assert_in_delta 10, b.dx_dy[1]
88
+
89
+ b.a = 45
90
+ b.m = 10
91
+
92
+ dx, dy = b.dx_dy
93
+
94
+ assert_in_delta exp/2, dx
95
+ assert_in_delta exp/2, dy
96
+ end
97
+
98
+ def test_m_a
99
+ b.velocity = V[10, 10]
100
+
101
+ assert_in_delta 14.142, b.m
102
+ assert_in_delta 45, b.a
103
+
104
+ assert_in_delta 14.142, b.m_a[0]
105
+ assert_in_delta 45, b.m_a[1]
106
+ end
107
+
108
+ def test_bounce
109
+ b.x = 99
110
+ b.a = 45
111
+
112
+ assert_body 99, 50, 10, 45, 0, b
113
+
114
+ b.move
115
+ b.bounce
116
+
117
+ assert_body 100, w.h-42.929, 8, 135, 0, b
118
+ end
119
+
120
+ def test_clip
121
+ b.x = 99
122
+
123
+ assert_body 99, 50, 10, 0, 0, b
124
+
125
+ b.move
126
+ b.clip
127
+
128
+ assert_body 100, 50, 10, 0, 0, b
129
+ end
130
+
131
+ def test_clip_off_wall
132
+ b.x = 99
133
+
134
+ assert_body 99, 50, 10, 0, 0, b
135
+
136
+ srand 42
137
+ b.move
138
+ b.clip_off_wall
139
+
140
+ assert_body 100, 50, 10, 0, 186, b
141
+ end
142
+
143
+ def test_move
144
+ assert_body 50, 50, 10, 0, 0, b
145
+
146
+ b.move
147
+
148
+ assert_body 60, 50, 10, 0, 0, b
149
+ end
150
+
151
+ def test_move_by
152
+ assert_body 50, 50, 10, 0, 0, b
153
+
154
+ b.move_by 180, 10
155
+
156
+ assert_body 40, 50, 10, 0, 0, b
157
+ end
158
+
159
+ def test_random_angle
160
+ srand 42
161
+
162
+ assert_in_delta 134.834, b.random_angle
163
+
164
+ assert_body 50, 50, 10, 0, 0, b
165
+ end
166
+
167
+ def test_random_turn
168
+ srand 42
169
+
170
+ assert_in_delta 16, b.random_turn(45)
171
+
172
+ assert_body 50, 50, 10, 0, 0, b
173
+ end
174
+
175
+ def test_turn
176
+ assert_body 50, 50, 10, 0, 0, b
177
+
178
+ b.turn 90
179
+
180
+ assert_body 50, 50, 10, 90, 0, b
181
+ end
182
+
183
+ def test_wrap
184
+ b.x = 99
185
+
186
+ assert_body 99, 50, 10, 0, 0, b
187
+
188
+ b.move
189
+ b.wrap
190
+
191
+ assert_body 0, 50, 10, 0, 0, b # TODO: maybe should be 9?
192
+ end
193
+ end
194
+
195
+ class TestInteger < Minitest::Test
196
+ def test_match
197
+ srand 42
198
+ assert_equal [0, 1], 2.times.map { rand(2) }
199
+
200
+ srand 42
201
+ assert(1 =~ 2)
202
+ refute(1 =~ 2)
203
+ end
204
+ end
205
+
206
+ class TestNumeric < Minitest::Test
207
+ def test_close_to
208
+ assert_operator 1.0001, :close_to?, 1.0002
209
+ refute_operator 1.0001, :close_to?, 2.0002
210
+ end
211
+
212
+ def test_degrees
213
+ assert_equal 1, 361.degrees
214
+ assert_equal 359, -1.degrees
215
+ end
216
+
217
+ def test_relative_angle
218
+ assert_equal 10, 0.relative_angle(10, 20)
219
+ assert_equal 5, 0.relative_angle(10, 5)
220
+
221
+ assert_equal 180, 180.relative_angle(0, 360)
222
+ assert_equal 185, 0.relative_angle(185, 360) # huh?
223
+
224
+ assert_equal(-180, 0.relative_angle(270, 180)) # Huh?
225
+ end
226
+ end
227
+
228
+ class TestSimulation < Minitest::Test
229
+ # make_my_diffs_pretty!
230
+
231
+ class FakeSimulation < Graphics::Simulation
232
+ def initialize
233
+ super 100, 100, 16, "blah"
234
+
235
+ s = []
236
+
237
+ def s.method_missing(*a)
238
+ @data ||= []
239
+ @data << a
240
+ end
241
+
242
+ def s.data
243
+ @data
244
+ end
245
+
246
+ self.screen = s
247
+
248
+ end
249
+ end
250
+
251
+ attr_accessor :t, :white, :exp
252
+
253
+ def setup
254
+ self.t = FakeSimulation.new
255
+ self.white = t.color[:white]
256
+ self.exp = []
257
+ end
258
+
259
+ def test_angle
260
+ t.angle 50, 50, 0, 10, :white
261
+ exp << [:draw_line, 50, 50, 60.0, 50.0, white, :antialiased]
262
+
263
+ t.angle 50, 50, 90, 10, :white
264
+ exp << [:draw_line, 50, 50, 50.0, 40.0, white, :antialiased]
265
+
266
+ t.angle 50, 50, 180, 10, :white
267
+ exp << [:draw_line, 50, 50, 40.0, 50.0, white, :antialiased]
268
+
269
+ t.angle 50, 50, 270, 10, :white
270
+ exp << [:draw_line, 50, 50, 50.0, 60.0, white, :antialiased]
271
+
272
+ t.angle 50, 50, 45, 10, :white
273
+ d45 = 10 * Math.sqrt(2) / 2
274
+ exp << [:draw_line, 50, 50, 50+d45, 50-d45, white, :antialiased]
275
+
276
+ assert_equal exp, t.screen.data
277
+ end
278
+
279
+ # def test_bezier
280
+ # raise NotImplementedError, 'Need to write test_bezier'
281
+ # end
282
+ #
283
+ # def test_blit
284
+ # raise NotImplementedError, 'Need to write test_blit'
285
+ # end
286
+ #
287
+ # def test_circle
288
+ # raise NotImplementedError, 'Need to write test_circle'
289
+ # end
290
+ #
291
+ # def test_clear
292
+ # raise NotImplementedError, 'Need to write test_clear'
293
+ # end
294
+ #
295
+ # def test_debug
296
+ # raise NotImplementedError, 'Need to write test_debug'
297
+ # end
298
+ #
299
+ # def test_draw
300
+ # raise NotImplementedError, 'Need to write test_draw'
301
+ # end
302
+ #
303
+ # def test_draw_and_flip
304
+ # raise NotImplementedError, 'Need to write test_draw_and_flip'
305
+ # end
306
+
307
+ def test_ellipse
308
+ t.ellipse 0, 0, 25, 25, :white
309
+ exp << [:draw_ellipse, 0, t.h-0, 25, 25, t.color[:white], false, :antialiased]
310
+
311
+ assert_equal exp, t.screen.data
312
+ end
313
+
314
+ # def test_fast_rect
315
+ # raise NotImplementedError, 'Need to write test_fast_rect'
316
+ # end
317
+ #
318
+ # def test_fps
319
+ # raise NotImplementedError, 'Need to write test_fps'
320
+ # end
321
+ #
322
+ # def test_handle_event
323
+ # raise NotImplementedError, 'Need to write test_handle_event'
324
+ # end
325
+ #
326
+ # def test_handle_keys
327
+ # raise NotImplementedError, 'Need to write test_handle_keys'
328
+ # end
329
+
330
+ def test_hline
331
+ t.hline 42, :white
332
+ h = t.h
333
+ exp << [:draw_line, 0, h-42, 100, h-42, t.color[:white], :antialiased]
334
+
335
+ assert_equal exp, t.screen.data
336
+ end
337
+
338
+ # def test_image
339
+ # raise NotImplementedError, 'Need to write test_image'
340
+ # end
341
+
342
+ def test_line
343
+ t.line 0, 0, 25, 25, :white
344
+ h = t.h
345
+ exp << [:draw_line, 0, h-0, 25, h-25, t.color[:white], :antialiased]
346
+
347
+ assert_equal exp, t.screen.data
348
+ end
349
+
350
+ def test_point
351
+ t.point 2, 10, :white
352
+
353
+ exp = [nil, nil, t.color[:white]]
354
+ assert_equal exp, t.screen
355
+
356
+ skip "This test isn't sufficient"
357
+ end
358
+
359
+ # def test_populate
360
+ # raise NotImplementedError, 'Need to write test_populate'
361
+ # end
362
+ #
363
+ # def test_rect
364
+ # raise NotImplementedError, 'Need to write test_rect'
365
+ # end
366
+ #
367
+ # def test_register_color
368
+ # raise NotImplementedError, 'Need to write test_register_color'
369
+ # end
370
+ #
371
+ # def test_render_text
372
+ # raise NotImplementedError, 'Need to write test_render_text'
373
+ # end
374
+ #
375
+ # def test_run
376
+ # raise NotImplementedError, 'Need to write test_run'
377
+ # end
378
+ #
379
+ # def test_sprite
380
+ # raise NotImplementedError, 'Need to write test_sprite'
381
+ # end
382
+ #
383
+ # def test_text
384
+ # raise NotImplementedError, 'Need to write test_text'
385
+ # end
386
+ #
387
+ # def test_text_size
388
+ # raise NotImplementedError, 'Need to write test_text_size'
389
+ # end
390
+ #
391
+ # def test_update
392
+ # raise NotImplementedError, 'Need to write test_update'
393
+ # end
394
+ #
395
+ # def test_vline
396
+ # raise NotImplementedError, 'Need to write test_vline'
397
+ # end
398
+ end
399
+
400
+ # class TestTrail < Minitest::Test
401
+ # def test_draw
402
+ # raise NotImplementedError, 'Need to write test_draw'
403
+ # end
404
+ #
405
+ # def test_lt2
406
+ # raise NotImplementedError, 'Need to write test_lt2'
407
+ # end
408
+ # end