ruby-miyako-mswin32 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/README +275 -20
  2. data/install_miyako.rb +5 -3
  3. data/lib/Miyako/API/audio.rb +11 -6
  4. data/lib/Miyako/API/basic_data.rb +0 -985
  5. data/lib/Miyako/API/bitmap.rb +19 -22
  6. data/lib/Miyako/API/choices.rb +203 -69
  7. data/lib/Miyako/API/collision.rb +451 -9
  8. data/lib/Miyako/API/color.rb +177 -0
  9. data/lib/Miyako/API/diagram.rb +18 -20
  10. data/lib/Miyako/API/fixedmap.rb +207 -73
  11. data/lib/Miyako/API/font.rb +111 -18
  12. data/lib/Miyako/API/i_yuki.rb +1201 -0
  13. data/lib/Miyako/API/input.rb +65 -0
  14. data/lib/Miyako/API/layout.rb +41 -29
  15. data/lib/Miyako/API/map.rb +202 -157
  16. data/lib/Miyako/API/map_event.rb +86 -19
  17. data/lib/Miyako/API/map_struct.rb +268 -0
  18. data/lib/Miyako/API/modules.rb +136 -37
  19. data/lib/Miyako/API/movie.rb +8 -8
  20. data/lib/Miyako/API/parts.rb +63 -20
  21. data/lib/Miyako/API/plane.rb +4 -4
  22. data/lib/Miyako/API/screen.rb +16 -8
  23. data/lib/Miyako/API/sprite.rb +290 -23
  24. data/lib/Miyako/API/sprite_animation.rb +23 -11
  25. data/lib/Miyako/API/sprite_list.rb +406 -183
  26. data/lib/Miyako/API/story.rb +4 -65
  27. data/lib/Miyako/API/struct_point.rb +157 -0
  28. data/lib/Miyako/API/struct_rect.rb +233 -0
  29. data/lib/Miyako/API/struct_segment.rb +641 -0
  30. data/lib/Miyako/API/struct_size.rb +158 -0
  31. data/lib/Miyako/API/struct_square.rb +253 -0
  32. data/lib/Miyako/API/textbox.rb +49 -35
  33. data/lib/Miyako/API/viewport.rb +5 -5
  34. data/lib/Miyako/API/wait_counter.rb +350 -0
  35. data/lib/Miyako/API/yuki.rb +95 -60
  36. data/lib/Miyako/EXT/raster_scroll.rb +30 -8
  37. data/lib/Miyako/EXT/slides.rb +6 -6
  38. data/lib/Miyako/miyako.rb +25 -11
  39. data/lib/Miyako/miyako_no_katana.so +0 -0
  40. data/lib/miyako.rb +28 -0
  41. data/lib/miyako_require_only.rb +35 -0
  42. data/sample/Diagram_sample/diagram_sample_yuki2.rb +30 -30
  43. data/sample/Room3/blue.rb +19 -19
  44. data/sample/Room3/green.rb +9 -9
  45. data/sample/Room3/main.rb +12 -12
  46. data/sample/Room3/red.rb +12 -12
  47. data/sample/Room3/title.rb +15 -10
  48. data/sample/collision_test2.rb +2 -1
  49. data/sample/fixed_map_test/fixed_map_sample.rb +7 -6
  50. data/sample/map_test/main_scene.rb +12 -10
  51. data/sample/map_test/map_manager.rb +14 -13
  52. data/sample/rasterscroll.rb +5 -5
  53. data/sample/takahashi.rb +3 -3
  54. data/sample/textbox_sample.rb +8 -5
  55. data/sample/transform.rb +2 -1
  56. data/uninstall_miyako.rb +4 -1
  57. metadata +13 -4
  58. data/lib/Miyako/EXT/miyako_cairo.rb +0 -62
  59. data/sample/cairo_sample.rb +0 -25
@@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
20
  ++
21
21
  =end
22
22
 
23
+ require 'delegate'
24
+
23
25
  module Miyako
