ray 0.0.0.pre2 → 0.0.1

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.
Files changed (76) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +3 -0
  3. data/README.md +62 -0
  4. data/Rakefile +33 -23
  5. data/VERSION +1 -1
  6. data/ext/audio.c +473 -0
  7. data/ext/color.c +4 -4
  8. data/ext/event.c +25 -3
  9. data/ext/extconf.rb +35 -22
  10. data/ext/font.c +287 -0
  11. data/ext/image.c +682 -33
  12. data/ext/joystick.c +9 -9
  13. data/ext/ray.c +166 -55
  14. data/ext/ray.h +120 -9
  15. data/ext/ray_osx.m +161 -0
  16. data/ext/rect.c +31 -4
  17. data/lib/ray/audio.rb +52 -0
  18. data/lib/ray/color.rb +16 -0
  19. data/lib/ray/dsl.rb +1 -3
  20. data/lib/ray/dsl/event.rb +1 -39
  21. data/lib/ray/dsl/event_listener.rb +38 -0
  22. data/lib/ray/dsl/event_runner.rb +3 -1
  23. data/lib/ray/dsl/event_translator.rb +74 -8
  24. data/lib/ray/dsl/handler.rb +3 -33
  25. data/lib/ray/dsl/matcher.rb +129 -23
  26. data/lib/ray/font.rb +108 -0
  27. data/lib/ray/font_set.rb +37 -0
  28. data/lib/ray/game.rb +171 -34
  29. data/lib/ray/helper.rb +43 -5
  30. data/lib/ray/image.rb +90 -3
  31. data/lib/ray/image_set.rb +35 -0
  32. data/lib/ray/joystick.rb +30 -0
  33. data/lib/ray/music_set.rb +35 -0
  34. data/lib/ray/ray.rb +17 -9
  35. data/lib/ray/rect.rb +51 -0
  36. data/lib/ray/resource_set.rb +92 -0
  37. data/lib/ray/scene.rb +220 -51
  38. data/lib/ray/sound_set.rb +35 -0
  39. data/lib/ray/sprite.rb +184 -0
  40. data/psp/ext.c +4 -0
  41. data/samples/hello_world/hello.rb +35 -0
  42. data/samples/hello_world/hello_dsl.rb +24 -0
  43. data/samples/pong/pong.rb +128 -0
  44. data/samples/sokoban/level_1 +7 -0
  45. data/samples/sokoban/sokoban.rb +370 -0
  46. data/spec/ray/audio_spec.rb +146 -0
  47. data/spec/ray/color_spec.rb +13 -0
  48. data/spec/ray/event_spec.rb +57 -168
  49. data/spec/ray/font_spec.rb +93 -0
  50. data/spec/ray/image_set_spec.rb +48 -0
  51. data/spec/ray/image_spec.rb +130 -44
  52. data/spec/ray/joystick_spec.rb +13 -9
  53. data/spec/ray/matcher_spec.rb +32 -55
  54. data/spec/ray/ray_spec.rb +33 -31
  55. data/spec/ray/rect_spec.rb +80 -0
  56. data/spec/ray/resource_set_spec.rb +105 -0
  57. data/spec/ray/sprite_spec.rb +163 -0
  58. data/spec/res/VeraMono.ttf +0 -0
  59. data/spec/res/aqua2.bmp +0 -0
  60. data/spec/res/pop.wav +0 -0
  61. data/spec/spec.opts +4 -0
  62. data/spec/spec_helper.rb +8 -0
  63. data/yard_ext.rb +91 -0
  64. metadata +104 -38
  65. data/bin/ray +0 -5
  66. data/bin/ray_irb +0 -4
  67. data/ext/SDLMain.h +0 -17
  68. data/ext/SDLMain.m +0 -381
  69. data/lib/ray/config.rb +0 -84
  70. data/lib/ray/dsl/converter.rb +0 -65
  71. data/lib/ray/dsl/listener.rb +0 -30
  72. data/lib/ray/dsl/type.rb +0 -58
  73. data/spec/ray/config_spec.rb +0 -90
  74. data/spec/ray/conversion_spec.rb +0 -43
  75. data/spec/ray/type_spec.rb +0 -17
  76. data/spec_runner.rb +0 -27
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ if Ray.has_audio_support?
4
+ describe Ray::Audio do
5
+ it "should allow to set and get audio parameters" do
6
+ Ray.init(:mono => true,
7
+ :format => Ray::Audio::FORMAT_S8,
8
+ :frequency => 44100)
9
+
10
+ Ray::Audio.frequency.should == 44100
11
+ Ray::Audio.should be_mono
12
+ Ray::Audio.format.should == Ray::Audio::FORMAT_S8
13
+
14
+ Ray.stop
15
+ end
16
+
17
+ it "should allow to change the volume" do
18
+ Ray.init(:mono => true,
19
+ :format => Ray::Audio::FORMAT_S8,
20
+ :frequency => 44100)
21
+
22
+ Ray::Audio.volume = 50
23
+ Ray::Audio.volume.should be_close(50, 0.1)
24
+
25
+ Ray.stop
26
+ end
27
+ end
28
+
29
+ describe Ray::Sound do
30
+ before :all do
31
+ Ray.init
32
+ end
33
+
34
+ it "should allow to load sounds" do
35
+ lambda {
36
+ Ray::Sound.new(path_of("pop.wav"))
37
+ }.should_not raise_exception
38
+ end
39
+
40
+ it "should allow to load sounds from IO objects" do
41
+ lambda {
42
+ open(path_of("pop.wav")) do |io|
43
+ Ray::Sound.new(io)
44
+ end
45
+ }.should_not raise_exception
46
+ end
47
+
48
+ it "should allow to change the volume" do
49
+ sound = Ray::Sound.new(path_of("pop.wav"))
50
+ sound.volume = 50
51
+ sound.volume.should be_close(50, 0.1)
52
+ end
53
+
54
+ it "should make Ray play" do
55
+ sound = Ray::Sound.new(path_of("pop.wav"))
56
+
57
+ lambda { sound.play(1) }.should change {
58
+ Ray::Audio.playing?(1) && !Ray::Audio.paused?(1)
59
+ }.from(false).to(true)
60
+
61
+ Ray::Audio.stop(1)
62
+ end
63
+
64
+ it "can be paused" do
65
+ sound = Ray::Sound.new(path_of("pop.wav"))
66
+ sound.play(1)
67
+
68
+ lambda { Ray::Audio.pause(1) }.should change {
69
+ Ray::Audio.playing?(1) && !Ray::Audio.paused?(1)
70
+ }.from(true).to(false)
71
+ end
72
+
73
+ it "can be resumed" do
74
+ sound = Ray::Sound.new(path_of("pop.wav"))
75
+ sound.play(1)
76
+ Ray::Audio.pause(1)
77
+
78
+ lambda { Ray::Audio.resume(1) }.should change {
79
+ Ray::Audio.playing?(1) && !Ray::Audio.paused?(1)
80
+ }.from(false).to(true)
81
+
82
+ Ray::Audio.stop(1)
83
+ end
84
+
85
+ after :all do
86
+ Ray.stop
87
+ end
88
+ end
89
+
90
+ describe Ray::Music do
91
+ before :all do
92
+ Ray.init
93
+ end
94
+
95
+ it "should be able to create object from valid files" do
96
+ lambda {
97
+ Ray::Music.new(path_of("pop.wav"))
98
+ }.should_not raise_exception
99
+ end
100
+
101
+ it "should be able to create object from IO objects" do
102
+ lambda {
103
+ open(path_of("pop.wav")) { |io| Ray::Music.new(io) }
104
+ }.should_not raise_exception
105
+ end
106
+
107
+ it "should make Ray play" do
108
+ music = Ray::Music.new(path_of("pop.wav"))
109
+ music.play
110
+
111
+ Ray::Audio.should be_playing
112
+ Ray::Audio.stop
113
+ end
114
+
115
+ it "can be paused" do
116
+ music = Ray::Music.new(path_of("pop.wav"))
117
+ music.play
118
+ Ray::Audio.pause
119
+
120
+ Ray::Audio.should be_paused
121
+ end
122
+
123
+ it "can be resumed" do
124
+ music = Ray::Music.new(path_of("pop.wav"))
125
+ music.play
126
+
127
+ Ray::Audio.pause
128
+ Ray::Audio.resume
129
+
130
+ Ray::Audio.should_not be_paused
131
+ Ray::Audio.stop
132
+ end
133
+
134
+ it "can be stopped" do
135
+ music = Ray::Music.new(path_of("pop.wav"))
136
+ music.play
137
+
138
+ Ray::Audio.stop
139
+ Ray::Audio.should_not be_playing
140
+ end
141
+
142
+ after :all do
143
+ Ray.stop
144
+ end
145
+ end
146
+ end
@@ -1,3 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
1
3
  describe Ray::Color do
