rubysketch 0.5.4 → 0.5.7

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: 82a93ef9dac4ae855bfa85f9a076ed05c807875db70be9c5e72419137499434e
4
- data.tar.gz: 2f432e94c80ad231f50ca11df96ecd6a13c389551f75c426e161701e25d85a23
3
+ metadata.gz: a9465d904b4ad4eed514cb114281c1f19b49e692750456714152033cbabd3bea
4
+ data.tar.gz: aff3bf85d73c1dc26fc200647a77c0dc2c0133630450f33bb0e98c62b5ac6f5e
5
5
  SHA512:
6
- metadata.gz: cdf7238a4d07fe88b5d1fe3d68ea6f62d9536b142afda5dad1f4c15538bae2047d4e188bbc88e0777d641650ad9c5f5864720345ad5ec950e2ff18e83f552db9
7
- data.tar.gz: 310a71a0b3388876bd0c0910a09bb9aa12e5686e5885ec8e4b2a32cb4af629ed18a010731a77b4a8ea1a9a4be41de504098767d0d133e3344554d5078508ad29
6
+ metadata.gz: 68579b3732c2a114b8d421b61a92cbe611d412ed84bc3f1bb7cb3d81ff2cd28ecbbd35aa2469cad156fb7510cafcf624d79630a4422f4ba85ce98fd47a06b8c4
7
+ data.tar.gz: a8227ef0c4a0e7c9653f0825c3b8dfb74036058b2550cc1e5075f85d85579c1450e69f93d5bfd543e66f883b2798eca98af04b2f2747da7e54bdafeb5b99e60e
data/ChangeLog.md CHANGED
@@ -1,6 +1,33 @@
1
1
  # rubysketch ChangeLog
2
2
 
3
3
 
4
+ ## [v0.5.7] - 2023-05-13
5
+
6
+ - Update dependencies
7
+
8
+
9
+ ## [v0.5.6] - 2023-05-11
10
+
11
+ - Add Sprite#center accessor
12
+ - Add Sprite#size=, Sprite#width=, and Sprite#height=
13
+
14
+
15
+ ## [v0.5.5] - 2023-05-08
16
+
17
+ - Add Sprite#draw()
18
+ - Add Sprite#angle accessor
19
+ - Add Sprite#pivot accessor
20
+ - Add Sprite#ox and Sprite#oy
21
+ - Add mousePressed, mouseReleased, mouseMoved, mouseDragged, mouseClicked, touchStarted, touchEnded, and touchMoved to Sprite class
22
+ - Add inspect() to classes
23
+ - Alias draw methods
24
+ - Sprite has density 1 by default
25
+ - Sprite is static by deault
26
+ - Add sprite.rb and physics.rb as an example
27
+ - Delete Sound class
28
+ - Remove wall collision by default
29
+
30
+
4
31
  ## [v0.5.4] - 2023-04-30
5
32
 
