rubysketch 0.5.3 → 0.5.5

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.
@@ -1,128 +1,750 @@
1
1
  module RubySketch
2
2
 
3
3
 
4
+ # Sprite object.
5
+ #
4
6
  class Sprite
5
7
 
6
- extend Forwardable
8
+ include Xot::Inspectable
7
9
 
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
10
+ # Initialize sprite object.
11
+ #
12
+ # @overload new(image: img)
13
+ # pos: [0, 0], size: [image.width, image.height]
14
+ # @param [Image] img sprite image
15
+ #
16
+ # @overload new(x, y, image: img)
17
+ # pos: [x, y], size: [image.width, image.height]
18
+ # @param [Numeric] x x of sprite position
19
+ # @param [Numeric] y y of sprite position
20
+ # @param [Image] img sprite image
21
+ #
22
+ # @overload new(x, y, w, h)
23
+ # pos(x, y), size: [w, h]
24
+ # @param [Numeric] x x of sprite position
25
+ # @param [Numeric] y y of sprite position
26
+ # @param [Numeric] w width of sprite
27
+ # @param [Numeric] h height of sprite
28
+ #
29
+ # @overload new(x, y, w, h, image: img, offset: off)
30
+ # pos: [x, y], size: [w, h], offset: [offset.x, offset.x]
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
+ # @param [Image] img sprite image
36
+ # @param [Vector] off offset of sprite image
37
+ #
38
+ def initialize(
39
+ x = 0, y = 0, w = nil, h = nil, image: nil, offset: nil,
40
+ context: nil)
12
41
 
13
- @image__, @offset__ = image, offset
14
- @view__ = View.new self, x: x, y: y, w: w, h: h, back: :white, dynamic: dynamic
42
+ w ||= (image&.width || 0)
43
+ h ||= (image&.height || 0)
44
+ raise 'invalid size' unless w >= 0 && h >= 0
45
+ raise 'invalid image' if image && !image.getInternal__.is_a?(Rays::Image)
46
+
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)
52
+
53
+ self.image = image if image
54
+ self.offset = offset if offset
15
55
  end
16
56
 
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=
57
+ # Returns the position of the sprite.
58
+ #
59
+ # @return [Vector] position
60
+ #
61
+ def position()
62
+ @view__.position.toVector
63
+ end
26
64
 
27
- def update(&block)
28
- @view__.on_update = block
65
+ # Sets the position of the sprite.
66
+ #
67
+ # @overload position=(vec)
68
+ # @param [Vector] vec position vector
69
+ #
70
+ # @overload position=(ary)
71
+ # @param [Array<Numeric>] ary an array of positionX and positionY
72
+ #
73
+ # @return [Vector] position
74
+ #
75
+ def position=(arg)
76
+ @view__.position = arg.is_a?(Vector) ? arg.getInternal__ : arg
77
+ arg
29
78
  end
30
79
 
31
- def contact(&block)
32
- @view__.on_contact = block
80
+ # Returns the x-coordinate position of the sprite.
81
+ #
82
+ # @return [Numeric] sprite position x
83
+ #
84
+ def x()
85
+ @view__.x
33
86
  end
34
87
 
35
- def contact?(&block)
36
- @view__.will_contact = block
88
+ # Set the x-coordinate position of the sprite.
89
+ #
90
+ # @param [Numeric] n sprite position x
91
+ #
92
+ # @return [Numeric] sprite position x
93
+ #
94
+ def x=(n)
95
+ @view__.x = n
96
+ n
37
97
  end
38
98
 
39
- def position()
40
- @view__.position.toVector
99
+ # Returns the y-coordinate position of the sprite.
100
+ #
101
+ # @return [Numeric] sprite position y
102
+ #
103
+ def y()
104
+ @view__.y
41
105
  end
42
106
 
43
- def position=(vector)
44
- @view__.position = vector.getInternal__
107
+ # Set the y-coordinate position of the sprite.
108
+ #
109
+ # @param [Numeric] n sprite position y
110
+ #
111
+ # @return [Numeric] sprite position y
112
+ #
113
+ def y=(n)
114
+ @view__.y = n
115
+ n
45
116
  end