2
4
  describe "#initialize" do
3
5
  it "should accept 3 integers" do
@@ -41,4 +43,15 @@ describe Ray::Color do
41
43
  end
42
44
  end
43
45
  end
46
+
47
+ describe "#==" do
48
+ it "should return true if both colors are identical" do
49
+ Ray::Color.new(10, 15, 20, 30).should == Ray::Color.new(10, 15, 20, 30)
50
+ Ray::Color.new(10, 15, 20, 30).should_not == Ray::Color.new(1, 15, 2, 3)
51
+ end
52
+
53
+ it "should not raise an exception if the argument isn't a color" do
54
+ Ray::Color.new(1, 1, 1, 1).should_not == 1
55
+ end
56
+ end
44
57
  end
@@ -1,16 +1,11 @@
1
- describe "the event DSL" do
2
- context "when someone listens to an event" do
3
- before :all do
4
- Ray.describe_matcher(:more_than, :integer) do |x|
5
- lambda { |i| i > x }
6
- end
7
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
8
2
 
9
- before :each do
3
+ describe Ray::DSL do
4
+ before :each do
10
5
  @runner = Ray::DSL::EventRunner.new
11
6
 
12
7
  @obj = Object.new
13
- @obj.extend Ray::DSL::Listener
8
+ @obj.extend Ray::DSL::EventListener
14
9
  @obj.extend Ray::DSL::EventRaiser