6
33
  - Add Sprite#image=() and Sprite#offset=()
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.4
1
+ 0.5.7
@@ -0,0 +1,24 @@
1
+ %w[xot rucy beeps rays reflex processing rubysketch]
2
+ .map {|s| File.expand_path "../../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'rubysketch'
6
+ using RubySketch
7
+
8
+ noStroke
9
+ gravity 0, 1000
10
+
11
+ sprites = []
12
+ ground = createSprite 0, height - 10, width, 10
13
+
14
+ draw do
15
+ background 100
16
+ sprite *sprites, ground
17
+ end
18
+
19
+ mousePressed do
20
+ sp = createSprite mouseX, mouseY, 20, 20
21
+ sp.dynamic = true
22
+ sp.restitution = 0.5
23
+ sprites << sp
24
+ end
@@ -0,0 +1,47 @@
1
+ %w[xot rucy beeps rays reflex processing rubysketch]
2
+ .map {|s| File.expand_path "../../#{s}/lib", __dir__}
3
+ .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
4
+
5
+ require 'rubysketch'
6
+ using RubySketch
7
+
8
+ sp = createSprite 100, 100, 50, 50
9
+ sp.angle += Math::PI * 0.2
10
+
11
+ red = 0
12
+
13
+ sp.update do
14
+ red = (red + 1) % 255
15
+ end
16
+
17
+ sp.draw do |&draw|
18
+ fill red, 200, 200
19
+ draw.call
20
+ fill 0
21
+ text :hello, 10, 20
22
+ end
23
+
24
+ sp.mousePressed do
25
+ p [:pressed, sp.mouseX, sp.mouseY, sp.mouseButton]
26
+ end
27
+
28
+ sp.mouseReleased do
29
+ p [:released, sp.mouseX, sp.mouseY, sp.mouseButton]
30
+ end
31
+
32
+ sp.mouseMoved do
33
+ p [:moved, sp.mouseX, sp.mouseY, sp.pmouseX, sp.pmouseY]
34
+ end
35
+
36
+ sp.mouseDragged do
37
+ p [:dragged, sp.mouseX, sp.mouseY, sp.pmouseX, sp.pmouseY]
38
+ end
39
+
40
+ sp.mouseClicked do
41
+ p [:clicked, sp.mouseX, sp.mouseY, sp.mouseButton]
42
+ end
43
+
44
+ draw do
45
+ background 0
46
+ sprite sp
47
+ end
@@ -6,8 +6,6 @@ require 'rubysketch/window'
6
6
  require 'rubysketch/helper'
7
7
 
8
8
  require 'rubysketch/sprite'
9
- require 'rubysketch/sound'
10
- require 'rubysketch/graphics_context'
11
9
  require 'rubysketch/context'
12
10
 
13
11
 
@@ -3,9 +3,6 @@ module RubySketch
3
3
 
4
4
  class Context < Processing::Context
5
5
 
6
- include GraphicsContext
7
-
8
- Sound = RubySketch::Sound
9
6
  Sprite = RubySketch::Sprite
10
7
 
11
8
  # @private
@@ -43,13 +40,15 @@ module RubySketch
43
40
  # @param [Vector] off offset of sprite image
44
41
  #
45
42
  def createSprite(*args, **kwargs)
46
- addSprite Sprite.new(*args, **kwargs)
43
+ addSprite Sprite.new(*args, **kwargs, context: self)
47
44
  end
48
45
 
49
46
  # Adds the sprite to the physics engine.
50
47
  #
51
48
  # @param [Sprite] sprite sprite object
52
49
  #
50
+ # @return [Sprite] added sprite
51
+ #
53
52
  def addSprite(sprite)
54
53
  @layer__.add sprite.getInternal__ if sprite
55
54
  sprite
@@ -59,14 +58,57 @@ module RubySketch
59
58
  #
60
59
  # @param [Sprite] sprite sprite object
61
60
  #
61
+ # @return [Sprite] removed sprite
62
+ #
62
63
  def removeSprite(sprite)
63
64
  @layer__.remove sprite.getInternal__ if sprite
64
65
  sprite
65
66
  end
66
67
 
68
+ # Draws one or more sprites.
69
+ #
70
+ # @param [Array<Sprite>] sprites
71
+ #
72
+ # @return [nil] nil
73
+ #
74
+ def sprite(*sprites)
75
+ sprites.flatten! if sprites.first&.is_a? Array
76
+ sprites.each do |sp|
77
+ view, draw = sp.getInternal__, sp.instance_variable_get(:@drawBlock__)
78
+ f, degrees, pivot = view.frame, view.angle, view.pivot
79
+ if draw
80
+ push do
81
+ translate f.x + pivot.x * f.w, f.y + pivot.y * f.h
82
+ rotate fromDegrees__ degrees
83
+ translate (-pivot.x) * f.w, (-pivot.y) * f.h
84
+ draw.call {drawSprite__ sp, 0, 0, f.w, f.h}
85
+ end
86
+ elsif degrees == 0
87
+ drawSprite__ sp, f.x, f.y, f.w, f.h
88
+ else
89
+ pushMatrix do
90
+ translate f.x + pivot.x * f.w, f.y + pivot.y * f.h
91
+ rotate fromDegrees__ degrees
92
+ translate (-pivot.x) * f.w, (-pivot.y) * f.h
93
+ drawSprite__ sp, 0, 0, f.w, f.h
94
+ end
95
+ end
96
+ end
97
+ nil
98
+ end
99
+
100
+ alias drawSprite sprite
101
+
67
102
  # @private
68
- def loadSound(path)
69
- Sound.load path
103
+ def drawSprite__(sp, x, y, w, h)
104
+ img, off = sp.image, sp.offset
105
+ if img && off
106
+ copy img, off.x, off.y, w, h, x, y, w, h
107
+ elsif img
108
+ image img, x, y
109
+ else
110
+ rect x, y, w, h
111
+ end
70
112
  end
71
113
 
72
114
  # Sets gravity for the physics engine.
@@ -97,6 +139,11 @@ module RubySketch
97
139
  # @private
98
140
  class SpriteLayer < Reflex::View
99
141
 
142
+ def initialize(*a, **k, &b)
143
+ super
144
+ remove wall
145
+ end
146
+
100
147
  def on_draw(e)
101
148
  e.block
102
149
  end
@@ -5,6 +5,8 @@ module RubySketch
5
5
  #
6
6
  class Sprite
7
7
 
8
+ include Xot::Inspectable
9
+
8
10
  # Initialize sprite object.
9
11
  #
10
12
  # @overload new(image: img)
@@ -33,13 +35,20 @@ module RubySketch
33
35
  # @param [Image] img sprite image
34
36
  # @param [Vector] off offset of sprite image
35
37
  #
36
- def initialize(x = 0, y = 0, w = nil, h = nil, image: nil, offset: nil)
38
+ def initialize(
39
+ x = 0, y = 0, w = nil, h = nil, image: nil, offset: nil,
40
+ context: nil)
41
+
37
42
  w ||= (image&.width || 0)
38
43
  h ||= (image&.height || 0)
39
44
  raise 'invalid size' unless w >= 0 && h >= 0
40
45
  raise 'invalid image' if image && !image.getInternal__.is_a?(Rays::Image)
41
46
 
42
- @view__ = SpriteView.new(self, x: x, y: y, w: w, h: h, back: :white)
47
+ @context__ = context || Context.context__
48
+ @view__ = SpriteView.new(
49
+ self, x: x, y: y, w: w, h: h,
50
+ static: true, density: 1, friction: 0, restitution: 0,
51
+ back: :white)
43
52
 
44
53
  self.image = image if image
45
54
  self.offset = offset if offset
@@ -59,7 +68,7 @@ module RubySketch
59
68
  # @param [Vector] vec position vector
60
69
  #
61
70
  # @overload position=(ary)
62
- # @param [Array<Numeric>] ary positionX, positionY
71
+ # @param [Array<Numeric>] ary an array of positionX and positionY
63
72
  #
64
73
  # @return [Vector] position
65
74
  #
@@ -109,6 +118,30 @@ module RubySketch
109
118
  alias pos position
110
119
  alias pos= position=
111
120
 
121
+ # Returns the center position of the sprite.
122
+ #
123
+ # @return [Vector] center position
124
+ #
125
+ def center()
126
+ Vector.new(x + w / 2, y + h / 2)
127
+ end
128
+
129
+ # Sets the center position of the sprite.
130
+ #
131
+ # @overload center=(vec)
132
+ # @param [Vector] vec center position
133
+ #
134
+ # @overload center=(ary)
135
+ # @param [Array<Numeric>] ary an array of centerX and centerY
136
+ #
137
+ # @return [Vector] center position
138
+ #
139
+ def center=(arg)
140
+ x, y = *(arg.is_a?(Vector) ? arg.getInternal__.to_a : arg)
141
+ self.pos = [x - w / 2, y - h / 2]
142
+ self.center
143
+ end
144
+
112
145
  # Returns the size of the sprite.
113
146
  #
114
147
  # @return [Vector] size
@@ -117,6 +150,15 @@ module RubySketch
117
150
  @view__.size.toVector
118
151
  end
119
152
 
153
+ # Returns the size of the sprite.
154
+ #
155
+ # @return [Vector] size
156
+ #
157
+ def size=(arg)
158
+ @view__.size = arg.is_a?(Vector) ? arg.getInternal__ : arg
159
+ arg
160
+ end
161
+
120
162
  # Returns the width of the sprite.
121
163
  #
122
164
  # @return [Numeric] width
@@ -125,6 +167,16 @@ module RubySketch
125
167
  @view__.width
126
168
  end
127
169
 
170
+ # Sets the width of the sprite.
171
+ #
172
+ # @param [Numeric] w width
173
+ #
174
+ # @return [Numeric] width
175
+ #
176
+ def width=(w)
177
+ @view__.width = w
178
+ end
179
+
128
180
  # Returns the height of the sprite.
129
181
  #
130
182
  # @return [Numeric] height
@@ -133,8 +185,62 @@ module RubySketch
133
185
  @view__.height
134
186
  end
135
187
 
136
- alias w width
137
- alias h height
188
+ # Sets the height of the sprite.
189
+ #
190
+ # @param [Numeric] h height
191
+ #
192
+ # @return [Numeric] height
193
+ #
194
+ def height=(h)
195
+ @view__.height = h
196
+ end
197
+
198
+ alias w width
199
+ alias w= width=
200
+ alias h height
201
+ alias h= height=
202
+
203
+ # Returns the rotation angle of sprite.
204
+ #
205
+ # @return [Numeric] radians or degrees depending on angleMode()
206
+ #
207
+ def angle()
208
+ a, c = @view__.angle, @context__
209
+ c ? c.fromDegrees__(a) : a * Processing::GraphicsContext::DEG2RAD__
210
+ end
211
+
212
+ # Sets the rotation angle of sprite.
213
+ #
214
+ # @param [Numeric] angle radians or degrees depending on angleMode()
215
+ #
216
+ # @return [Numeric] angle
217
+ #
218
+ def angle=(angle)
219
+ c = @context__
220
+ @view__.angle =
221
+ c ? c.toAngle__(angle) : angle * Processing::GraphicsContext::RAD2DEG__
222
+ angle
223
+ end
224
+
225
+ # Returns the rotation center of sprite.
226
+ #
227
+ # @return [Array<Numeric>] [pivotX, pivotY]
228
+ #
229
+ def pivot()
230
+ @view__.pivot.to_a[0, 2]
231
+ end
232
+
233
+ # Sets the rotation center of sprite.
234
+ # [0.0, 0.0] is the left-top, [1.0, 1.0] is the right-bottom, and [0.5, 0.5] is the center.
235
+ #
236
+ # @param [Array<Numeric>] ary an array of pivotX and pivotY
237
+ #
238
+ # @return [Array<Numeric>] [pivotX, pivotY]
239
+ #
240
+ def pivot=(array)
241
+ @view__.pivot = array
242
+ pivot
243
+ end
138
244
 
139
245
  # Returns the velocity of the sprite.
140
246
  #
@@ -150,7 +256,7 @@ module RubySketch
150
256
  # @param [Vector] vec velocity vector
151
257
  #
152
258
  # @overload velocity=(ary)
153
- # @param [Array<Numeric>] ary velocityX, velocityY
259
+ # @param [Array<Numeric>] ary an array of velocityX and velocityY
154
260
  #
155
261
  # @return [Vector] velocity
156
262
  #
@@ -226,14 +332,62 @@ module RubySketch
226
332
  @offset__
227
333
  end
228
334
 
335
+ # Sets the offset of the sprite image.
336
+ #
337
+ # @overload offset=(vec)
338
+ # @param [Vector] vec offset
339
+ #
340
+ # @overload velocity=(ary)
341
+ # @param [Array<Numeric>] ary an array of offsetX and offsetY
342
+ #
343
+ # @return [Vector] offset of the sprite image
344
+ #
229
345
  def offset=(arg)
230
346
  @offset__ =
231
347
  case arg
232
348
  when Vector then arg
233
- when Array then Vector.new(*arg[0, 2])
349
+ when Array then Vector.new(arg[0] || 0, arg[1] || 0)
234
350
  when nil then nil
235
351
  else raise ArgumentError
236
352
  end
353
+ @offset__
354
+ end
355
+
356
+ # Returns the x-axis offset of the sprite image.
357
+ #
358
+ # @return [Numeric] offset.x
359
+ #
360
+ def ox()
361
+ @offset__&.x || 0
362
+ end
363
+
364
+ # Sets the x-axis offset of the sprite image.
365
+ #
366
+ # @param [Numeric] n x-axis offset
367
+ #
368
+ # @return [Numeric] offset.x
369
+ #
370
+ def ox=(n)
371
+ self.offset = [n, oy]
372
+ n
373
+ end
374
+
375
+ # Returns the y-axis offset of the sprite image.
376
+ #
377
+ # @return [Numeric] offset.y
378
+ #
379
+ def oy()
380
+ @offset__&.y || 0
381
+ end
382
+
383
+ # Sets the y-axis offset of the sprite image.
384
+ #
385
+ # @param [Numeric] n y-axis offset
386
+ #
387
+ # @return [Numeric] offset.y
388
+ #
389
+ def oy=(n)
390
+ self.offset = [ox, n]
237
391
  end
238
392
 
239
393
  # Returns whether the sprite is movable by the physics engine.
@@ -319,6 +473,54 @@ module RubySketch
319
473
  alias rest restitution
320
474
  alias rest= restitution=
321
475
 
476
+ # Returns the x-position of the mouse in the sprite coordinates.
477
+ #
478
+ # @return [Numeric] x position
479
+ #
480
+ def mouseX()
481
+ @view__.mouseX
482
+ end
483
+
484
+ # Returns the y-position of the mouse in the sprite coordinates.
485
+ #
486
+ # @return [Numeric] y position
487
+ #
488
+ def mouseY()
489
+ @view__.mouseY
490
+ end
491
+
492
+ # Returns the previous x-position of the mouse in the sprite coordinates.
493
+ #
494
+ # @return [Numeric] x position
495
+ #
496
+ def pmouseX()
497
+ @view__.pmouseX
498
+ end
499
+
500
+ # Returns the previous y-position of the mouse in the sprite coordinates.
501
+ #
502
+ # @return [Numeric] y position
503
+ #
504
+ def pmouseY()
505
+ @view__.pmouseY
506
+ end
507
+
508
+ # Returns the mouse button clicked on the sprite.
509
+ #
510
+ # @return [LEFT, RIGHT, CENTER] mouse button
511
+ #
512
+ def mouseButton()
513
+ @view__.mouseButton
514
+ end
515
+
516
+ # Returns the touch objects touched on the sprite.
517
+ #
518
+ # @return [Array<Touch>] touches
519
+ #
520
+ def touches()
521
+ @view__.touches
522
+ end
523
+
322
524
  # Defines update block.
323
525
  #
324
526
  # @example vx is updated every frame
@@ -332,6 +534,134 @@ module RubySketch
332
534
  @view__.update = block
333
535
  end
334
536
 
537
+ # Defines draw block.
538
+ #
539
+ # @example Draw on your own before and after default drawing
540
+ # sprite.draw do |&defaultDrawSprite|
541
+ # rect 0, 0, 10, 10
542
+ # defaultDrawSprite.call
543
+ # text :hello, 10, 20
544
+ # end
545
+ #
546
+ # @return [nil] nil
547
+ #
548
+ def draw(&block)
549
+ @drawBlock__ = block
550
+ nil
551
+ end
552
+
553
+ # Defines mousePressed block.
554
+ #
555
+ # @example Print mouse states on mouse press
556
+ # sprite.mousePressed do
557
+ # p [sprite.mouseX, sprite.mouseY, sprite.mouseButton]
558
+ # end
559
+ #
560
+ # @return [nil] nil
561
+ #
562
+ def mousePressed(&block)
563
+ @view__.mousePressed = block
564
+ nil
565
+ end
566
+
567
+ # Defines mouseReleased block.
568
+ #
569
+ # @example Print mouse states on mouse release
570
+ # sprite.mouseReleased do
571
+ # p [sprite.mouseX, sprite.mouseY, sprite.mouseButton]
572
+ # end
573
+ #
574
+ # @return [nil] nil
575
+ #
576
+ def mouseReleased(&block)
577
+ @view__.mouseReleased = block
578
+ nil
579
+ end
580
+
581
+ # Defines mouseMoved block.
582
+ #
583
+ # @example Print mouse states on mouse move
584
+ # sprite.mouseMoved do
585
+ # p [sprite.mouseX, sprite.mouseY, sprite.pmouseX, sprite.pmouseY]
586
+ # end
587
+ #
588
+ # @return [nil] nil
589
+ #
590
+ def mouseMoved(&block)
591
+ @view__.mouseMoved = block
592
+ nil
593
+ end
594
+
595
+ # Defines mouseDragged block.
596
+ #
597
+ # @example Print mouse states on mouse drag
598
+ # sprite.mouseDragged do
599
+ # p [sprite.mouseX, sprite.mouseY, sprite.pmouseX, sprite.pmouseY]
600
+ # end
601
+ #
602
+ # @return [nil] nil
603
+ #
604
+ def mouseDragged(&block)
605
+ @view__.mouseDragged = block
606
+ nil
607
+ end
608
+
609
+ # Defines mouseClicked block.
610
+ #
611
+ # @example Print mouse states on mouse click
612
+ # sprite.mouseClicked do
613
+ # p [sprite.mouseX, sprite.mouseY, sprite.mouseButton]
614
+ # end
615
+ #
616
+ # @return [nil] nil
617
+ #
618
+ def mouseClicked(&block)
619
+ @view__.mouseClicked = block
620
+ nil
621
+ end
622
+
623
+ # Defines touchStarted block.
624
+ #
625
+ # @example Print touches on touch start
626
+ # sprite.touchStarted do
627
+ # p sprite.touches
628
+ # end
629
+ #
630
+ # @return [nil] nil
631
+ #
632
+ def touchStarted(&block)
633
+ @view__.touchStarted = block
634
+ nil
635
+ end
636
+
637
+ # Defines touchEnded block.
638
+ #
639
+ # @example Print touches on touch end
640
+ # sprite.touchEnded do
641
+ # p sprite.touches
642
+ # end
643
+ #
644
+ # @return [nil] nil
645
+ #
646
+ def touchEnded(&block)
647
+ @view__.touchEnded = block
648
+ nil
649
+ end
650
+
651
+ # Defines touchMoved block.
652
+ #
653
+ # @example Print touches on touch move
654
+ # sprite.touchMoved do
655
+ # p sprite.touches
656
+ # end
657
+ #
658
+ # @return [nil] nil
659
+ #
660
+ def touchMoved(&block)
661
+ @view__.touchMoved = block
662
+ nil
663
+ end
664
+
335
665
  # Defines contact block.
336
666
  #
337
667
  # @example Score increases when the player sprite touches a coin
@@ -347,7 +677,7 @@ module RubySketch
347
677
 
348
678
  # Defines contact? block.
349
679
  #
350
- # @example only collide with an enemy
680
+ # @example Only collide with an enemy
351
681
  # playerSprite.contact? do |o|
352
682
  # o.enemy?
353
683
  # end
@@ -358,18 +688,6 @@ module RubySketch
358
688
  @view__.will_contact = block
359
689
  end
360
690
 
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
-
373
691
  # @private
374
692
  def getInternal__()
375
693
  @view__
@@ -381,28 +699,106 @@ module RubySketch
381
699
  # @private
382
700
  class SpriteView < Reflex::View
383
701
 
384
- attr_accessor :update, :contact, :will_contact
385
- attr_reader :sprite
702
+ attr_accessor :update,
703
+ :mousePressed, :mouseReleased, :mouseMoved, :mouseDragged, :mouseClicked,
704
+ :touchStarted, :touchEnded, :touchMoved,
705
+ :contact, :will_contact
706
+
707
+ attr_reader :sprite, :touches
386
708
 
387
709
  def initialize(sprite, *a, **k, &b)
388
710
  @sprite = sprite
389
711
  super(*a, **k, &b)
712
+
713
+ @pointerPos =
714
+ @pointerPrevPos = Rays::Point.new 0
715
+ @pointersPressed = []
716
+ @pointersReleased = []
717
+ @touches = []
718
+ end
719
+
720
+ def mouseX()
721
+ @pointerPos.x
722
+ end
723
+
724
+ def mouseY()
725
+ @pointerPos.y
726
+ end
727
+
728
+ def pmouseX()
729
+ @pointerPrevPos.x
730
+ end
731
+
732
+ def pmouseY()
733
+ @pointerPrevPos.y
734
+ end
735
+
736
+ def mouseButton()
737
+ ((@pointersPressed + @pointersReleased) & [LEFT, RIGHT, CENTER]).last
390
738
  end
391
739
 
392
740
  def on_update(e)
393
- @update.call if @update
741
+ @update&.call
742
+ end
743
+
744
+ def on_pointer_down(e)
745
+ updatePointerStates e, true
746
+ @pointerDownStartPos = @pointerPos.dup
747
+ (@touchStarted || @mousePressed)&.call
748
+ end
749
+
750
+ def on_pointer_up(e)
751
+ updatePointerStates e, false
752
+ (@touchEnded || @mouseReleased)&.call
753
+ if startPos = @pointerDownStartPos
754
+ @mouseClicked&.call if (@pointerPos - startPos).length < 3
755
+ @pointerDownStartPos = nil
756
+ end
757
+ @pointersReleased.clear
758
+ end
759
+
760
+ def on_pointer_move(e)
761
+ updatePointerStates e
762
+ (@touchMoved || (e.drag? ? @mouseDragged : @mouseMoved))&.call
763
+ end
764
+
765
+ def on_pointer_cancel(e)
766
+ on_pointer_up e
394
767
  end
395
768
 
396
769
  def on_contact(e)
397
770
  v = e.view
398
- @contact.call v.sprite, e.action if @contact && v.is_a?(SpriteView)
771
+ @contact.call v.sprite, e.action if @contact && v.respond_to?(:sprite)
399
772
  end
400
773
 
401
774
  def will_contact?(v)
402
- return true if !@will_contact || !v.is_a?(SpriteView)
775
+ return true unless @will_contact && v.respond_to?(:sprite)
403
776
  @will_contact.call v.sprite
404
777
  end
405
778
 
779
+ private
780
+
781
+ MOUSE_BUTTON_MAP = {
782
+ mouse_left: Processing::GraphicsContext::LEFT,
783
+ mouse_right: Processing::GraphicsContext::RIGHT,
784
+ mouse_middle: Processing::GraphicsContext::CENTER
785
+ }
786
+
787
+ def updatePointerStates(event, pressed = nil)
788
+ @pointerPrevPos = @pointerPos
789
+ @pointerPos = event.pos.dup
790
+ @touches = event.pointers.map {|p| Touch.new(p.id, *p.pos.to_a)}
791
+ if pressed != nil
792
+ event.types
793
+ .tap {|types| types.delete :mouse}
794
+ .map {|type| MOUSE_BUTTON_MAP[type] || type}
795
+ .each do |type|
796
+ (pressed ? @pointersPressed : @pointersReleased).push type
797
+ @pointersPressed.delete type unless pressed
798
+ end
799
+ end
800
+ end
801
+
406
802
  end# SpriteView
407
803
 
408
804
 
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.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'
31
+ s.add_runtime_dependency 'xot', '~> 0.1.35'
32
+ s.add_runtime_dependency 'rucy', '~> 0.1.35'
33
+ s.add_runtime_dependency 'beeps', '~> 0.1.36'
34
+ s.add_runtime_dependency 'rays', '~> 0.1.36'
35
+ s.add_runtime_dependency 'reflexion', '~> 0.1.38'
36
+ s.add_runtime_dependency 'processing', '~> 0.5.8'
37
37
 
38
38
  s.add_development_dependency 'rake'
39
39
  s.add_development_dependency 'test-unit'
data/test/helper.rb CHANGED
@@ -1,6 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
1
  %w[../xot ../rucy ../beeps ../rays ../reflex ../processing .]
5
2
  .map {|s| File.expand_path "../#{s}/lib", __dir__}
6
3
  .each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
data/test/test_sprite.rb CHANGED
@@ -1,6 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
1
  require_relative 'helper'
5
2
 
6
3
 
@@ -67,16 +64,65 @@ class TestSprite < Test::Unit::TestCase
67
64
  assert_equal vec(1, 2), s.pos
68
65
  end
69
66
 
67
+ def test_center()
68
+ s = sprite 0, 0, 10, 20
69
+ assert_equal vec( 5, 10), s.center
70
+
71
+ s.center = vec 100, 200
72
+ assert_equal vec( 95, 190), s.pos
73
+
74
+ s.center = [300, 400]
75
+ assert_equal vec(295, 390), s.pos
76
+ end
77
+
70
78
  def test_size()
71
79
  assert_equal vec(0, 0), sprite .size
72
80
  assert_equal vec(1, 0), sprite(0, 0, 1) .size
73
81
  assert_equal vec(1, 2), sprite(0, 0, 1, 2) .size
74
82
  assert_equal vec(3, 4), sprite(image: image(3, 4)).size
83
+
84
+ s = sprite
85
+ s.size = vec 10, 20
86
+ assert_equal vec(10, 20), s.size
87
+
88
+ s.size = [30, 40]
89
+ assert_equal vec(30, 40), s.size
75
90
  end
76
91
 
77
92
  def test_wh()
78
93
  assert_equal 1, sprite(0, 0, 1, 2).width
94
+ assert_equal 1, sprite(0, 0, 1, 2).w
79
95
  assert_equal 2, sprite(0, 0, 1, 2).height
96
+ assert_equal 2, sprite(0, 0, 1, 2).h
97
+
98
+ s = sprite
99
+ s.width = 10
100
+ assert_equal vec(10, 0), s.size
101
+
102
+ s.w = 20
103
+ assert_equal vec(20, 0), s.size
104
+
105
+ s.height = 30
106
+ assert_equal vec(20, 30), s.size
107
+
108
+ s.h = 40
109
+ assert_equal vec(20, 40), s.size
110
+ end
111
+
112
+ def test_angle()
113
+ s = sprite
114
+ assert_equal 0, s.angle
115
+
116
+ s.angle = Math::PI
117
+ assert_in_epsilon Math::PI, s.angle
118
+ end
119
+
120
+ def test_pivot()
121
+ s = sprite
122
+ assert_each_in_epsilon [0, 0], s.pivot
123
+
124
+ s.pivot = [0.1, 0.2]
125
+ assert_each_in_epsilon [0.1, 0.2], s.pivot
80
126
  end
81
127
 
82
128
  def test_velocity()
@@ -122,18 +168,44 @@ class TestSprite < Test::Unit::TestCase
122
168
  s = sprite
123
169
  assert_equal nil, s.offset
124
170
 
125
- s.offset = [1, 2]
171
+ s.offset = [1, 2]
126
172
  assert_equal vec(1, 2), s.offset
127
173
 
128
- s.offset = vec(3, 4)
174
+ s.offset = vec(3, 4)
129
175
  assert_equal vec(3, 4), s.offset
130
176
 
131
- s.offset = nil
177
+ s.offset = [5]
178
+ assert_equal vec(5, 0), s.offset
179
+
180
+ s.offset = []
181
+ assert_equal vec(0, 0), s.offset
182
+
183
+ s.offset = nil
132
184
  assert_equal nil, s.offset
133
185
 
134
186
  assert_raise(ArgumentError) {s.offset = 1}
135
187
  end
136
188
 
189
+ def test_oxoy()
190
+ s = sprite
191
+ assert_equal [0, 0], [s.ox, s.oy]
192
+ assert_equal nil, s.offset
193
+
194
+ s.ox = 1
195
+ assert_equal [1, 0], [s.ox, s.oy]
196
+ assert_equal vec(1, 0), s.offset
197
+
198
+ s = sprite
199
+
200
+ s.oy = 2
201
+ assert_equal [0, 2], [s.ox, s.oy]
202
+ assert_equal vec(0, 2), s.offset
203
+
204
+ s.offset = nil
205
+ assert_equal [0, 0], [s.ox, s.oy]
206
+ assert_equal nil, s.offset
207
+ end
208
+
137
209
  def test_dynamic?()
138
210
  s = sprite
139
211
  assert_equal false, s.dynamic?
@@ -147,10 +219,10 @@ class TestSprite < Test::Unit::TestCase
147
219
 
148
220
  def test_density()
149
221
  s = sprite
150
- assert_equal 0, s.dens
151
-
152
- s.dens = 1
153
222
  assert_equal 1, s.dens
223
+
224
+ s.dens = 2
225
+ assert_equal 2, s.dens
154
226
  end
155
227
 
156
228
  def test_friction()
@@ -192,4 +264,8 @@ class TestSprite < Test::Unit::TestCase
192
264
  assert_not_nil v.will_contact
193
265
  end
194
266
 
267
+ def test_inspect()
268
+ assert_match %r|#<RubySketch::Sprite:0x\w{16}>|, sprite.inspect
269
+ end
270
+
195
271
  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.4
4
+ version: 0.5.7
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-30 00:00:00.000000000 Z
11
+ date: 2023-05-12 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.34
19
+ version: 0.1.35
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.34
26
+ version: 0.1.35
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.34
33
+ version: 0.1.35
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.34
40
+ version: 0.1.35
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.35
47
+ version: 0.1.36
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.35
54
+ version: 0.1.36
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.34
61
+ version: 0.1.36
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.34
68
+ version: 0.1.36
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.35
75
+ version: 0.1.38
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.35
82
+ version: 0.1.38
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.5
89
+ version: 0.5.8
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.5
96
+ version: 0.5.8
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -156,13 +156,13 @@ files:
156
156
  - RubySketch.podspec
157
157
  - VERSION
158
158
  - examples/hello.rb
159
+ - examples/physics.rb
160
+ - examples/sprite.rb
159
161
  - lib/rubysketch.rb
160
162
  - lib/rubysketch/all.rb
161
163
  - lib/rubysketch/context.rb
162
164
  - lib/rubysketch/extension.rb
163
- - lib/rubysketch/graphics_context.rb
164
165
  - lib/rubysketch/helper.rb
165
- - lib/rubysketch/sound.rb
166
166
  - lib/rubysketch/sprite.rb
167
167
  - lib/rubysketch/window.rb
168
168
  - pod.rake
@@ -170,7 +170,6 @@ files:
170
170
  - src/RubySketch.h
171
171
  - src/RubySketch.mm
172
172
  - test/helper.rb
173
- - test/test_sound.rb
174
173
  - test/test_sprite.rb
175
174
  homepage: https://github.com/xord/rubysketch
176
175
  licenses: []
@@ -196,5 +195,4 @@ specification_version: 4
196
195
  summary: A game engine based on the Processing API.
197
196
  test_files:
198
197
  - test/helper.rb
199
- - test/test_sound.rb
200
198
  - test/test_sprite.rb
@@ -1,30 +0,0 @@
1
- module RubySketch
2
-
3
-
4
- module GraphicsContext
5
-
6
- # Draws one or more sprites.
7
- #
8
- # @param [Array<Sprite>] sprites
9
- #
10
- def sprite(*sprites)
11
- sprites.flatten! if sprites.first&.is_a? Array
12
- sprites.each do |sp|
13
- v = sp.getInternal__
14
- f, angle = v.frame, v.angle
15
- if angle == 0
16
- sp.on_draw__ f.x, f.y, f.w, f.h
17
- else
18
- pushMatrix do
19
- translate f.x, f.y
20
- rotate radians(angle)
21
- sp.on_draw__ 0, 0, f.w, f.h
22
- end
23
- end
24
- end
25
- end
26
-
27
- end# GraphicsContext
28
-
29
-
30
- end# RubySketch
@@ -1,86 +0,0 @@
1
- module RubySketch
2
-
3
-
4
- # @private
5
- class Sound
6
-
7
- # @private
8
- def initialize(sound)
9
- @sound = sound
10
- end
11
-
12
- # Play sound.
13
- #
14
- def play()
15
- old = @player
16
- @player = @sound.play
17
- old&.stop
18
- true
19
- end
20
-
21
- # Pause sound.
22
- #
23
- def pause()
24
- return false unless @player
25
- @player.pause
26
- true
27
- end
28
-
29
- # Stop sound.
30
- #
31
- def stop()
32
- return false unless @player
33
- @player.stop
34
- @player = nil
35
- true
36
- end
37
-
38
- # Returns whether the sound is playing or not.
39
- #
40
- # @return [Boolean] playing or not
41
- #
42
- def playing?()
43
- @player ? @player.playing? : false
44
- end
45
-
46
- # Returns whether the sound is paused or not.
47
- #
48
- # @return [Boolean] paused or not
49
- #
50
- def paused?()
51
- @player ? @player.paused? : false
52
- end
53
-
54
- # Returns whether the sound is stopped or not.
55
- #
56
- # @return [Boolean] stopped or not
57
- #
58
- def stopped?()
59
- @player ? @player.stopped? : true
60
- end
61
-
62
- # Save the sound data to a file.
63
- #
64
- # @param [String] path file path
65
- #
66
- # @return [Sound] self
67
- #
68
- def save(path)
69
- @sound.save path
70
- end
71
-
72
- # Load a sound file.
73
- #
74
- # @param [String] path file path
75
- #
76
- # @return [Sound] sound object
77
- #
78
- def self.load(path)
79
- f = Beeps::FileIn.new path
80
- self.new Beeps::Sound.new(f, f.seconds, nchannels: f.nchannels)
81
- end
82
-
83
- end# Sound
84
-
85
-
86
- end# RubySketch
data/test/test_sound.rb DELETED
@@ -1,88 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
- require_relative 'helper'
5
-
6
-
7
- class TestSound < Test::Unit::TestCase
8
-
9
- RS = RubySketch
10
- B = Beeps
11
-
12
- PATH = 'test.wav'
13
-
14
- def sound()
15
- RS::Sound.load PATH
16
- end
17
-
18
- def setup()
19
- B::Sound.new(B::Oscillator.new >> B::Gain.new(gain: 0), 0.1).save PATH
20
- end
21
-
22
- def teardown()
23
- B::SoundPlayer.stop_all
24
- File.delete PATH if File.exist?(PATH)
25
- end
26
-
27
- def test_play()
28
- s = sound
29
- assert_equal [false, false, true], [s.playing?, s.paused?, s.stopped?]
30
- s.play
31
- assert_equal [true, false, false], [s.playing?, s.paused?, s.stopped?]
32
- end
33
-
34
- def test_pause()
35
- s = sound
36
- s.play
37
- assert_equal [true, false, false], [s.playing?, s.paused?, s.stopped?]
38
- s.pause
39
- assert_equal [false, true, false], [s.playing?, s.paused?, s.stopped?]
40
- end
41
-
42
- def test_stop()
43
- s = sound
44
- s.play
45
- assert_equal [true, false, false], [s.playing?, s.paused?, s.stopped?]
46
- s.stop
47
- assert_equal [false, false, true], [s.playing?, s.paused?, s.stopped?]
48
- end
49
-
50
- def test_play_end_then_stop()
51
- s = sound
52
- s.play
53
- assert_equal [true, false, false], [s.playing?, s.paused?, s.stopped?]
54
- sleep 0.2
55
- assert_equal [false, false, true], [s.playing?, s.paused?, s.stopped?]
56
- end
57
-
58
- def test_play_after_pause()
59
- s = sound
60
- s.play
61
- s.pause
62
- assert_equal [false, true, false], [s.playing?, s.paused?, s.stopped?]
63
- s.play
64
- assert_equal [true, false, false], [s.playing?, s.paused?, s.stopped?]
65
- end
66
-
67
- def test_stop_after_pause()
68
- s = sound
69
- s.play
70
- s.pause
71
- assert_equal [false, true, false], [s.playing?, s.paused?, s.stopped?]
72
- s.stop
73
- assert_equal [false, false, true], [s.playing?, s.paused?, s.stopped?]
74
- end
75
-
76
- def test_save_load()
77
- s = sound
78
-
79
- File.delete PATH
80
- assert_false File.exist? PATH
81
-
82
- s.save PATH
83
- assert_true File.exist? PATH
84
-
85
- assert_nothing_raised {RS::Sound.load(PATH).play}
86
- end
87
-
88
- end# TestSound