46
117
 
118
+ alias pos position
119
+ alias pos= position=
120
+
121
+ # Returns the size of the sprite.
122
+ #
123
+ # @return [Vector] size
124
+ #
47
125
  def size()
48
126
  @view__.size.toVector
49
127
  end
50
128
 
51
- def image()
52
- @image__
129
+ # Returns the width of the sprite.
130
+ #
131
+ # @return [Numeric] width
132
+ #
133
+ def width()
134
+ @view__.width
53
135
  end
54
136
 
55
- def offset()
56
- @offset__
137
+ # Returns the height of the sprite.
138
+ #
139
+ # @return [Numeric] height
140
+ #
141
+ def height()
142
+ @view__.height
57
143
  end
58
144
 
145
+ alias w width
146
+ alias h height
147
+
148
+ # Returns the rotation angle of sprite.
149
+ #
150
+ # @return [Numeric] radians or degrees depending on angleMode()
151
+ #
152
+ def angle()
153
+ a, c = @view__.angle, @context__
154
+ c ? c.fromDegrees__(a) : a * Processing::GraphicsContext::DEG2RAD__
155
+ end
156
+
157
+ # Sets the rotation angle of sprite.
158
+ #
159
+ # @param [Numeric] angle radians or degrees depending on angleMode()
160
+ #
161
+ # @return [Numeric] angle
162
+ #
163
+ def angle=(angle)
164
+ c = @context__
165
+ @view__.angle =
166
+ c ? c.toAngle__(angle) : angle * Processing::GraphicsContext::RAD2DEG__
167
+ angle
168
+ end
169
+
170
+ # Returns the rotation center of sprite.
171
+ #
172
+ # @return [Array<Numeric>] [pivotX, pivotY]
173
+ #
174
+ def pivot()
175
+ @view__.pivot.to_a[0, 2]
176
+ end
177
+
178
+ # Sets the rotation center of sprite.
179
+ # [0.0, 0.0] is the left-top, [1.0, 1.0] is the right-bottom, and [0.5, 0.5] is the center.
180
+ #
181
+ # @param [Array<Numeric>] ary an array of pivotX and pivotY
182
+ #
183
+ # @return [Array<Numeric>] [pivotX, pivotY]
184
+ #
185
+ def pivot=(array)
186
+ @view__.pivot = array
187
+ pivot
188
+ end
189
+
190
+ # Returns the velocity of the sprite.
191
+ #
192
+ # @return [Vector] velocity
193
+ #
59
194
  def velocity()
60
195
  @view__.velocity.toVector
61
196
  end
62
197
 
63
- def velocity=(vector)
64
- @view__.velocity = vector.getInternal__
198
+ # Sets the velocity of the sprite.
199
+ #
200
+ # @overload velocity=(vec)
201
+ # @param [Vector] vec velocity vector
202
+ #
203
+ # @overload velocity=(ary)
204
+ # @param [Array<Numeric>] ary an array of velocityX and velocityY
205
+ #
206
+ # @return [Vector] velocity
207
+ #
208
+ def velocity=(arg)
209
+ @view__.velocity = arg.is_a?(Vector) ? arg.getInternal__ : arg
210
+ arg
65
211
  end
66
212
 
213
+ # Returns the x-axis velocity of the sprite.
214
+ #
215
+ # @return [Numeric] velocity.x
216
+ #
67
217
  def vx()
68
218
  @view__.velocity.x
69
219
  end
70
220
 
71
- def vx=(value)
72
- @view__.velocity = @view__.velocity.tap {|v| v.x = value}
73
- value
221
+ # Sets the x-axis velocity of the sprite.
222
+ #
223
+ # @param [Numeric] n x-axis velocity
224
+ #
225
+ # @return [Numeric] velocity.x
226
+ #
227
+ def vx=(n)
228
+ @view__.velocity = @view__.velocity.tap {|v| v.x = n}
229
+ n
74
230
  end
75
231
 