24
26
  #==矩形当たり判定領域(コリジョン)クラス
25
27
  # コリジョンの範囲は、元データ(スプライト等)の左上端を[0.0,0.0]として考案する
@@ -27,10 +29,15 @@ module Miyako
27
29
  class Collision
28
30
  extend Forwardable
29
31
 
32
+ # 関連づけられたインスタンス
33
+ attr_reader :body
30
34
  # コリジョンの範囲([x,y,w,h])
31
35
  attr_reader :rect
32
- # 移動時イベントブロック配列
33
-
36
+ # コリジョンの中心点([x,y])
37
+ attr_reader :center
38
+ # コリジョンの半径
39
+ attr_reader :radius
40
+
34
41
  #===コリジョンのインスタンスを作成する
35
42
  # 幅・高さが0以下のときは例外が発生する
36
43
  # 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
@@ -47,6 +54,7 @@ module Miyako
47
54
  h = @rect[2].to_f
48
55
  @center = Point.new(@rect[0].to_f + w / 2.0, @rect[1].to_f + h / 2.0)
49
56
  @radius = circum ? Math.sqrt(w ** 2 + h ** 2) / 2.0 : [w, h].min / 2.0
57
+ @body = nil
50
58
  end
51
59
 
52
60
  def initialize_copy(obj) #:nodoc:
@@ -54,6 +62,26 @@ module Miyako
54
62
  @center = @center.dup
55
63
  end
56
64
 
65
+ #===当たり判定とインスタンスを関連づける
66
+ #当たり判定と、それをもとにしたインスタンスとの関連がわかりにくいときに使用する
67
+ #引数にcollision=メソッドの有無を調査して、持っているときは、collision=メソッドを
68
+ #自分自身を引数にして呼び出す(collision=メソッドを持っているのは現状でSpriteクラスのみ)
69
+ #_obj_:: 関連づける元のインスタンス
70
+ #返却値:: 自分自身を帰す
71
+ def bind(obj)
72
+ @body = obj
73
+ @body.collision = self if @body.class.method_defined?(:collision=)
74
+ return self
75
+ end
76
+
77
+ #===CollisionExクラスのインスタンスを生成する
78
+ #自分自身に位置情報を渡してCollisionExクラスのインスタンスを生成する
79
+ #_pos_:: CollisionEx生成時に渡す位置。省略時は[0,0]
80
+ #返却値:: CollisionEx構造体
81
+ def to_ex(pos=[0,0])
82
+ CollisionEx.new(@rect, pos)
83
+ end
84
+
57
85
  #===当たり判定を行う(領域が重なっている)
58
86
  #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
59
87
  #_c2_:: 判定対象のコリジョンインスタンス
@@ -224,12 +252,15 @@ module Miyako
224
252
  class CircleCollision
225
253
  extend Forwardable
226
254
 
255
+ # 関連づけられたインスタンス
256
+ attr_reader :body
227
257
  # コリジョンの中心点([x,y])
228
258
  attr_reader :center
229
259
  # コリジョンの半径
230
260
  attr_reader :radius
231
- # 移動時イベントブロック配列
232
-
261
+ # コリジョンの範囲([x,y,w,h])
262
+ attr_reader :rect
263
+
233
264
  #===コリジョンのインスタンスを作成する
234
265
  # コリジョンの半径が0もしくはマイナスのとき例外が発生する
235
266
  # 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
@@ -249,6 +280,7 @@ module Miyako
249
280
  else
250
281
  @rect = Rect.new(@center[0]-@radius, @center[1]-@radius, @radius*2.0, @radius*2.0)
251
282
  end
283
+ @body = nil
252
284
  end
253
285
 
254
286
  def initialize_copy(obj) #:nodoc:
@@ -256,6 +288,26 @@ module Miyako
256
288
  @center = @center.dup
257
289
  end
258
290
 