15
10
  @obj.extend Ray::Matchers
16
11
 
@@ -18,174 +13,68 @@ describe "the event DSL" do
18
13
  @obj.raiser_runner = @runner
19
14
  end
20
15
 
21
- context "without any arguments" do
22
- it "should always send it" do
23
- var = 0
24
- @obj.on :foo do
25
- var += 1
26
- end
16
+ it "should send events with the same arguments and name as in #on" do
17
+ count = 0
18
+ @obj.on :right_event, "danger", "bar" do |*args|
19
+ args.should == ["danger", "bar"]
20
+ count += 1
21
+ end
22
+
23
+ [:right_event, :wrong_event].each do |name|
24
+ @obj.raise_event(name)
25
+ @obj.raise_event(name, "bar")
26
+ @obj.raise_event(name, "danger")
27
+ @obj.raise_event(name, "danger", "bar")
28
+ end
29
+
30
+ @runner.run
31
+ count.should == 1
32
+ end
33
+
34
+ it "should use === to see if an event can be raised" do
35
+ true_matcher = mock('true_matcher')
36
+ true_matcher.should_receive(:===).and_return(true)
27
37
 
28
- @obj.raise_event(:foo, "blabla")
29
- @obj.raise_event(:foo)
30
- @obj.raise_event(:foo, :error, 3, "read")
38
+ false_matcher = mock('false_matcher')
39
+ false_matcher.should_receive(:===).and_return(false)
31
40
 
32
- @runner.run
33
- var.should == 3
34
- end
41
+ worked = nil
42
+
43
+ @obj.on :event, true_matcher do
44
+ worked.should_not == false
45
+ worked = true
35
46
  end
36
47
 