232
+ # Returns the y-axis velocity of the sprite.
233
+ #
234
+ # @return [Numeric] velocity.y
235
+ #
76
236
  def vy()
77
237
  @view__.velocity.y
78
238
  end
79
239
 
80
- def vy=(value)
81
- @view__.velocity = @view__.velocity.tap {|v| v.y = value}
82
- value
240
+ # Sets the y-axis velocity of the sprite.
241
+ #
242
+ # @param [Numeric] n y-axis velocity
243
+ #
244
+ # @return [Numeric] velocity.y
245
+ #
246
+ def vy=(n)
247
+ @view__.velocity = @view__.velocity.tap {|v| v.y = n}
248
+ n
249
+ end
250
+
251
+ alias vel velocity
252
+ alias vel= velocity=
253
+
254
+ # Returns the image of the sprite.
255
+ #
256
+ # @return [Image] sprite image
257
+ #
258
+ def image()
259
+ @image__
260
+ end
261
+
262
+ # Sets the sprite image.
263
+ #
264
+ # @param [Image] img sprite image
265
+ #
266
+ # @return [Image] sprite image
267
+ #
268
+ def image=(img)
269
+ @image__ = img
270
+ end
271
+
272
+ # Returns the offset of the sprite image.
273
+ #
274
+ # @return [Vector] offset of the sprite image
275
+ #
276
+ def offset()
277
+ @offset__
278
+ end
279
+
280
+ # Sets the offset of the sprite image.
281
+ #
282
+ # @overload offset=(vec)
283
+ # @param [Vector] vec offset
284
+ #
285
+ # @overload velocity=(ary)
286
+ # @param [Array<Numeric>] ary an array of offsetX and offsetY
287
+ #
288
+ # @return [Vector] offset of the sprite image
289
+ #
290
+ def offset=(arg)
291
+ @offset__ =
292
+ case arg
293
+ when Vector then arg
294
+ when Array then Vector.new(arg[0] || 0, arg[1] || 0)
295
+ when nil then nil
296
+ else raise ArgumentError
297
+ end
298
+ @offset__
299
+ end
300
+
301
+ # Returns the x-axis offset of the sprite image.
302
+ #
303
+ # @return [Numeric] offset.x
304
+ #
305
+ def ox()
306
+ @offset__&.x || 0
307
+ end
308
+
309
+ # Sets the x-axis offset of the sprite image.
310
+ #
311
+ # @param [Numeric] n x-axis offset
312
+ #
313
+ # @return [Numeric] offset.x
314
+ #
315
+ def ox=(n)
316
+ self.offset = [n, oy]
317
+ n
318
+ end
319
+
320
+ # Returns the y-axis offset of the sprite image.
321
+ #
322
+ # @return [Numeric] offset.y
323
+ #
324
+ def oy()
325
+ @offset__&.y || 0
326
+ end
327
+
328
+ # Sets the y-axis offset of the sprite image.
329
+ #
330
+ # @param [Numeric] n y-axis offset
331
+ #
332
+ # @return [Numeric] offset.y
333
+ #
334
+ def oy=(n)
335
+ self.offset = [ox, n]
336
+ end
337
+
338
+ # Returns whether the sprite is movable by the physics engine.
339
+ #
340
+ # @return [Boolean] true if dynamic
341
+ #
342
+ def dynamic?()
343
+ @view__.dynamic?
344
+ end
345
+
346
+ # Sets whether the sprite is movable by the physics engine.
347
+ #
348
+ # @param [Boolean] bool movable or not
349
+ #
350
+ # @return [Boolean] true if dynamic
351
+ #
352
+ def dynamic=(bool)
353
+ @view__.dynamic = bool
354
+ bool
355
+ end
356
+
357
+ # Returns the density of the sprite.
358
+ #
359
+ # @return [Numeric] density
360
+ #
361
+ def density()
362
+ @view__.density
363
+ end
364
+
365
+ # Sets the density of the sprite.
366
+ #
367
+ # @param [Numeric] n density
368
+ #
369
+ # @return [Numeric] density
370
+ #
371
+ def density=(n)
372
+ @view__.density = n
373
+ n
374
+ end
375
+
376
+ # Returns the friction of the sprite.
377
+ #
378
+ # @return [Numeric] friction
379
+ #
380
+ def friction()
381
+ @view__.friction
382
+ end
383
+
384
+ # Sets the friction of the sprite.
385
+ #
386
+ # @param [Numeric] n friction
387
+ #
388
+ # @return [Numeric] friction
389
+ #
390
+ def friction=(n)
391
+ @view__.friction = n
392
+ n
393
+ end
394
+
395
+ # Returns the restitution of the sprite.
396
+ #
397
+ # @return [Numeric] restitution
398
+ #
399
+ def restitution()
400
+ @view__.restitution
401
+ end
402
+
403
+ # Sets the restitution of the sprite.
404
+ #
405
+ # @param [Numeric] n restitution
406
+ #
407
+ # @return [Numeric] restitution
408
+ #
409
+ def restitution=(n)
410
+ @view__.restitution = n
411
+ n
83
412
  end