291
+ #===当たり判定とインスタンスを関連づける
292
+ #当たり判定と、それをもとにしたインスタンスとの関連がわかりにくいときに使用する
293
+ #引数にcollision=メソッドの有無を調査して、持っているときは、collision=メソッドを
294
+ #自分自身を引数にして呼び出す(collision=メソッドを持っているのは現状でSpriteクラスのみ)
295
+ #_obj_:: 関連づける元のインスタンス
296
+ #返却値:: 自分自身を帰す
297
+ def bind(obj)
298
+ @body = obj
299
+ @body.collision = self if @body.class.method_defined?(:collision=)
300
+ return self
301
+ end
302
+
303
+ #===CircleCollisionExクラスのインスタンスを生成する
304
+ #自分自身に位置情報を渡してCircleCollisionExクラスのインスタンスを生成する
305
+ #_pos_:: CircleCollisionEx生成時に渡す位置。省略時は[0,0]
306
+ #返却値:: CircleCollisionEx構造体
307
+ def to_ex(pos=[0,0])
308
+ CircleCollisionEx.new(@center, @radius, pos)
309
+ end
310
+
259
311
  #===当たり判定間の距離を算出する
260
312
  #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
261
313
  #_c2_:: 判定対象のコリジョンインスタンス
@@ -415,6 +467,245 @@ module Miyako
415
467
  end
416
468
  end
417
469
 