37
- context "with some arguments" do
38
- it "should send the ones with the same arguments" do
39
- var = 0
40
- @obj.on :foo, "danger", "bar" do
41
- var += 1
42
- end
43
-
44
- @obj.raise_event(:foo)
45
- @obj.raise_event(:foo, "bar")
46
- @obj.raise_event(:foo, "danger")
47
- @obj.raise_event(:foo, "danger", "bar")
48
- @obj.raise_event(:foo, "danger", "bar", "test")
49
-
50
- @runner.run
51
- var.should == 1
52
- end
53
-
54
- context "if a matcher is one of them" do
55
- it "should send the events if it matches the argument" do
56
- count = 0
57
-
58
- @obj.instance_eval do
59
- on :foo, more_than(10) do |x|
60
- x.should > 10
61
- count += 1
62
- end
63
-
64
- raise_event(:foo, 5)
65
- raise_event(:foo, "a")
66
- raise_event(:foo, 15)
67
- end
68
-
69
- @runner.run
70
- count.should == 1
71
- end
72
- end
73
-
74
- context "if a regex is one of them" do
75
- it "should send the event if a string match it" do
76
- count = 0
77
-
78
- @obj.instance_eval do
79
- on :foo, /hello/ do |str|
80
- str.should =~ /hello/
81
- count += 1
82
- end
83
-
84
- raise_event(:foo, 0)
85
- raise_event(:foo, "wat?")
86
- raise_event(:foo, "Hey, hello you!")
87
- raise_event(:foo, /hey hello you/)
88
- end
89
-
90
- @runner.run
91
- count.should == 1
92
- end
93
-
94
- it "should send then event if the argument is the same regex" do
95
- count = 0
96
-
97
- @obj.instance_eval do
98
- on :foo, /hello/ do |reg|
99
- reg.should == /hello/
100
- count += 1
101
- end
102
-
103
- raise_event(:foo, 0)
104
- raise_event(:foo, 5.5)
105
- raise_event(:foo, "Goodbye!")
106
- raise_event(:foo, /hello/)
107
- end
108
-
109
- @runner.run
110
- count.should == 1
111
- end
112
- end
48
+ @obj.on :event, false_matcher do
49
+ worked = false
113
50
  end
114
51
 
115
- context "if the event was described" do
116
- before :all do
117
- Ray.describe_event(:weird_thing, :string, :integer)
118
- end
119
-
120
- it "should convert arguments at creation" do
121
- ev = Ray::DSL::Event.new(:weird_thing, [3, "3"])
122
- ev.args.should == ["3", 3]
123
- end
124
-
125
- it "should not raise an error if it can't convert objects" do
126
- ev = Ray::DSL::Event.new(:weird_thing, ["str", String])
127
- ev.args.should == ["str", String]
128
- end
129
-
130
- it "should always convert if a method like #to_i is available" do
131
- obj = Object.new
132
- class << obj; def to_i; 3; end; end
133
-
134
- ev = Ray::DSL::Event.new(:weird_thing, [String, obj])
135
- ev.args.should == ["String", 3]
136
- end
137
-
138
- it "should try to convert arguments for handlers" do
139
- count = 0
140
-
141
- @obj.instance_eval do
142
- on :weird_thing, 3 do |x|
143
- x.should == "3"
144
- count += 1
145
- end
146
-
147
- raise_event(:weird_thing, 0)
148
- raise_event(:weird_thing, 3)
149
- raise_event(:weird_thing, "3")
150
- raise_event(:weird_thing, String)
151
- end
152
-
153
- @runner.run
154
- count.should == 2
155
- end
156
-
157
- it "should not try to convert matchers and regexps in handlers" do
158
- count = 0
159
-
160
- Ray.describe_conversion(Ray::DSL::Matcher => :integer,
161
- Regexp => :string) {}
162
-
163
- Ray.describe_matcher(:more_than, :integer) do |x|
164
- lambda { |val| val > x }
165
- end
166
-
167
- @obj.instance_eval do
168
- on :weird_thing, /\d/, more_than(10) do |x, y|
169
- count += 1
170
- end
171
-
172
- raise_event(:weird_thing, "1", 15)
173
- end
174
-
175
- @runner.run
176
- count.should == 1
177
- end
52
+ @obj.raise_event(:event, :argument)
53
+ @runner.run
54
+
55
+ worked.should be_true
56
+ end
57
+
58
+ it "should pass the arguments of the event to the block" do
59
+ @obj.on :foo do |*args|
60
+ args.should == ["a", "b", "c"]
178
61
  end