84
413
 
85
- alias pos position
86
- alias pos= position=
87
- alias vel velocity
88
- alias vel= velocity=
89
414
  alias dens density
90
415
  alias dens= density=
91
416
  alias fric friction
92
- alias fric= friction
417
+ alias fric= friction=
93
418
  alias rest restitution
94
419
  alias rest= restitution=
95
420
 
421
+ # Returns the x-position of the mouse in the sprite coordinates.
422
+ #
423
+ # @return [Numeric] x position
424
+ #
425
+ def mouseX()
426
+ @view__.mouseX
427
+ end
428
+
429
+ # Returns the y-position of the mouse in the sprite coordinates.
430
+ #
431
+ # @return [Numeric] y position
432
+ #
433
+ def mouseY()
434
+ @view__.mouseY
435
+ end
436
+
437
+ # Returns the previous x-position of the mouse in the sprite coordinates.
438
+ #
439
+ # @return [Numeric] x position
440
+ #
441
+ def pmouseX()
442
+ @view__.pmouseX
443
+ end
444
+
445
+ # Returns the previous y-position of the mouse in the sprite coordinates.
446
+ #
447
+ # @return [Numeric] y position
448
+ #
449
+ def pmouseY()
450
+ @view__.pmouseY
451
+ end
452
+
453
+ # Returns the mouse button clicked on the sprite.
454
+ #
455
+ # @return [LEFT, RIGHT, CENTER] mouse button
456
+ #
457
+ def mouseButton()
458
+ @view__.mouseButton
459
+ end
460
+
461
+ # Returns the touch objects touched on the sprite.
462
+ #
463
+ # @return [Array<Touch>] touches
464
+ #
465
+ def touches()
466
+ @view__.touches
467
+ end
468
+
469
+ # Defines update block.
470
+ #
471
+ # @example vx is updated every frame
472
+ # sprite.update do
473
+ # self.vx *= 0.9
474
+ # end
475
+ #
476
+ # @return [nil] nil
477
+ #
478
+ def update(&block)
479
+ @view__.update = block
480
+ end
481
+
482
+ # Defines draw block.
483
+ #
484
+ # @example Draw on your own before and after default drawing
485
+ # sprite.draw do |&defaultDrawSprite|
486
+ # rect 0, 0, 10, 10
487
+ # defaultDrawSprite.call
488
+ # text :hello, 10, 20
489
+ # end
490
+ #
491
+ # @return [nil] nil
492
+ #
493
+ def draw(&block)
494
+ @drawBlock__ = block
495
+ nil
496
+ end
497
+
498
+ # Defines mousePressed block.
499
+ #
500
+ # @example Print mouse states on mouse press
501
+ # sprite.mousePressed do
502
+ # p [sprite.mouseX, sprite.mouseY, sprite.mouseButton]
503
+ # end
504
+ #
505
+ # @return [nil] nil
506
+ #
507
+ def mousePressed(&block)
508
+ @view__.mousePressed = block
509
+ nil
510
+ end
511
+
512
+ # Defines mouseReleased block.
513
+ #
514
+ # @example Print mouse states on mouse release
515
+ # sprite.mouseReleased do
516
+ # p [sprite.mouseX, sprite.mouseY, sprite.mouseButton]
517
+ # end
518
+ #
519
+ # @return [nil] nil
520
+ #
521
+ def mouseReleased(&block)
522
+ @view__.mouseReleased = block
523
+ nil
524
+ end
525
+
526
+ # Defines mouseMoved block.
527
+ #
528
+ # @example Print mouse states on mouse move
529
+ # sprite.mouseMoved do
530
+ # p [sprite.mouseX, sprite.mouseY, sprite.pmouseX, sprite.pmouseY]
531
+ # end
532
+ #
533
+ # @return [nil] nil
534
+ #
535
+ def mouseMoved(&block)
536
+ @view__.mouseMoved = block
537
+ nil
538
+ end
539
+
540
+ # Defines mouseDragged block.
541
+ #
542
+ # @example Print mouse states on mouse drag
543
+ # sprite.mouseDragged do
544
+ # p [sprite.mouseX, sprite.mouseY, sprite.pmouseX, sprite.pmouseY]
545
+ # end
546
+ #
547
+ # @return [nil] nil
548
+ #
549
+ def mouseDragged(&block)
550
+ @view__.mouseDragged = block
551
+ nil
552
+ end
553
+
554
+ # Defines mouseClicked block.
555
+ #
556
+ # @example Print mouse states on mouse click
557
+ # sprite.mouseClicked do
558
+ # p [sprite.mouseX, sprite.mouseY, sprite.mouseButton]
559
+ # end
560
+ #
561
+ # @return [nil] nil
562
+ #
563
+ def mouseClicked(&block)
564
+ @view__.mouseClicked = block
565
+ nil
566
+ end
567
+
568
+ # Defines touchStarted block.
569
+ #
570
+ # @example Print touches on touch start
571
+ # sprite.touchStarted do
572
+ # p sprite.touches
573
+ # end
574
+ #
575
+ # @return [nil] nil
576
+ #
577
+ def touchStarted(&block)
578
+ @view__.touchStarted = block
579
+ nil
580
+ end
581
+
582
+ # Defines touchEnded block.
583
+ #
584
+ # @example Print touches on touch end
585
+ # sprite.touchEnded do
586
+ # p sprite.touches
587
+ # end
588
+ #
589
+ # @return [nil] nil
590
+ #
591
+ def touchEnded(&block)
592
+ @view__.touchEnded = block
593
+ nil
594
+ end
595
+
596
+ # Defines touchMoved block.
597
+ #
598
+ # @example Print touches on touch move
599
+ # sprite.touchMoved do
600
+ # p sprite.touches
601
+ # end
602
+ #
603
+ # @return [nil] nil
604
+ #
605
+ def touchMoved(&block)
606
+ @view__.touchMoved = block
607
+ nil
608
+ end
609
+
610
+ # Defines contact block.
611
+ #
612
+ # @example Score increases when the player sprite touches a coin
613
+ # playerSprite.contact do |o|
614
+ # score += 1 if o.coin?
615
+ # end
616
+ #
617
+ # @return [nil] nil
618
+ #
619
+ def contact(&block)
620
+ @view__.contact = block
621
+ end
622
+
623
+ # Defines contact? block.
624
+ #
625
+ # @example Only collide with an enemy
626
+ # playerSprite.contact? do |o|
627
+ # o.enemy?
628
+ # end
629
+ #
630
+ # @return [nil] nil
631
+ #
632
+ def contact?(&block)
633
+ @view__.will_contact = block
634
+ end
635
+
96
636
  # @private