470
+ #==位置情報付き矩形当たり判定領域(コリジョン)クラス
471
+ #コリジョンの範囲は、元データ(スプライト等)の左上端を[0.0,0.0]として考案する
472
+ #コリジョンで使用する値は、実数での設定が可能
473
+ class CollisionEx < Collision
474
+ #コリジョンの位置(Point構造体)
475
+ attr_reader :pos
476
+
477
+ #===コリジョンのインスタンスを作成する
478
+ # 幅・高さが0以下のときは例外が発生する
479
+ # 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
480
+ # そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。
481
+ # circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。
482
+ #_rect_:: コリジョンを設定する範囲
483
+ #_pos_:: コリジョンの位置
484
+ #_circum_:: 矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue
485
+ #返却値:: 作成されたコリジョン
486
+ def initialize(rect, pos, circum = true)
487
+ super(rect, circum)
488
+ @pos = Point.new(*pos.to_a)
489
+ end
490
+
491
+ #===Collisionクラスのインスタンスを生成する
492
+ #自分自身から位置情報を除いてCollisionクラスのインスタンスを生成する
493
+ #返却値:: Collision構造体
494
+ def to_col
495
+ Collision.new(@rect)
496
+ end
497
+
498
+ #===当たり判定を行う(領域が重なっている)
499
+ #_c2_:: 判定対象のコリジョンインスタンス
500
+ #返却値:: 1ピクセルでも重なっていれば true を返す
501
+ def collision?(c2)
502
+ return Collision.collision?(self, self.pos, c2, c2.pos)
503
+ end
504
+
505
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
506
+ #_c2_:: 判定対象のコリジョンインスタンス
507
+ #返却値:: 領域が隣り合っていれば true を返す
508
+ def meet?(c2)
509
+ return Collision.meet?(self, self.pos, c2, c2.pos)
510
+ end
511
+
512
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
513
+ #_c2_:: 判定対象のコリジョンインスタンス
514
+ #返却値:: 領域が覆われていれば true を返す
515
+ def cover?(c2)
516
+ return Collision.cover?(self, self.pos, c2, c2.pos)
517
+ end
518
+
519
+ #===当たり判定を行う(レシーバがc2を覆っている)
520
+ #_c2_:: 判定対象のコリジョンインスタンス
521
+ #返却値:: 領域が覆われていれば true を返す
522
+ def covers?(pos1, c2, pos2)
523
+ return Collision.covers?(self, pos1, c2, pos2)
524
+ end
525
+
526
+ #===当たり判定を行う(レシーバがc2に覆われている)
527
+ #_c2_:: 判定対象のコリジョンインスタンス
528
+ #返却値:: 領域が覆われていれば true を返す
529
+ def covered?(pos1, c2, pos2)
530
+ return Collision.covered?(self, pos1, c2, pos2)
531
+ end
532
+
533
+ #===当たり判定を行う(領域が重なっている)
534
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
535
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
536
+ #返却値:: 1ピクセルでも重なっていれば true を返す
537
+ def CollisionEx.collision?(c1, c2)
538
+ return Collision.collision?(c1, c1.pos, c2, c2.pos)
539
+ end
540
+
541
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
542
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
543
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
544
+ #返却値:: 領域が隣り合っていれば true を返す
545
+ def CollisionEx.meet?(c1, pos1, c2, pos2)
546
+ return Collision.meet?(c1, c1.pos, c2, c2.pos)
547
+ end
548
+
549
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
550
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
551
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
552
+ #返却値:: 領域が覆われていれば true を返す
553
+ def CollisionEx.cover?(c1, pos1, c2, pos2)
554
+ return Collision.cover?(c1, c1.pos, c2, c2.pos)
555
+ end
556
+
557
+ #===当たり判定を行う(c1がc2を覆っている)
558
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
559
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
560
+ #返却値:: 領域が覆われていれば true を返す
561
+ def CollisionEx.covers?(c1, pos1, c2, pos2)
562
+ return Collision.covers?(c1, c1.pos, c2, c2.pos)
563
+ end
564
+
565
+ #===当たり判定を行う(c1がc2に覆われている)
566
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
567
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
568
+ #返却値:: 領域が覆われていれば true を返す
569
+ def CollisionEx.covered?(c1, pos1, c2, pos2)
570
+ return Collision.covered?(c1, c1.pos, c2, c2.pos)
571
+ end
572
+
573
+ #== インスタンスの内容を解放する
574
+ #返却値:: なし
575
+ def dispose
576
+ super
577
+ @pos = nil
578
+ end
579
+ end
580
+
581
+ #==位置情報付き円形当たり判定領域(サークルコリジョン)クラス
582
+ #円形の当たり判定を実装する。
583
+ #コリジョンは中心位置と半径で構成され、円形当たり判定同士で衝突判定を行う
584
+ #コリジョンで使用する値は、実数での設定が可能
585
+ class CircleCollisionEx < CircleCollision
586
+ #===コリジョンのインスタンスを作成する
587
+ #コリジョンの半径が0もしくはマイナスのとき例外が発生する
588
+ #内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
589
+ #そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。
590
+ #circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。
591
+ #_center_:: コリジョンを設定する範囲
592
+ #_radius_:: コリジョンの半径
593
+ #_pos_:: コリジョンの位置
594
+ #_circum_:: 矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue
595
+ #返却値:: 作成されたコリジョン
596
+ def initialize(center, radius, pos, circum = true)
597
+ super(center, radius, circum)
598
+ @pos = Point.new(*pos.to_a)
599
+ end
600
+
601
+ #===CicleCollisionクラスのインスタンスを生成する
602
+ #自分自身から位置情報を除いてCircleCollisionクラスのインスタンスを生成する
603
+ #返却値:: CircleCollision構造体
604
+ def to_col
605
+ CircleCollision.new(@center, @radius)
606
+ end
607
+
608
+ #===当たり判定間の距離を算出する
609
+ #_c2_:: 判定対象のコリジョンインスタンス
610
+ #返却値:: 1ピクセルでも重なっていれば true を返す
611
+ def interval(c2)
612
+ return CircleCollision.interval(self, self.pos, c2, c2.pos)
613
+ end
614
+
615
+ #===当たり判定を行う(領域が重なっている)
616
+ #_c2_:: 判定対象のコリジョンインスタンス
617
+ #返却値:: 1ピクセルでも重なっていれば true を返す
618
+ def collision?(c2)
619
+ return CircleCollision.collision?(self, self.pos, c2, c2.pos)
620
+ end
621
+
622
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
623
+ #_c2_:: 判定対象のコリジョンインスタンス
624
+ #返却値:: 領域が隣り合っていれば true を返す
625
+ def meet?(c2)
626
+ return CircleCollision.meet?(self, self.pos, c2, c2.pos)
627
+ end
628
+
629
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
630
+ #_c2_:: 判定対象のコリジョンインスタンス
631
+ #返却値:: 領域が覆われていれば true を返す
632
+ def cover?(c2)
633
+ return CircleCollision.cover?(self, self.pos, c2, c2.pos)
634
+ end
635
+
636
+ #===当たり判定を行う(レシーバがc2を覆っている)
637
+ #_c2_:: 判定対象のコリジョンインスタンス
638
+ #返却値:: 領域が覆われていれば true を返す
639
+ def covers?(c2)
640
+ return CircleCollision.covers?(self, self.pos, c2, c2.pos)
641
+ end
642
+
643
+ #===当たり判定を行う(レシーバがc2に覆われている)
644
+ #_c2_:: 判定対象のコリジョンインスタンス
645
+ #返却値:: 領域が覆われていれば true を返す
646
+ def covered?(c2)
647
+ return CircleCollision.covered?(self, self.pos, c2, c2.pos)
648
+ end
649
+
650
+ #===当たり判定間の距離を算出する
651
+ # 2つの当たり判定がどの程度離れているかを算出する。
652
+ # 返ってくる値は、衝突していなければ正の実数、衝突していれば負の実数で返ってくる
653
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
654
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
655
+ #返却値:: 当たり判定間の距離
656
+ def CircleCollisionEx.interval(c1, c2)
657
+ return CircleCollision.interval(c1, c1.pos, c2, c2.pos)
658
+ end
659
+
660
+ #===当たり判定を行う(領域が重なっている)
661
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
662
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
663
+ #返却値:: 1ピクセルでも重なっていれば true を返す
664
+ def CircleCollisionEx.collision?(c1, c2)
665
+ return CircleCollision.collision?(c1, c1.pos, c2, c2.pos)
666
+ end
667
+
668
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
669
+ # 但し、実際の矩形範囲が偶数の時は性格に判定できない場合があるため注意
670
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
671
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
672
+ #返却値:: 領域が隣り合っていれば true を返す
673
+ def CircleCollisionEx.meet?(c1, c2)
674
+ return CircleCollision.meet?(c1, c1.pos, c2, c2.pos)
675
+ end
676
+
677
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
678
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
679
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
680
+ #返却値:: 領域が覆われていれば true を返す
681
+ def CircleCollisionEx.cover?(c1, c2)
682
+ return CircleCollision.cover?(c1, c1.pos, c2, c2.pos)
683
+ end
684
+
685
+ #===当たり判定を行う(c1がc2を覆っている)
686
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
687
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
688
+ #返却値:: 領域が覆われていれば true を返す
689
+ def CircleCollisionEx.covers?(c1, c2)
690
+ return CircleCollision.covers?(c1, c1.pos, c2, c2.pos)
691
+ end
692
+
693
+ #===当たり判定を行う(c1がc2に覆われている)
694
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
695
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
696
+ #返却値:: 領域が覆われていれば true を返す
697
+ def CircleCollisionEx.covered?(c1, c2)
698
+ return CircleCollision.covered?(c1, c1.pos, c2, c2.pos)
699
+ end
700
+
701
+ #== インスタンスの内容を解放する
702
+ #返却値:: なし
703
+ def dispose
704
+ super
705
+ @pos = nil
706
+ end
707
+ end
708
+
418
709
  #==コリジョン管理クラス
