rubysketch 0.5.3 → 0.5.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2aae68b50056538ec9f1de57091af05176af8b629331d40e16b640de83d4a610
4
- data.tar.gz: 8929fd46a62eeb5457f386a72b255d3a6267fc1380bb29aabe9b093a722ecb34
3
+ metadata.gz: 82a93ef9dac4ae855bfa85f9a076ed05c807875db70be9c5e72419137499434e
4
+ data.tar.gz: 2f432e94c80ad231f50ca11df96ecd6a13c389551f75c426e161701e25d85a23
5
5
  SHA512:
6
- metadata.gz: fe6b88ffc3d9ee14f6b9206df4b554d498cd6a4b5b13a21baf8a6b0cfcebec4888322d12f6cee09829cc7a1038ad9ad2854945d5bb4e8706337bbfa310c113ab
7
- data.tar.gz: 56dac7438fb09ed3d8164e390e44dc785be289e6c4a4e5c3b9550fd5363c87f0a5a05f94806b6f68e691019e9297e2be6710435c5b0cafa35b2527ca1d7d1124
6
+ metadata.gz: cdf7238a4d07fe88b5d1fe3d68ea6f62d9536b142afda5dad1f4c15538bae2047d4e188bbc88e0777d641650ad9c5f5864720345ad5ec950e2ff18e83f552db9
7
+ data.tar.gz: 310a71a0b3388876bd0c0910a09bb9aa12e5686e5885ec8e4b2a32cb4af629ed18a010731a77b4a8ea1a9a4be41de504098767d0d133e3344554d5078508ad29
@@ -20,8 +20,9 @@ def setup_dependencies(build: true, only: nil)
20
20
 
21
21
  exts.each do |ext|
22
22
  gem = RENAMES[ext.to_sym].then {|s| s || ext}