97
637
  def getInternal__()
98
638
  @view__
99
639
  end
100
640
 
101
- class View < Reflex::View
102
- attr_accessor :update, :contact, :will_contact
103
- attr_reader :sprite
641
+ end# Sprite
104
642
 
105
- def initialize(sprite, *a, **k, &b)
106
- @sprite = sprite
107
- super(*a, **k, &b)
108
- end
109
643
 
110
- def on_update(e)
111
- @update.call if @update
112
- end
644
+ # @private
645
+ class SpriteView < Reflex::View
646
+
647
+ attr_accessor :update,
648
+ :mousePressed, :mouseReleased, :mouseMoved, :mouseDragged, :mouseClicked,
649
+ :touchStarted, :touchEnded, :touchMoved,
650
+ :contact, :will_contact
651
+
652
+ attr_reader :sprite, :touches
653
+
654
+ def initialize(sprite, *a, **k, &b)
655
+ @sprite = sprite
656
+ super(*a, **k, &b)
657
+
658
+ @pointerPos =
659
+ @pointerPrevPos = Rays::Point.new 0
660
+ @pointersPressed = []
661
+ @pointersReleased = []
662
+ @touches = []
663
+ end
664
+
665
+ def mouseX()
666
+ @pointerPos.x
667
+ end
668
+
669
+ def mouseY()
670
+ @pointerPos.y
671
+ end
672
+
673
+ def pmouseX()
674
+ @pointerPrevPos.x
675
+ end
676
+
677
+ def pmouseY()
678
+ @pointerPrevPos.y
679
+ end
680
+
681
+ def mouseButton()
682
+ ((@pointersPressed + @pointersReleased) & [LEFT, RIGHT, CENTER]).last
683
+ end
684
+
685
+ def on_update(e)
686
+ @update&.call
687
+ end
688
+
689
+ def on_pointer_down(e)
690
+ updatePointerStates e, true
691
+ @pointerDownStartPos = @pointerPos.dup
692
+ (@touchStarted || @mousePressed)&.call
693
+ end
113
694
 