419
710
  # 複数のコリジョンと元オブジェクトを配列の様に一括管理できる
420
711
  # 当たり判定を一括処理することで高速化を図る
@@ -483,7 +774,7 @@ module Miyako
483
774
  def [](idx)
484
775
  return @collisions[idx]
485
776
  end
486
-
777
+
487
778
  #===コリジョン・本体の削除
488
779
  #_idx_:: 配列のインデックス番号
489
780
  #返却値:: 削除したコリジョンと本体との対
@@ -491,7 +782,7 @@ module Miyako
491
782
  def delete(idx)
492
783
  return @collisions.delete_at(idx)
493
784
  end
494
-
785
+
495
786
  #===インデックス形式でのコリジョン・本体の取得
496
787
  #_idx_:: 配列のインデックス番号
497
788
  #返却値:: インデックスに対応したコリジョンと本体との対
@@ -518,7 +809,7 @@ module Miyako
518
809
  yield @collisions[idx][0], @collisions[idx][1]
519
810
  return self
520
811
  end
521
-
812
+
522
813
  #===当たり判定を行う(配列要素がcと重なっている)
523
814
  # 重なったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
524
815
  # 重なったコリジョンが無い場合はnilを返す
@@ -590,7 +881,7 @@ module Miyako
590
881
  end