179
62
 
180
- context "when the proc takes arguments" do
181
- it "should pass the arguments given to the event" do
182
- @obj.on :foo do |*args|
183
- args.should == ["a", "b", "c"]
184
- end
63
+ @obj.raise_event(:foo, "a", "b", "c")
64
+ @runner.run
65
+ end
185
66
 
186
- @obj.raise_event(:foo, "a", "b", "c")
187
- @runner.run
188
- end
67
+ it "should send events with more arguments than #on if they match" do
68
+ count = 0
69
+ @obj.on :foo do
70
+ count += 1
189
71
  end
72
+
73
+ @obj.raise_event(:foo, "blabla")
74
+ @obj.raise_event(:foo)
75
+ @obj.raise_event(:foo, :error, 3, "read")
76
+
77
+ @runner.run
78
+ count.should == 3
190
79
  end
191
80
  end
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ if Ray.has_font_support?
4
+ describe Ray::Font do
5
+ before :all do
6
+ Ray.init
7
+ end
8
+
9
+ it "should be able to load fonts from a file" do
10
+ lambda {
11
+ Ray::Font.new(path_of("VeraMono.ttf"), 12)
12
+ }.should_not raise_exception
13
+ end
14
+
15
+ it "should be able to load fonts from IO objects" do
16
+ lambda {
17
+ open(path_of("VeraMono.ttf")) { |io| Ray::Font.new(io, 12) }
18
+ }.should_not raise_exception
19
+ end
20
+
21
+ it "should create normal font" do
22
+ Ray::Font.new(path_of("VeraMono.ttf"), 12).should be_normal
23
+ end
24
+
25
+ it "should allow to change its style" do
26
+ font = Ray::Font.new(path_of("VeraMono.ttf"), 12)
27
+ font.style = Ray::Font::STYLE_BOLD | Ray::Font::STYLE_ITALIC
28
+
29
+ font.should be_italic
30
+ font.should be_bold
31
+ end
32
+
33
+ describe "#draw" do
34
+ before :all do
35
+ @win = Ray.create_window(:w => 100, :h => 100)
36
+ @font = Ray::Font.new(path_of("VeraMono.ttf"), 12)
37
+ end
38
+
39
+ it "should return an image when we don't say where to draw" do
40
+ @font.draw("Something").should be_a(Ray::Image)
41
+ end
42
+
43
+ it "should return the surface it drew on if it did" do
44
+ @font.draw("Something", :on => @win, :at => [0, 0]).should == @win
45
+ end
46
+ end
47
+
48
+ after :all do
49
+ Ray.stop
50
+ end
51
+ end
52
+
53
+ describe "String#draw" do
54
+ before :all do
55
+ Ray.init
56
+
57
+ @win = Ray.create_window(:w => 100, :h => 100)
58
+ @font = Ray::Font.new(path_of("VeraMono.ttf"), 12)
59
+ end
60
+
61
+ it "should be able to guess the size" do
62
+ lambda {
63
+ "Hello world!".draw(:font => @font)
64
+ }.should_not raise_exception
65
+ end
66
+
67
+ it "should use the specified width unless :on is specified" do
68
+ img = "Hello world!".draw(:font => @font, :w => 40)
69
+ img.w.should == 40
70
+ end
71
+
72
+ it "should require the font to be specified" do
73
+ lambda {
74
+ "Hello world".draw(:on => @win)
75
+ }.should raise_exception
76
+ end
77
+
78
+ it "should draw on multiple lines" do
79
+ img = "Hello\nworld".draw(:font => @font, :w => 100)
80
+ img.height.should == @font.line_skip * 2
81
+ end
82
+
83
+ it "should allow to specify an explicit size" do
84
+ img = "Hello\nworld".draw(:font => @font, :h => 100, :w => 50)
85
+ img.width.should == 50
86
+ img.height.should == 100
87
+ end
88
+
89
+ after :all do
90
+ Ray.stop
91
+ end
92
+ end
93
+ end