114
- def on_contact(e)
115
- v = e.view
116
- @contact.call v.sprite, e.action if @contact && v.is_a?(View)
695
+ def on_pointer_up(e)
696
+ updatePointerStates e, false
697
+ (@touchEnded || @mouseReleased)&.call
698
+ if startPos = @pointerDownStartPos
699
+ @mouseClicked&.call if (@pointerPos - startPos).length < 3
700
+ @pointerDownStartPos = nil
117
701
  end
702
+ @pointersReleased.clear
703
+ end
704
+
705
+ def on_pointer_move(e)
706
+ updatePointerStates e
707
+ (@touchMoved || (e.drag? ? @mouseDragged : @mouseMoved))&.call
708
+ end
118
709
 
119
- def will_contact?(v)
120
- return true if !@will_contact || !v.is_a?(View)
121
- @will_contact.call v.sprite
710
+ def on_pointer_cancel(e)
711
+ on_pointer_up e
712
+ end
713
+
714
+ def on_contact(e)
715
+ v = e.view
716
+ @contact.call v.sprite, e.action if @contact && v.respond_to?(:sprite)
717
+ end
718
+
719
+ def will_contact?(v)
720
+ return true unless @will_contact && v.respond_to?(:sprite)
721
+ @will_contact.call v.sprite
722
+ end
723
+
724
+ private
725
+
726
+ MOUSE_BUTTON_MAP = {
727
+ mouse_left: Processing::GraphicsContext::LEFT,
728
+ mouse_right: Processing::GraphicsContext::RIGHT,
729
+ mouse_middle: Processing::GraphicsContext::CENTER
730
+ }
731
+
732
+ def updatePointerStates(event, pressed = nil)
733
+ @pointerPrevPos = @pointerPos
734
+ @pointerPos = event.pos.dup
735
+ @touches = event.pointers.map {|p| Touch.new(p.id, *p.pos.to_a)}
736
+ if pressed != nil
737
+ event.types
738
+ .tap {|types| types.delete :mouse}
739
+ .map {|type| MOUSE_BUTTON_MAP[type] || type}
740
+ .each do |type|
741
+ (pressed ? @pointersPressed : @pointersReleased).push type
742
+ @pointersPressed.delete type unless pressed
743
+ end
122
744
  end
123
745
  end
124
746
 
125
- end# Sprite
747
+ end# SpriteView
126
748
 
127
749
 
128
750
  end# RubySketch