591
882
 
592
883
  #===当たり判定を行う(配列要素かcがもう一方を覆っている))
593
- # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
884
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
594
885
  # 覆われたコリジョンが無い場合はnilを返す
595
886
  #_c_:: 判定対象のコリジョンインスタンス
596
887
  #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
@@ -620,7 +911,7 @@ module Miyako
620
911
  end
621
912
 
622
913
  #===インデックス形式でのコリジョン・本体の取得
623
- # 判定に引っかかったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
914
+ # 判定に引っかかったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
624
915
  # 当たり判定に引っかかったコリジョンが無い場合はnilを返す
625
916
  #_idx_:: 配列のインデックス番号
626
917
  #返却値:: インデックスに対応したコリジョンと本体との対
@@ -635,4 +926,155 @@ module Miyako
635
926
  @collisions = nil
636
927
  end
637
928
  end
929
+
930
+
931
+ #==コリジョン管理クラス
932
+ # 複数のコリジョンと元オブジェクトを配列の様に一括管理できる
933
+ # 当たり判定を一括処理することで高速化を図る
934
+ class CollisionsEx < Delegator
935
+
936
+ attr_accessor :collision
937
+
938
+ #===コリジョンのインスタンスを作成する
939
+ #利用できる要素はCollisionEx,CircleCollisionEx(か、その派生)のみ
940
+ #_collisions_:: コリジョンの配列。デフォルトは []
941
+ #返却値:: 作成されたインスタンス
942
+ def initialize(collisions=[])
943
+ @collisions = Array.new(collisions)
944
+ @collision = nil
945
+ end
946
+
947
+ def __getobj__ #:nodoc:
948
+ @collisions
949
+ end
950
+
951
+ def __setobj__(obj) #:nodoc:
952
+ end
953
+
954
+ def initialize_copy(obj) #:nodoc:
955
+ @collisions = @collisions.dup
956
+ end
957
+
958
+ def deep_dup_collision #:nodocs:
959
+ @collisions = @collisions.deep_dup
960
+ return self
961
+ end
962
+
963
+ #===要素も複製した複製インスタンスを返す
964
+ #返却値:: 複製したインスタンスを返す
965
+ def deep_dup
966
+ ret = self.dup
967
+ ret.deep_dup_collision
968
+ end
969
+
970
+ #===現在所持している配列から最大範囲のコリジョンを作成する
971
+ #ただし、配列が空の時はnilを返す
972
+ #返却値:: 生成したコリジョン(CollisionExクラスのインスタンス)
973
+ def from_children
974
+ return nil if @collisions.empty?
975
+ array = []
976
+ @collisions.each{|cc|
977
+ if cc.class.method_defined?(:from_children)
978
+ col = cc.from_children
979
+ next unless col
980
+ array << col.rect.to_square.to_a
981
+ else
982
+ rect = cc.rect.dup
983
+ rect[0] += cc.pos[0]
984
+ rect[1] += cc.pos[1]
985
+ array << rect.to_square.to_a
986
+ end
987
+ }
988
+ el = array.shift
989
+ if array.length >= 1
990
+ array = el.zip(*array)
991
+ el = [array[0].min, array[1].min, array[2].max, array[3].max]
992
+ end
993
+ CollisionEx.new(Rect.new(el[0], el[1], el[2]-el[0]+1, el[3]-el[1]+1), Point.new(0,0))
994
+ end
995
+
996
+ #===コリジョンと位置情報を追加する
997
+ #_collision_:: コリジョン
998
+ #返却値:: 自分自身を返す
999
+ def add(collision)
1000
+ @collisions << collision
1001
+ return self
1002
+ end
1003
+
1004
+ #===インスタンスに、コリジョンと位置情報の集合を追加する
1005
+ #_collisions_:: コリジョンの配列
1006
+ #返却値:: 自分自身を返す
1007
+ def append(collisions)
1008
+ @collisions.concat(collisions)
1009
+ return self
1010
+ end
1011
+
1012
+ #===当たり判定を行う(配列要素とcが重なっている)
1013
+ # 重なったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
1014
+ # 重なったコリジョンが無い場合はnilを返す
1015
+ #_c_:: 判定対象のコリジョンインスタンス
1016
+ #返却値:: コリジョンの配列。
1017
+ def collision?(c)
1018
+ return nil if @collision and !@collision.collision?(c)
1019
+ collision_inner(c, []){|cc,c| cc.collision?(c) }
1020
+ end
1021
+
1022
+ def collision_inner(c, array) #:nodoc:
1023
+ @collisions.each{|cc|
1024
+ ret = yield cc, c
1025
+ array << (ret == true ? cc : ret) if ret
1026
+ }
1027
+ array.length == 0 ? nil : array
1028
+ end
1029
+
1030
+ private :collision_inner
1031
+
1032
+ #===当たり判定を行う(配列要素がcとピクセル単位で隣り合っている)
1033
+ # 隣り合ったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
1034
+ # 隣り合ったコリジョンが無い場合はnilを返す
1035
+ #_c_:: 判定対象のコリジョンインスタンス
1036
+ #返却値:: コリジョンの配列。
1037
+ def meet?(c)
1038
+ return nil if @collision and !@collision.collision?(c)
1039
+ collision_inner(c, []){|cc,c| cc.meet?(c) }
1040
+ end
1041
+
1042
+ #===当たり判定を行う(配列要素かcがもう一方を覆っている))
1043
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
1044
+ # 覆われたコリジョンが無い場合はnilを返す
1045
+ #_c_:: 判定対象のコリジョンインスタンス
1046
+ #返却値:: コリジョンの配列。
1047
+ def cover?(c)
1048
+ return nil if @collision and !@collision.collision?(c)
1049
+ collision_inner(c, []){|cc,c| cc.cover?(c) }
1050
+ end
1051
+
1052
+ #===当たり判定を行う(配列要素が領域がcを覆っている))
1053
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
1054
+ # 覆われたコリジョンが無い場合はnilを返す
1055
+ #_c_:: 判定対象のコリジョンインスタンス
1056
+ #返却値:: コリジョンの配列。
1057
+ def covers?(c)
1058
+ return nil if @collision and !@collision.collision?(c)
1059
+ collision_inner(c, []){|cc,c| cc.covers?(c) }
1060
+ end
1061
+
1062
+ #===当たり判定を行う(配列要素がcに覆われている))
1063
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
1064
+ # 覆われたコリジョンが無い場合はnilを返す
1065
+ #_c_:: 判定対象のコリジョンインスタンス
1066
+ #返却値:: コリジョンの配列。
1067
+ def covered?(c)
1068
+ return nil if @collision and !@collision.collision?(c)
1069
+ collision_inner(c, []){|cc,c| cc.covers?(c) }
1070
+ end
1071
+
1072
+ #===オブジェクトを解放する
1073
+ #返却値:: なし
1074
+ def dispose
1075
+ @collisions.clear
1076
+ @collisions = nil
1077
+ @collision = nil
1078
+ end
1079
+ end
638
1080
  end