23
- clone = "git clone --depth 1 https://github.com/xord/#{ext}.git ../#{ext}"
24
23
  ver = gemspec[/add_runtime_dependency.*['"]#{gem}['"].*['"]\s*~>\s*([\d\.]+)\s*['"]/, 1]
24
+ opts = '-c advice.detachedHead=false --depth 1'
25
+ clone = "git clone #{opts} https://github.com/xord/#{ext}.git ../#{ext}"
25
26
 
26
27
  # 'rake subtree:push' pushes all subrepos, so cloning by new tag
27
28
  # often fails before tagging each new tag
data/ChangeLog.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # rubysketch ChangeLog
2
2
 
3
3
 
4
+ ## [v0.5.4] - 2023-04-30
5
+
6
+ - Add Sprite#image=() and Sprite#offset=()
7
+ - gravity() takes vector by pixel
8
+ - Add documents for Sprite class and test it
9
+
10
+
4
11
  ## [v0.5.3] - 2023-04-22
5
12
 
6
13
  - Depends on Beeps
data/RubySketch.podspec CHANGED
@@ -23,11 +23,15 @@ Pod::Spec.new do |s|
23
23
  incdirs = exts.map {|x| "#{root}/#{x}/include"}.concat %W[
24
24
  #{root}/src
25
25
  #{root}/beeps/vendor/stk/include
26
+ #{root}/beeps/vendor/AudioFile
27
+ #{root}/beeps/vendor/r8brain-free-src
28
+ #{root}/beeps/vendor/signalsmith-stretch
26
29
  #{root}/rays/vendor/glm
27
30
  #{root}/rays/vendor/clipper/cpp
28
31
  #{root}/rays/vendor/poly2tri/poly2tri
29
32
  #{root}/rays/vendor/splines-lib
30
- #{root}/reflex/vendor/Box2D/Box2D
33
+ #{root}/reflex/vendor/box2d/include
34
+ #{root}/reflex/vendor/box2d/src
31
35
  ${PODS_ROOT}/CRuby/CRuby/include
32
36
  ]
33
37
 
@@ -63,16 +67,25 @@ Pod::Spec.new do |s|
63
67
  end
64
68
 
65
69
  s.subspec "Beeps" do |spec|
66
- spec.source_files = "beeps/src/*.cpp"
67
- spec.frameworks = %w[OpenAL]
70
+ spec .source_files = "beeps/src/*.cpp"
71
+ spec.osx.source_files = "beeps/src/osx/*.{cpp,mm}"
72
+ spec.ios.source_files = "beeps/src/osx/*.{cpp,mm}"
73
+ spec.frameworks = %w[OpenAL AVFoundation]
68
74
 
69
75
  spec.subspec "STK" do |sub|
70
76
  sub.source_files = "beeps/vendor/stk/src/*.cpp"
71
- sub.exclude_files = %W[Tcp Udp Socket Thread Mutex InetWv Rt].map {|s|
77
+ sub.exclude_files = %w[Tcp Udp Socket Thread Mutex InetWv Rt].map {|s|
72
78
  "beeps/vendor/stk/src/#{s}*.cpp"
73
79
  }
74
80
  end
75
81
 
82
+ spec.subspec "R8BrainFreeSrc" do |sub|
83
+ sub.source_files = "beeps/vendor/r8brain-free-src/*.cpp"
84
+ sub.exclude_files = %w[example pffft_double/].map {|s|
85
+ "beeps/vendor/r8brain-free-src/#{s}*.cpp"
86
+ }
87
+ end
88
+
76
89
  spec.subspec "Ext" do |ext|
77
90
  ext.source_files = "beeps/ext/beeps/*.cpp"
78
91
  end
@@ -108,7 +121,7 @@ Pod::Spec.new do |s|
108
121
  spec.ios.frameworks = %w[CoreMotion]
109
122
 
110
123
  spec.subspec "Box2D" do |sub|
111
- sub.source_files = "reflex/vendor/Box2D/Box2D/Box2D/**/*.cpp"
124
+ sub.source_files = "reflex/vendor/box2d/src/**/*.cpp"
112
125
  end
113
126
 
114
127
  spec.subspec "Ext" do |ext|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.3
1
+ 0.5.4
@@ -1,4 +1,3 @@
1
- require 'forwardable'
2
1
  require 'beeps'
3
2
  require 'processing/all'
4
3
 
@@ -10,3 +9,11 @@ require 'rubysketch/sprite'
10
9
  require 'rubysketch/sound'
11
10
  require 'rubysketch/graphics_context'
12
11
  require 'rubysketch/context'
12
+
13
+
14
+ module RubySketch
15
+
16
+ Vector = Processing::Vector
17
+ Image = Processing::Image
18
+
19
+ end# RubySketch
@@ -5,47 +5,103 @@ module RubySketch
5
5
 
6
6
  include GraphicsContext
7
7
 
8
+ Sound = RubySketch::Sound
9
+ Sprite = RubySketch::Sprite
10
+
11
+ # @private
8
12
  def initialize(window)
9
13
  super
10
- @sprites__ = window.add SpritesView.new
14
+ @layer__ = window.add_overlay SpriteLayer.new
11
15
  end
12
16
 
17
+ # Creates a new sprite and add it to physics engine.
18
+ #
19
+ # @overload createSprite(image: img)
20
+ # pos: [0, 0], size: [image.width, image.height]
21
+ # @param [Image] img sprite image
22
+ #
23
+ # @overload createSprite(x, y, image: img)
24
+ # pos: [x, y], size: [image.width, image.height]
25
+ # @param [Numeric] x x of sprite position
26
+ # @param [Numeric] y y of sprite position
27
+ # @param [Image] img sprite image
28
+ #
29
+ # @overload createSprite(x, y, w, h)
30
+ # pos(x, y), size: [w, h]
31
+ # @param [Numeric] x x of sprite position
32
+ # @param [Numeric] y y of sprite position
33
+ # @param [Numeric] w width of sprite
34
+ # @param [Numeric] h height of sprite
35
+ #
36
+ # @overload createSprite(x, y, w, h, image: img, offset: off)
37
+ # pos: [x, y], size: [w, h], offset: [offset.x, offset.x]
38
+ # @param [Numeric] x x of sprite position
39
+ # @param [Numeric] y y of sprite position
40
+ # @param [Numeric] w width of sprite
41
+ # @param [Numeric] h height of sprite
42
+ # @param [Image] img sprite image
43
+ # @param [Vector] off offset of sprite image
44
+ #
13
45
  def createSprite(*args, **kwargs)
14
46
  addSprite Sprite.new(*args, **kwargs)
15
47
  end
16
48
 
49
+ # Adds the sprite to the physics engine.
50
+ #
51
+ # @param [Sprite] sprite sprite object
52
+ #
17
53
  def addSprite(sprite)
18
- @sprites__.add sprite.getInternal__ if sprite
54
+ @layer__.add sprite.getInternal__ if sprite
19
55
  sprite
20
56
  end
21
57
 
58
+ # Removes the sprite from the physics engine.
59
+ #
60
+ # @param [Sprite] sprite sprite object
61
+ #
22
62
  def removeSprite(sprite)
23
- @sprites__.remove sprite.getInternal__ if sprite
63
+ @layer__.remove sprite.getInternal__ if sprite
24
64
  sprite
25
65
  end
26
66
 
67
+ # @private
27
68
  def loadSound(path)
28
69
  Sound.load path
29
70
  end
30
71
 
72
+ # Sets gravity for the physics engine.
73
+ #
74
+ # @overload gravity(vec)
75
+ # @param [Vector] vec gracity vector
76
+ #
77
+ # @overload gravity(ary)
78
+ # @param [Array<Numeric>] ary gravityX, gravityY
79
+ #
80
+ # @overload gravity(x, y)
81
+ # @param [Numeric] x x of gravity vector
82
+ # @param [Numeric] y y of gracity vector
83
+ #
31
84
  def gravity(*args)
32
85
  x, y =
33
- case args
34
- when Processing::Vector then args.array
86
+ case arg = args.first
87
+ when Vector then arg.array
88
+ when Array then arg
35
89
  else args
36
90
  end
37
- @sprites__.then do |v|
38
- v.gravity x * v.meter, y * v.meter
39
- end
91
+ @layer__.gravity x, y
40
92
  end
41
93
 
42
- class SpritesView < Reflex::View
43
- def on_draw(e)
44
- e.block
45
- end
94
+ end# Context
95
+
96
+
97
+ # @private
98
+ class SpriteLayer < Reflex::View
99
+
100
+ def on_draw(e)
101
+ e.block
46
102
  end
47
103
 
48
- end# Context
104
+ end# SpriteLayer
49
105
 
50
106
 
51
107
  end# RubySketch
@@ -1,6 +1,7 @@
1
1
  module RubySketch
2
2
 
3
3
 
4
+ # @private
4
5
  module Extension
5
6
 
6
7
  module_function
@@ -3,34 +3,27 @@ module RubySketch
3
3
 
4
4
  module GraphicsContext
5
5
 
6
+ # Draws one or more sprites.
7
+ #
8
+ # @param [Array<Sprite>] sprites
9
+ #
6
10
  def sprite(*sprites)
7
11
  sprites.flatten! if sprites.first&.is_a? Array
8
12
  sprites.each do |sp|
9
13
  v = sp.getInternal__
10
- f, angle, img, offset = v.frame, v.angle, sp.image, sp.offset
14
+ f, angle = v.frame, v.angle
11
15
  if angle == 0
12
- drawSprite__ f.x, f.y, f.w, f.h, img, offset
16
+ sp.on_draw__ f.x, f.y, f.w, f.h
13
17
  else
14
18
  pushMatrix do
15
19
  translate f.x, f.y
16
20
  rotate radians(angle)
17
- drawSprite__ 0, 0, f.w, f.h, img, offset
21
+ sp.on_draw__ 0, 0, f.w, f.h
18
22
  end
19
23
  end
20
24
  end
21
25
  end
22
26
 
23
- def drawSprite__(x, y, w, h, img, offset)
24
- if img && offset
25
- ox, oy = offset
26
- copy img, ox, oy, w, h, x, y, w, h
27
- elsif img
28
- image img, x, y
29
- else
30
- rect x, y, w, h
31
- end
32
- end
33
-
34
27
  end# GraphicsContext
35
28
 
36
29
 
@@ -1,3 +1,4 @@
1
+ # @private
1
2
  class Rays::Point
2
3
  def toVector()
3
4
  Processing::Vector.new x, y, z
@@ -1,6 +1,7 @@
1
1
  module RubySketch
2
2
 
3
3
 
4
+ # @private
4
5
  class Sound
5
6
 
6
7
  # @private
@@ -8,6 +9,8 @@ module RubySketch
8
9
  @sound = sound
9
10
  end
10
11
 
12
+ # Play sound.
13
+ #
11
14
  def play()
12
15
  old = @player
13
16
  @player = @sound.play
@@ -15,12 +18,16 @@ module RubySketch
15
18
  true
16
19
  end
17
20
 
21
+ # Pause sound.
22
+ #
18
23
  def pause()
19
24
  return false unless @player
20
25
  @player.pause
21
26
  true
22
27
  end
23
28
 
29
+ # Stop sound.
30
+ #
24
31
  def stop()
25
32
  return false unless @player
26
33
  @player.stop
@@ -28,22 +35,46 @@ module RubySketch
28
35
  true
29
36
  end
30
37
 
38
+ # Returns whether the sound is playing or not.
39
+ #
40
+ # @return [Boolean] playing or not
41
+ #
31
42
  def playing?()
32
43
  @player ? @player.playing? : false
33
44
  end
34
45
 
46
+ # Returns whether the sound is paused or not.
47
+ #
48
+ # @return [Boolean] paused or not
49
+ #
35
50
  def paused?()
36
- !playing? && !stopped?
51
+ @player ? @player.paused? : false
37
52
  end
38
53
 
54
+ # Returns whether the sound is stopped or not.
55
+ #
56
+ # @return [Boolean] stopped or not
57
+ #
39
58
  def stopped?()
40
59
  @player ? @player.stopped? : true
41
60
  end
42
61
 
62
+ # Save the sound data to a file.
63
+ #
64
+ # @param [String] path file path
65
+ #
66
+ # @return [Sound] self
67
+ #
43
68
  def save(path)
44
69
  @sound.save path
45
70
  end
46
71
 
72
+ # Load a sound file.
73
+ #
74
+ # @param [String] path file path
75
+ #
76
+ # @return [Sound] sound object
77
+ #
47
78
  def self.load(path)
48
79
  f = Beeps::FileIn.new path
49
80
  self.new Beeps::Sound.new(f, f.seconds, nchannels: f.nchannels)
@@ -1,128 +1,409 @@
1
1
  module RubySketch
2
2
 
3
3
 
4
+ # Sprite object.
5
+ #
4
6
  class Sprite
5
7
 
6
- extend Forwardable
8
+ # Initialize sprite object.
9
+ #
10
+ # @overload new(image: img)
11
+ # pos: [0, 0], size: [image.width, image.height]
12
+ # @param [Image] img sprite image
13
+ #
14
+ # @overload new(x, y, image: img)
15
+ # pos: [x, y], size: [image.width, image.height]
16
+ # @param [Numeric] x x of sprite position
17
+ # @param [Numeric] y y of sprite position
18
+ # @param [Image] img sprite image
19
+ #
20
+ # @overload new(x, y, w, h)
21
+ # pos(x, y), size: [w, h]
22
+ # @param [Numeric] x x of sprite position
23
+ # @param [Numeric] y y of sprite position
24
+ # @param [Numeric] w width of sprite
25
+ # @param [Numeric] h height of sprite
26
+ #
27
+ # @overload new(x, y, w, h, image: img, offset: off)
28
+ # pos: [x, y], size: [w, h], offset: [offset.x, offset.x]
29
+ # @param [Numeric] x x of sprite position
30
+ # @param [Numeric] y y of sprite position
31
+ # @param [Numeric] w width of sprite
32
+ # @param [Numeric] h height of sprite
33
+ # @param [Image] img sprite image
34
+ # @param [Vector] off offset of sprite image
35
+ #
36
+ def initialize(x = 0, y = 0, w = nil, h = nil, image: nil, offset: nil)
37
+ w ||= (image&.width || 0)
38
+ h ||= (image&.height || 0)
39
+ raise 'invalid size' unless w >= 0 && h >= 0
40
+ raise 'invalid image' if image && !image.getInternal__.is_a?(Rays::Image)
7
41
 
8
- def initialize(x = 0, y = 0, w = nil, h = nil, image: nil, offset: nil, dynamic: false)
9
- w ||= image&.width || 0
10
- h ||= image&.height || 0
11
- raise 'invalid size' unless w >= 0 && h >= 0
42
+ @view__ = SpriteView.new(self, x: x, y: y, w: w, h: h, back: :white)
12
43
 
13
- @image__, @offset__ = image, offset
14
- @view__ = View.new self, x: x, y: y, w: w, h: h, back: :white, dynamic: dynamic
44
+ self.image = image if image
45
+ self.offset = offset if offset
15
46
  end
16
47
 
17
- def_delegators :@view__,
18
- :x, :x=,
19
- :y, :y=,
20
- :w, :h,
21
- :width, :height,
22
- :dynamic?, :dynamic=,
23
- :density, :density=,
24
- :friction, :friction=,
25
- :restitution, :restitution=
48
+ # Returns the position of the sprite.
49
+ #
50
+ # @return [Vector] position
51
+ #
52
+ def position()
53
+ @view__.position.toVector
54
+ end
26
55
 
27
- def update(&block)
28
- @view__.on_update = block
56
+ # Sets the position of the sprite.
57
+ #
58
+ # @overload position=(vec)
59
+ # @param [Vector] vec position vector
60
+ #
61
+ # @overload position=(ary)
62
+ # @param [Array<Numeric>] ary positionX, positionY
63
+ #
64
+ # @return [Vector] position
65
+ #
66
+ def position=(arg)
67
+ @view__.position = arg.is_a?(Vector) ? arg.getInternal__ : arg
68
+ arg
29
69
  end
30
70
 
31
- def contact(&block)
32
- @view__.on_contact = block
71
+ # Returns the x-coordinate position of the sprite.
72
+ #
73
+ # @return [Numeric] sprite position x
74
+ #
75
+ def x()
76
+ @view__.x
33
77
  end
34
78
 
35
- def contact?(&block)
36
- @view__.will_contact = block
79
+ # Set the x-coordinate position of the sprite.
80
+ #
81
+ # @param [Numeric] n sprite position x
82
+ #
83
+ # @return [Numeric] sprite position x
84
+ #
85
+ def x=(n)
86
+ @view__.x = n
87
+ n
37
88
  end
38
89
 
39
- def position()
40
- @view__.position.toVector
90
+ # Returns the y-coordinate position of the sprite.
91
+ #
92
+ # @return [Numeric] sprite position y
93
+ #
94
+ def y()
95
+ @view__.y
41
96
  end
42
97
 
43
- def position=(vector)
44
- @view__.position = vector.getInternal__
98
+ # Set the y-coordinate position of the sprite.
99
+ #
100
+ # @param [Numeric] n sprite position y
101
+ #
102
+ # @return [Numeric] sprite position y
103
+ #
104
+ def y=(n)
105
+ @view__.y = n
106
+ n
45
107
  end
46
108
 
109
+ alias pos position
110
+ alias pos= position=
111
+
112
+ # Returns the size of the sprite.
113
+ #
114
+ # @return [Vector] size
115
+ #
47
116
  def size()
48
117
  @view__.size.toVector
49
118
  end
50
119
 
51
- def image()
52
- @image__
120
+ # Returns the width of the sprite.
121
+ #
122
+ # @return [Numeric] width
123
+ #
124
+ def width()
125
+ @view__.width
53
126
  end
54
127
 
55
- def offset()
56
- @offset__
128
+ # Returns the height of the sprite.
129
+ #
130
+ # @return [Numeric] height
131
+ #
132
+ def height()
133
+ @view__.height
57
134
  end
58
135
 
136
+ alias w width
137
+ alias h height
138
+
139
+ # Returns the velocity of the sprite.
140
+ #
141
+ # @return [Vector] velocity
142
+ #
59
143
  def velocity()
60
144
  @view__.velocity.toVector
61
145
  end
62
146
 
63
- def velocity=(vector)
64
- @view__.velocity = vector.getInternal__
147
+ # Sets the velocity of the sprite.
148
+ #
149
+ # @overload velocity=(vec)
150
+ # @param [Vector] vec velocity vector
151
+ #
152
+ # @overload velocity=(ary)
153
+ # @param [Array<Numeric>] ary velocityX, velocityY
154
+ #
155
+ # @return [Vector] velocity
156
+ #
157
+ def velocity=(arg)
158
+ @view__.velocity = arg.is_a?(Vector) ? arg.getInternal__ : arg
159
+ arg
65
160
  end
66
161
 
162
+ # Returns the x-axis velocity of the sprite.
163
+ #
164
+ # @return [Numeric] velocity.x
165
+ #
67
166
  def vx()
68
167
  @view__.velocity.x
69
168
  end
70
169
 
71
- def vx=(value)
72
- @view__.velocity = @view__.velocity.tap {|v| v.x = value}
73
- value
170
+ # Sets the x-axis velocity of the sprite.
171
+ #
172
+ # @param [Numeric] n x-axis velocity
173
+ #
174
+ # @return [Numeric] velocity.x
175
+ #
176
+ def vx=(n)
177
+ @view__.velocity = @view__.velocity.tap {|v| v.x = n}
178
+ n
74
179
  end
75
180
 
181
+ # Returns the y-axis velocity of the sprite.
182
+ #
183
+ # @return [Numeric] velocity.y
184
+ #
76
185
  def vy()
77
186
  @view__.velocity.y
78
187
  end
79
188
 
80
- def vy=(value)
81
- @view__.velocity = @view__.velocity.tap {|v| v.y = value}
82
- value
189
+ # Sets the y-axis velocity of the sprite.
190
+ #
191
+ # @param [Numeric] n y-axis velocity
192
+ #
193
+ # @return [Numeric] velocity.y
194
+ #
195
+ def vy=(n)
196
+ @view__.velocity = @view__.velocity.tap {|v| v.y = n}
197
+ n
198
+ end
199
+
200
+ alias vel velocity
201
+ alias vel= velocity=
202
+
203
+ # Returns the image of the sprite.
204
+ #
205
+ # @return [Image] sprite image
206
+ #
207
+ def image()
208
+ @image__
209
+ end
210
+
211
+ # Sets the sprite image.
212
+ #
213
+ # @param [Image] img sprite image
214
+ #
215
+ # @return [Image] sprite image
216
+ #
217
+ def image=(img)
218
+ @image__ = img
219
+ end
220
+
221
+ # Returns the offset of the sprite image.
222
+ #
223
+ # @return [Vector] offset of the sprite image
224
+ #
225
+ def offset()
226
+ @offset__
227
+ end
228
+
229
+ def offset=(arg)
230
+ @offset__ =
231
+ case arg
232
+ when Vector then arg
233
+ when Array then Vector.new(*arg[0, 2])
234
+ when nil then nil
235
+ else raise ArgumentError
236
+ end
237
+ end
238
+
239
+ # Returns whether the sprite is movable by the physics engine.
240
+ #
241
+ # @return [Boolean] true if dynamic
242
+ #
243
+ def dynamic?()
244
+ @view__.dynamic?
245
+ end
246
+
247
+ # Sets whether the sprite is movable by the physics engine.
248
+ #
249
+ # @param [Boolean] bool movable or not
250
+ #
251
+ # @return [Boolean] true if dynamic
252
+ #
253
+ def dynamic=(bool)
254
+ @view__.dynamic = bool
255
+ bool
256
+ end
257
+
258
+ # Returns the density of the sprite.
259
+ #
260
+ # @return [Numeric] density
261
+ #
262
+ def density()
263
+ @view__.density
264
+ end
265
+
266
+ # Sets the density of the sprite.
267
+ #
268
+ # @param [Numeric] n density
269
+ #
270
+ # @return [Numeric] density
271
+ #
272
+ def density=(n)
273
+ @view__.density = n
274
+ n
275
+ end
276
+
277
+ # Returns the friction of the sprite.
278
+ #
279
+ # @return [Numeric] friction
280
+ #
281
+ def friction()
282
+ @view__.friction
283
+ end
284
+
285
+ # Sets the friction of the sprite.
286
+ #
287
+ # @param [Numeric] n friction
288
+ #
289
+ # @return [Numeric] friction
290
+ #
291
+ def friction=(n)
292
+ @view__.friction = n
293
+ n
294
+ end
295
+
296
+ # Returns the restitution of the sprite.
297
+ #
298
+ # @return [Numeric] restitution
299
+ #
300
+ def restitution()
301
+ @view__.restitution
302
+ end
303
+
304
+ # Sets the restitution of the sprite.
305
+ #
306
+ # @param [Numeric] n restitution
307
+ #
308
+ # @return [Numeric] restitution
309
+ #
310
+ def restitution=(n)
311
+ @view__.restitution = n
312
+ n
83
313
  end
84
314
 
85
- alias pos position
86
- alias pos= position=
87
- alias vel velocity
88
- alias vel= velocity=
89
315
  alias dens density
90
316
  alias dens= density=
91
317
  alias fric friction
92
- alias fric= friction
318
+ alias fric= friction=
93
319
  alias rest restitution
94
320
  alias rest= restitution=
95
321
 
322
+ # Defines update block.
323
+ #
324
+ # @example vx is updated every frame
325
+ # sprite.update do
326
+ # self.vx *= 0.9
327
+ # end
328
+ #
329
+ # @return [nil] nil
330
+ #
331
+ def update(&block)
332
+ @view__.update = block
333
+ end
334
+
335
+ # Defines contact block.
336
+ #
337
+ # @example Score increases when the player sprite touches a coin
338
+ # playerSprite.contact do |o|
339
+ # score += 1 if o.coin?
340
+ # end
341
+ #
342
+ # @return [nil] nil
343
+ #
344
+ def contact(&block)
345
+ @view__.contact = block
346
+ end
347
+
348
+ # Defines contact? block.
349
+ #
350
+ # @example only collide with an enemy
351
+ # playerSprite.contact? do |o|
352
+ # o.enemy?
353
+ # end
354
+ #
355
+ # @return [nil] nil
356
+ #
357
+ def contact?(&block)
358
+ @view__.will_contact = block
359
+ end
360
+
361
+ # @private
362
+ def on_draw__(x, y, w, h)
363
+ img, off = frame, @image__, @offset__
364
+ if img && off
365
+ copy img, off.x, off.y, f.w, h, x, y, w, h
366
+ elsif img
367
+ image img, x, y
368
+ else
369
+ rect x, y, w, h
370
+ end
371
+ end
372
+
96
373
  # @private
97
374
  def getInternal__()
98
375
  @view__
99
376
  end
100
377
 
101
- class View < Reflex::View
102
- attr_accessor :update, :contact, :will_contact
103
- attr_reader :sprite
378
+ end# Sprite
104
379
 
105
- def initialize(sprite, *a, **k, &b)
106
- @sprite = sprite
107
- super(*a, **k, &b)
108
- end
109
380
 
110
- def on_update(e)
111
- @update.call if @update
112
- end
381
+ # @private
382
+ class SpriteView < Reflex::View
113
383
 
114
- def on_contact(e)
115
- v = e.view
116
- @contact.call v.sprite, e.action if @contact && v.is_a?(View)
117
- end
384
+ attr_accessor :update, :contact, :will_contact
385
+ attr_reader :sprite
118
386
 
119
- def will_contact?(v)
120
- return true if !@will_contact || !v.is_a?(View)
121
- @will_contact.call v.sprite
122
- end
387
+ def initialize(sprite, *a, **k, &b)
388
+ @sprite = sprite
389
+ super(*a, **k, &b)
123
390
  end
124
391
 
125
- end# Sprite
392
+ def on_update(e)
393
+ @update.call if @update
394
+ end
395
+
396
+ def on_contact(e)
397
+ v = e.view
398
+ @contact.call v.sprite, e.action if @contact && v.is_a?(SpriteView)
399
+ end
400
+
401
+ def will_contact?(v)
402
+ return true if !@will_contact || !v.is_a?(SpriteView)
403
+ @will_contact.call v.sprite
404
+ end
405
+
406
+ end# SpriteView
126
407
 
127
408
 
128
409
  end# RubySketch
@@ -1,6 +1,7 @@
1
1
  module RubySketch
2
2
 
3
3
 
4
+ # @private
4
5
  class Window < Processing::Window
5
6
 
6
7
  def on_update(e)
data/pod.rake CHANGED
@@ -19,15 +19,17 @@ task :setup
19
19
 
20
20
  repos.each do |repo, ver|
21
21
  rakefile = "#{repo}/Rakefile"
22
- opts = {
23
- depth: 1,
24
- branch: (ENV['RUBYSKETCH_BRANCH'] || "v#{ver}")
25
- }.map {|k, v| "--#{k} #{v}"}.join ' '
22
+ opts = [
23
+ '-c advice.detachedHead=false',
24
+ '--no-single-branch',
25
+ '--depth 1',
26
+ "--branch #{ENV['RUBYSKETCH_BRANCH'] || ('v' + ver)}"
27
+ ]
26
28
 
27
29
  task :setup => rakefile
28
30
 
29
31
  file rakefile do
30
- sh %( git clone #{opts} #{github}/#{repo} )
32
+ sh %( git clone #{opts.join ' '} #{github}/#{repo} )
31
33
  sh %( cd #{repo} && VENDOR_NOCOMPILE=1 rake vendor erb )
32
34
  end
33
35
  end
data/rubysketch.gemspec CHANGED
@@ -28,12 +28,12 @@ Gem::Specification.new do |s|
28
28
  s.platform = Gem::Platform::RUBY
29
29
  s.required_ruby_version = '>= 2.7.0'
30
30
 
31
- s.add_runtime_dependency 'xot', '~> 0.1.33'
32
- s.add_runtime_dependency 'rucy', '~> 0.1.33'
33
- s.add_runtime_dependency 'beeps', '~> 0.1.33'
34
- s.add_runtime_dependency 'rays', '~> 0.1.33'
35
- s.add_runtime_dependency 'reflexion', '~> 0.1.33'
36
- s.add_runtime_dependency 'processing', '~> 0.5.3'
31
+ s.add_runtime_dependency 'xot', '~> 0.1.34'
32
+ s.add_runtime_dependency 'rucy', '~> 0.1.34'
33
+ s.add_runtime_dependency 'beeps', '~> 0.1.35'
34
+ s.add_runtime_dependency 'rays', '~> 0.1.34'
35
+ s.add_runtime_dependency 'reflexion', '~> 0.1.35'
36
+ s.add_runtime_dependency 'processing', '~> 0.5.5'
37
37
 
38
38
  s.add_development_dependency 'rake'
39
39
  s.add_development_dependency 'test-unit'
data/test/test_sound.rb CHANGED
@@ -73,7 +73,7 @@ class TestSound < Test::Unit::TestCase
73
73
  assert_equal [false, false, true], [s.playing?, s.paused?, s.stopped?]
74
74
  end
75
75
 
76
- def test_save()
76
+ def test_save_load()
77
77
  s = sound
78
78
 
79
79
  File.delete PATH
@@ -81,10 +81,8 @@ class TestSound < Test::Unit::TestCase
81
81
 
82
82
  s.save PATH
83
83
  assert_true File.exist? PATH
84
- end
85
84
 
86
- def test_load()
87
- assert_nothing_raised {sound.play}
85
+ assert_nothing_raised {RS::Sound.load(PATH).play}
88
86
  end
89
87
 
90
88
  end# TestSound
data/test/test_sprite.rb CHANGED
@@ -6,18 +6,190 @@ require_relative 'helper'
6
6
 
7
7
  class TestSprite < Test::Unit::TestCase
8
8
 
9
+ RS = RubySketch
10
+
9
11
  def sprite(*args, **kwargs)
10
- RubySketch::Sprite.new(*args, **kwargs)
12
+ RS::Sprite.new(*args, **kwargs)
11
13
  end
12
14
 
13
15
  def vec(*args, **kwargs)
14
- Processing::Vector.new(*args, **kwargs)
16
+ RS::Vector.new(*args, **kwargs)
17
+ end
18
+
19
+ def image(w, h)
20
+ RS::Image.new Rays::Image.new(w, h)
15
21
  end
16
22
 
17
23
  def test_initialize()
18
- assert_equal 0, sprite.x
19
- assert_equal 0, sprite.y
20
- assert_equal vec(0, 0), sprite.pos
24
+ assert_equal vec(0, 0), sprite .pos
25
+ assert_equal vec(1, 2), sprite(1, 2) .pos
26
+ assert_equal vec(1, 2), sprite(1, 2, 3, 4).pos
27
+
28
+ assert_equal vec(0, 0), sprite .size
29
+ assert_equal vec(3, 4), sprite(1, 2, 3, 4) .size
30
+ assert_equal vec(5, 6), sprite( image: image(5, 6)).size
31
+ assert_equal vec(5, 6), sprite(1, 2, image: image(5, 6)).size
32
+ assert_equal vec(3, 4), sprite(1, 2, 3, 4, image: image(5, 6)).size
33
+
34
+ assert_equal nil, sprite .image
35
+ assert_equal [1, 2], sprite(image: image(1, 2)).image.size
36
+
37
+ assert_equal nil, sprite.offset
38
+ assert_equal vec(1, 2), sprite(offset: [1, 2]).offset
39
+ assert_equal vec(1, 2), sprite(offset: vec(1, 2)).offset
40
+
41
+ assert_raise {sprite 0, 0, -1, 0}
42
+ assert_raise {sprite 0, 0, 0, -1}
43
+ end
44
+
45
+ def test_position()
46
+ s = sprite
47
+ assert_equal vec(0, 0), s.pos
48
+
49
+ s.pos = vec(1, 2)
50
+ assert_equal vec(1, 2), s.pos
51
+
52
+ s.pos = [3, 4]
53
+ assert_equal vec(3, 4), s.pos
54
+ end
55
+
56
+ def test_xy()
57
+ s = sprite
58
+ assert_equal 0, s.x
59
+ assert_equal vec(0, 0), s.pos
60
+
61
+ s.x = 1
62
+ assert_equal 1, s.x
63
+ assert_equal vec(1, 0), s.pos
64
+
65
+ s.y = 2
66
+ assert_equal 2, s.y
67
+ assert_equal vec(1, 2), s.pos
68
+ end
69
+
70
+ def test_size()
71
+ assert_equal vec(0, 0), sprite .size
72
+ assert_equal vec(1, 0), sprite(0, 0, 1) .size
73
+ assert_equal vec(1, 2), sprite(0, 0, 1, 2) .size
74
+ assert_equal vec(3, 4), sprite(image: image(3, 4)).size
75
+ end
76
+
77
+ def test_wh()
78
+ assert_equal 1, sprite(0, 0, 1, 2).width
79
+ assert_equal 2, sprite(0, 0, 1, 2).height
80
+ end
81
+
82
+ def test_velocity()
83
+ s = sprite
84
+ assert_equal vec(0, 0), s.vel
85
+
86
+ s.vel = vec(1, 2)
87
+ assert_equal vec(1, 2), s.vel
88
+
89
+ s.vel = [3, 4]
90
+ assert_equal vec(3, 4), s.vel
91
+ end
92
+
93
+ def test_vxvy()
94
+ s = sprite
95
+ assert_equal 0, s.vx
96
+ assert_equal vec(0, 0), s.vel
97
+
98
+ s.vx = 1
99
+ assert_equal 1, s.vx
100
+ assert_equal vec(1, 0), s.vel
101
+
102
+ s.vy = 2
103
+ assert_equal 2, s.vy
104
+ assert_equal vec(1, 2), s.vel
105
+ end
106
+
107
+ def test_image()
108
+ s = sprite
109
+ assert_equal nil, s.image
110
+
111
+ s.image = image(1, 2)
112
+ assert_equal [1, 2], s.image.size
113
+
114
+ s.image = image(3, 4)
115
+ assert_equal [3, 4], s.image.size
116
+
117
+ s.image = nil
118
+ assert_equal nil, s.image
119
+ end
120
+
121
+ def test_offset()
122
+ s = sprite
123
+ assert_equal nil, s.offset
124
+
125
+ s.offset = [1, 2]
126
+ assert_equal vec(1, 2), s.offset
127
+
128
+ s.offset = vec(3, 4)
129
+ assert_equal vec(3, 4), s.offset
130
+
131
+ s.offset = nil
132
+ assert_equal nil, s.offset
133
+
134
+ assert_raise(ArgumentError) {s.offset = 1}
135
+ end
136
+
137
+ def test_dynamic?()
138
+ s = sprite
139
+ assert_equal false, s.dynamic?
140
+
141
+ s.dynamic = true
142
+ assert_equal true, s.dynamic?
143
+
144
+ s.dynamic = false
145
+ assert_equal false, s.dynamic?
146
+ end
147
+
148
+ def test_density()
149
+ s = sprite
150
+ assert_equal 0, s.dens
151
+
152
+ s.dens = 1
153
+ assert_equal 1, s.dens
154
+ end
155
+
156
+ def test_friction()
157
+ s = sprite
158
+ assert_equal 0, s.fric
159
+
160
+ s.fric = 1
161
+ assert_equal 1, s.fric
162
+ end
163
+
164
+ def test_restitution()
165
+ s = sprite
166
+ assert_equal 0, s.rest
167
+
168
+ s.rest = 1
169
+ assert_equal 1, s.rest
170
+ end
171
+
172
+ def test_blocks()
173
+ s = sprite
174
+ v = s.instance_variable_get :@view__
175
+ assert_nil v.update
176
+ assert_nil v.contact
177
+ assert_nil v.will_contact
178
+
179
+ s.update {}
180
+ assert_not_nil v.update
181
+ assert_nil v.contact
182
+ assert_nil v.will_contact
183
+
184
+ s.contact {}
185
+ assert_not_nil v.update
186
+ assert_not_nil v.contact
187
+ assert_nil v.will_contact
188
+
189
+ s.contact? {}
190
+ assert_not_nil v.update
191
+ assert_not_nil v.contact
192
+ assert_not_nil v.will_contact
21
193
  end
22
194
 
23
195
  end# TestSprite
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysketch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - xordog
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-21 00:00:00.000000000 Z
11
+ date: 2023-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xot
@@ -16,84 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.33
19
+ version: 0.1.34
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.33
26
+ version: 0.1.34
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rucy
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.1.33
33
+ version: 0.1.34
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.1.33
40
+ version: 0.1.34
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: beeps
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.1.33
47
+ version: 0.1.35
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.1.33
54
+ version: 0.1.35
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rays
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.1.33
61
+ version: 0.1.34
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.1.33
68
+ version: 0.1.34
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: reflexion
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.1.33
75
+ version: 0.1.35
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.1.33
82
+ version: 0.1.35
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: processing
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.5.3
89
+ version: 0.5.5
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.5.3
96
+ version: 0.5.5
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement