ruby-miyako 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. data/README +1115 -0
  2. data/Rakefile +7 -0
  3. data/defines.h +144 -0
  4. data/extconf.rb +44 -0
  5. data/extern.h +29 -0
  6. data/img/cursor.png +0 -0
  7. data/img/cursors.png +0 -0
  8. data/img/dice.png +0 -0
  9. data/img/wait_cursor.png +0 -0
  10. data/img/win_base.png +0 -0
  11. data/img/window.png +0 -0
  12. data/install_miyako.rb +87 -0
  13. data/lib/Miyako/API/audio.rb +584 -0
  14. data/lib/Miyako/API/basic_data.rb +1026 -0
  15. data/lib/Miyako/API/bitmap.rb +534 -0
  16. data/lib/Miyako/API/choices.rb +481 -0
  17. data/lib/Miyako/API/collision.rb +638 -0
  18. data/lib/Miyako/API/diagram.rb +586 -0
  19. data/lib/Miyako/API/drawing.rb +151 -0
  20. data/lib/Miyako/API/exceptions.rb +105 -0
  21. data/lib/Miyako/API/fixedmap.rb +462 -0
  22. data/lib/Miyako/API/font.rb +430 -0
  23. data/lib/Miyako/API/input.rb +456 -0
  24. data/lib/Miyako/API/layout.rb +644 -0
  25. data/lib/Miyako/API/map.rb +583 -0
  26. data/lib/Miyako/API/map_event.rb +222 -0
  27. data/lib/Miyako/API/modules.rb +357 -0
  28. data/lib/Miyako/API/movie.rb +166 -0
  29. data/lib/Miyako/API/parts.rb +188 -0
  30. data/lib/Miyako/API/plane.rb +205 -0
  31. data/lib/Miyako/API/screen.rb +341 -0
  32. data/lib/Miyako/API/shape.rb +443 -0
  33. data/lib/Miyako/API/sprite.rb +773 -0
  34. data/lib/Miyako/API/sprite_animation.rb +494 -0
  35. data/lib/Miyako/API/sprite_list.rb +1135 -0
  36. data/lib/Miyako/API/spriteunit.rb +168 -0
  37. data/lib/Miyako/API/story.rb +350 -0
  38. data/lib/Miyako/API/textbox.rb +773 -0
  39. data/lib/Miyako/API/utility.rb +419 -0
  40. data/lib/Miyako/API/viewport.rb +190 -0
  41. data/lib/Miyako/API/yuki.rb +1180 -0
  42. data/lib/Miyako/EXT/miyako_cairo.rb +62 -0
  43. data/lib/Miyako/EXT/raster_scroll.rb +138 -0
  44. data/lib/Miyako/EXT/slides.rb +157 -0
  45. data/lib/Miyako/miyako.rb +201 -0
  46. data/lib/Miyako/miyako_require_only.rb +35 -0
  47. data/logo/EGSR_logo.png +0 -0
  48. data/logo/EGSR_logo_bg.png +0 -0
  49. data/logo/EGSR_logo_fg.png +0 -0
  50. data/logo/EGSR_title_banner.png +0 -0
  51. data/logo/EGSR_title_logo.png +0 -0
  52. data/logo/miyako.png +0 -0
  53. data/logo/miyako_banner.png +0 -0
  54. data/logo/space.png +0 -0
  55. data/miyako_basicdata.c +484 -0
  56. data/miyako_bitmap.c +1225 -0
  57. data/miyako_collision.c +403 -0
  58. data/miyako_drawing.c +187 -0
  59. data/miyako_font.c +334 -0
  60. data/miyako_hsv.c +830 -0
  61. data/miyako_input_audio.c +254 -0
  62. data/miyako_layout.c +191 -0
  63. data/miyako_no_katana.c +1086 -0
  64. data/miyako_sprite2.c +431 -0
  65. data/miyako_transform.c +438 -0
  66. data/miyako_utility.c +288 -0
  67. data/sample/Animation1/m1ku.rb +68 -0
  68. data/sample/Animation1/m1ku_arm_0.png +0 -0
  69. data/sample/Animation1/m1ku_arm_1.png +0 -0
  70. data/sample/Animation1/m1ku_arm_2.png +0 -0
  71. data/sample/Animation1/m1ku_arm_3.png +0 -0
  72. data/sample/Animation1/m1ku_back.jpg +0 -0
  73. data/sample/Animation1/m1ku_body.png +0 -0
  74. data/sample/Animation1/m1ku_eye_0.png +0 -0
  75. data/sample/Animation1/m1ku_eye_1.png +0 -0
  76. data/sample/Animation1/m1ku_eye_2.png +0 -0
  77. data/sample/Animation1/m1ku_eye_3.png +0 -0
  78. data/sample/Animation1/m1ku_hair_front.png +0 -0
  79. data/sample/Animation1/m1ku_hair_rear.png +0 -0
  80. data/sample/Animation1/readme.txt +72 -0
  81. data/sample/Animation2/lex.rb +96 -0
  82. data/sample/Animation2/lex_back.png +0 -0
  83. data/sample/Animation2/lex_body.png +0 -0
  84. data/sample/Animation2/lex_roadroller.png +0 -0
  85. data/sample/Animation2/lex_wheel_0.png +0 -0
  86. data/sample/Animation2/lex_wheel_1.png +0 -0
  87. data/sample/Animation2/lex_wheel_2.png +0 -0
  88. data/sample/Animation2/readme.txt +72 -0
  89. data/sample/Animation2/song_title.png +0 -0
  90. data/sample/Diagram_sample/back.png +0 -0
  91. data/sample/Diagram_sample/chr01.png +0 -0
  92. data/sample/Diagram_sample/chr02.png +0 -0
  93. data/sample/Diagram_sample/cursor.png +0 -0
  94. data/sample/Diagram_sample/diagram_sample_yuki2.rb +329 -0
  95. data/sample/Diagram_sample/readme.txt +90 -0
  96. data/sample/Diagram_sample/wait_cursor.png +0 -0
  97. data/sample/Room3/blue.rb +297 -0
  98. data/sample/Room3/ending.rb +180 -0
  99. data/sample/Room3/green.rb +220 -0
  100. data/sample/Room3/image/akamatsu.png +0 -0
  101. data/sample/Room3/image/aoyama.png +0 -0
  102. data/sample/Room3/image/congra.png +0 -0
  103. data/sample/Room3/image/congratulation.png +0 -0
  104. data/sample/Room3/image/congratulation_bg.png +0 -0
  105. data/sample/Room3/image/cursor.png +0 -0
  106. data/sample/Room3/image/midori.png +0 -0
  107. data/sample/Room3/image/mittsu_no_oheya.png +0 -0
  108. data/sample/Room3/image/mittsu_no_oheya_logo.png +0 -0
  109. data/sample/Room3/image/room_blue.png +0 -0
  110. data/sample/Room3/image/room_green.png +0 -0
  111. data/sample/Room3/image/room_red.png +0 -0
  112. data/sample/Room3/image/start.png +0 -0
  113. data/sample/Room3/image/three_doors.png +0 -0
  114. data/sample/Room3/image/wait_cursor.png +0 -0
  115. data/sample/Room3/main.rb +120 -0
  116. data/sample/Room3/main_component.rb +59 -0
  117. data/sample/Room3/readme.txt +76 -0
  118. data/sample/Room3/red.rb +227 -0
  119. data/sample/Room3/room3.rb +25 -0
  120. data/sample/Room3/title.rb +184 -0
  121. data/sample/ball_action_sample.rb +204 -0
  122. data/sample/blit_rop.rb +70 -0
  123. data/sample/cairo_sample.rb +25 -0
  124. data/sample/circle_collision_test.rb +66 -0
  125. data/sample/collision_test.rb +33 -0
  126. data/sample/collision_test2.rb +108 -0
  127. data/sample/fixed_map_test/cursor.png +0 -0
  128. data/sample/fixed_map_test/fixed_map_sample.rb +140 -0
  129. data/sample/fixed_map_test/map.csv +19 -0
  130. data/sample/fixed_map_test/map_01.png +0 -0
  131. data/sample/fixed_map_test/mapchip.csv +23 -0
  132. data/sample/fixed_map_test/monster.png +0 -0
  133. data/sample/fixed_map_test/readme.txt +72 -0
  134. data/sample/map_test/chara.rb +58 -0
  135. data/sample/map_test/chr1.png +0 -0
  136. data/sample/map_test/cursor.png +0 -0
  137. data/sample/map_test/main_parts.rb +69 -0
  138. data/sample/map_test/main_scene.rb +153 -0
  139. data/sample/map_test/map.png +0 -0
  140. data/sample/map_test/map2.png +0 -0
  141. data/sample/map_test/map_layer.csv +127 -0
  142. data/sample/map_test/map_manager.rb +75 -0
  143. data/sample/map_test/map_test.rb +23 -0
  144. data/sample/map_test/mapchip.csv +21 -0
  145. data/sample/map_test/oasis.rb +71 -0
  146. data/sample/map_test/readme.txt +89 -0
  147. data/sample/map_test/route.rb +157 -0
  148. data/sample/map_test/sea.png +0 -0
  149. data/sample/map_test/town.rb +74 -0
  150. data/sample/map_test/wait_cursor.png +0 -0
  151. data/sample/map_test/window.png +0 -0
  152. data/sample/polygon_test.rb +35 -0
  153. data/sample/rasterscroll.rb +25 -0
  154. data/sample/takahashi.rb +42 -0
  155. data/sample/text.png +0 -0
  156. data/sample/textbox_sample.rb +192 -0
  157. data/sample/transform.rb +54 -0
  158. data/sample/utility_test.rb +73 -0
  159. data/sample/utility_test2.rb +61 -0
  160. data/sample/utility_test3.rb +64 -0
  161. data/sample/utility_test4.rb +73 -0
  162. data/uninstall_miyako.rb +19 -0
  163. data/win/miyako_no_katana.so +0 -0
  164. metadata +216 -0
@@ -0,0 +1,638 @@
1
+ # -*- encoding: utf-8 -*-
2
+ =begin
3
+ --
4
+ Miyako v2.1
5
+ Copyright (C) 2007-2009 Cyross Makoto
6
+
7
+ This library is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU Lesser General Public
9
+ License as published by the Free Software Foundation; either
10
+ version 2.1 of the License, or (at your option) any later version.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public
18
+ License along with this library; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ ++
21
+ =end
22
+
23
+ module Miyako
24
+ #==矩形当たり判定領域(コリジョン)クラス
25
+ # コリジョンの範囲は、元データ(スプライト等)の左上端を[0.0,0.0]として考案する
26
+ # コリジョンで使用する値は、実数での設定が可能
27
+ class Collision
28
+ extend Forwardable
29
+
30
+ # コリジョンの範囲([x,y,w,h])
31
+ attr_reader :rect
32
+ # 移動時イベントブロック配列
33
+
34
+ #===コリジョンのインスタンスを作成する
35
+ # 幅・高さが0以下のときは例外が発生する
36
+ # 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
37
+ # そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。
38
+ # circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。
39
+ #_rect_:: コリジョンを設定する範囲
40
+ #_circum_:: 矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue
41
+ #返却値:: 作成されたコリジョン
42
+ def initialize(rect, circum = true)
43
+ @rect = Rect.new(*(rect.to_a[0..3]))
44
+ raise MiyakoValueError, "Illegal width! #{@rect[2]}" if @rect[2] < Float::EPSILON
45
+ raise MiyakoValueError, "Illegal height! #{@rect[3]}" if @rect[3] < Float::EPSILON
46
+ w = @rect[2].to_f
47
+ h = @rect[2].to_f
48
+ @center = Point.new(@rect[0].to_f + w / 2.0, @rect[1].to_f + h / 2.0)
49
+ @radius = circum ? Math.sqrt(w ** 2 + h ** 2) / 2.0 : [w, h].min / 2.0
50
+ end
51
+
52
+ def initialize_copy(obj) #:nodoc:
53
+ @rect = @rect.dup
54
+ @center = @center.dup
55
+ end
56
+
57
+ #===当たり判定を行う(領域が重なっている)
58
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
59
+ #_c2_:: 判定対象のコリジョンインスタンス
60
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
61
+ #返却値:: 1ピクセルでも重なっていれば true を返す
62
+ def collision?(pos1, c2, pos2)
63
+ return Collision.collision?(self, pos1, c2, pos2)
64
+ end
65
+
66
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
67
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
68
+ #_c2_:: 判定対象のコリジョンインスタンス
69
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
70
+ #返却値:: 領域が隣り合っていれば true を返す
71
+ def meet?(pos1, c2, pos2)
72
+ return Collision.meet?(self, pos1, c2, pos2)
73
+ end
74
+
75
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
76
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
77
+ #_c2_:: 判定対象のコリジョンインスタンス
78
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
79
+ #返却値:: 領域が覆われていれば true を返す
80
+ def cover?(pos1, c2, pos2)
81
+ return Collision.cover?(self, pos1, c2, pos2)
82
+ end
83
+
84
+ #===当たり判定を行う(レシーバがc2を覆っている)
85
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
86
+ #_c2_:: 判定対象のコリジョンインスタンス
87
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
88
+ #返却値:: 領域が覆われていれば true を返す
89
+ def covers?(pos1, c2, pos2)
90
+ return Collision.covers?(self, pos1, c2, pos2)
91
+ end
92
+
93
+ #===当たり判定を行う(レシーバがc2に覆われている)
94
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
95
+ #_c2_:: 判定対象のコリジョンインスタンス
96
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
97
+ #返却値:: 領域が覆われていれば true を返す
98
+ def covered?(pos1, c2, pos2)
99
+ return Collision.covered?(self, pos1, c2, pos2)
100
+ end
101
+
102
+ #===当たり判定を行う(領域が重なっている)
103
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
104
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
105
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
106
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
107
+ #返却値:: 1ピクセルでも重なっていれば true を返す
108
+ def Collision.collision?(c1, pos1, c2, pos2)
109
+ l1 = pos1[0] + c1.rect[0]
110
+ t1 = pos1[1] + c1.rect[1]
111
+ r1 = l1 + c1.rect[2] - 1
112
+ b1 = t1 + c1.rect[3] - 1
113
+ l2 = pos2[0] + c2.rect[0]
114
+ t2 = pos2[1] + c2.rect[1]
115
+ r2 = l2 + c2.rect[2] - 1
116
+ b2 = t2 + c2.rect[3] - 1
117
+ v = 0
118
+ v |= 1 if l1 <= l2 && l2 <= r1
119
+ v |= 1 if l1 <= r2 && r2 <= r1
120
+ v |= 2 if t1 <= t2 && t2 <= b1
121
+ v |= 2 if t1 <= b2 && b2 <= b1
122
+ return v == 3
123
+ end
124
+
125
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
126
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
127
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
128
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
129
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
130
+ #返却値:: 領域が隣り合っていれば true を返す
131
+ def Collision.meet?(c1, pos1, c2, pos2)
132
+ l1 = pos1[0] + c1.rect[0]
133
+ t1 = pos1[1] + c1.rect[1]
134
+ r1 = l1 + c1.rect[2]
135
+ b1 = t1 + c1.rect[3]
136
+ l2 = pos2[0] + c2.rect[0]
137
+ t2 = pos2[1] + c2.rect[1]
138
+ r2 = l2 + c2.rect[2]
139
+ b2 = t2 + c2.rect[3]
140
+ v = 0
141
+ v |= 1 if r1 == l2
142
+ v |= 1 if b1 == t2
143
+ v |= 1 if l1 == r2
144
+ v |= 1 if t1 == b2
145
+ return v == 1
146
+ end
147
+
148
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
149
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
150
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
151
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
152
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
153
+ #返却値:: 領域が覆われていれば true を返す
154
+ def Collision.cover?(c1, pos1, c2, pos2)
155
+ l1 = pos1[0] + c1.rect[0]
156
+ t1 = pos1[1] + c1.rect[1]
157
+ r1 = l1 + c1.rect[2]
158
+ b1 = t1 + c1.rect[3]
159
+ l2 = pos2[0] + c2.rect[0]
160
+ t2 = pos2[1] + c2.rect[1]
161
+ r2 = l2 + c2.rect[2]
162
+ b2 = t2 + c2.rect[3]
163
+ v = 0
164
+ v |= 1 if l1 >= l2 && r1 <= r2
165
+ v |= 2 if t1 >= t2 && b1 <= b2
166
+ v |= 4 if l2 >= l1 && r2 <= r1
167
+ v |= 8 if t2 >= t1 && b2 <= b1
168
+ return v & 3 == 3 || v & 12 == 12
169
+ end
170
+
171
+ #===当たり判定を行う(c1がc2を覆っている)
172
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
173
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
174
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
175
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
176
+ #返却値:: 領域が覆われていれば true を返す
177
+ def Collision.covers?(c1, pos1, c2, pos2)
178
+ l1 = pos1[0] + c1.rect[0]
179
+ t1 = pos1[1] + c1.rect[1]
180
+ r1 = l1 + c1.rect[2]
181
+ b1 = t1 + c1.rect[3]
182
+ l2 = pos2[0] + c2.rect[0]
183
+ t2 = pos2[1] + c2.rect[1]
184
+ r2 = l2 + c2.rect[2]
185
+ b2 = t2 + c2.rect[3]
186
+ v = 0
187
+ v |= 1 if l2 >= l1 && r2 <= r1
188
+ v |= 2 if t2 >= t1 && b2 <= b1
189
+ return v & 3 == 3
190
+ end
191
+
192
+ #===当たり判定を行う(c1がc2に覆われている)
193
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
194
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
195
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
196
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
197
+ #返却値:: 領域が覆われていれば true を返す
198
+ def Collision.covered?(c1, pos1, c2, pos2)
199
+ l1 = pos1[0] + c1.rect[0]
200
+ t1 = pos1[1] + c1.rect[1]
201
+ r1 = l1 + c1.rect[2]
202
+ b1 = t1 + c1.rect[3]
203
+ l2 = pos2[0] + c2.rect[0]
204
+ t2 = pos2[1] + c2.rect[1]
205
+ r2 = l2 + c2.rect[2]
206
+ b2 = t2 + c2.rect[3]
207
+ v = 0
208
+ v |= 1 if l1 >= l2 && r1 <= r2
209
+ v |= 2 if t1 >= t2 && b1 <= b2
210
+ return v & 3 == 3
211
+ end
212
+
213
+ #== インスタンスの内容を解放する
214
+ #返却値:: なし
215
+ def dispose
216
+ @rect = nil
217
+ end
218
+ end
219
+
220
+ #==円形当たり判定領域(サークルコリジョン)クラス
221
+ # 円形の当たり判定を実装する。
222
+ # コリジョンは中心位置と半径で構成され、円形当たり判定同士で衝突判定を行う
223
+ # コリジョンで使用する値は、実数での設定が可能
224
+ class CircleCollision
225
+ extend Forwardable
226
+
227
+ # コリジョンの中心点([x,y])
228
+ attr_reader :center
229
+ # コリジョンの半径
230
+ attr_reader :radius
231
+ # 移動時イベントブロック配列
232
+
233
+ #===コリジョンのインスタンスを作成する
234
+ # コリジョンの半径が0もしくはマイナスのとき例外が発生する
235
+ # 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
236
+ # そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。
237
+ # circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。
238
+ #_center_:: コリジョンを設定する範囲
239
+ #_radius_:: コリジョンの半径
240
+ #_circum_:: 矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue
241
+ #返却値:: 作成されたコリジョン
242
+ def initialize(center, radius, circum = true)
243
+ raise MiyakoValueError, "illegal radius! #{radius}" if radius < Float::EPSILON
244
+ @center = Point.new(*(center.to_a[0..1]))
245
+ @radius = radius
246
+ if circum
247
+ rad = @radius.to_f / Math.sqrt(2.0)
248
+ @rect = Rect.new(@center[0]-rad, @center[1]-rad, rad*2.0, rad*2.0)
249
+ else
250
+ @rect = Rect.new(@center[0]-@radius, @center[1]-@radius, @radius*2.0, @radius*2.0)
251
+ end
252
+ end
253
+
254
+ def initialize_copy(obj) #:nodoc:
255
+ @rect = @rect.dup
256
+ @center = @center.dup
257
+ end
258
+
259
+ #===当たり判定間の距離を算出する
260
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
261
+ #_c2_:: 判定対象のコリジョンインスタンス
262
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
263
+ #返却値:: 1ピクセルでも重なっていれば true を返す
264
+ def interval(pos1, c2, pos2)
265
+ return CircleCollision.interval(self, pos1, c2, pos2)
266
+ end
267
+
268
+ #===当たり判定を行う(領域が重なっている)
269
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
270
+ #_c2_:: 判定対象のコリジョンインスタンス
271
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
272
+ #返却値:: 1ピクセルでも重なっていれば true を返す
273
+ def collision?(pos1, c2, pos2)
274
+ return CircleCollision.collision?(self, pos1, c2, pos2)
275
+ end
276
+
277
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
278
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
279
+ #_c2_:: 判定対象のコリジョンインスタンス
280
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
281
+ #返却値:: 領域が隣り合っていれば true を返す
282
+ def meet?(pos1, c2, pos2)
283
+ return CircleCollision.meet?(self, pos1, c2, pos2)
284
+ end
285
+
286
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
287
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
288
+ #_c2_:: 判定対象のコリジョンインスタンス
289
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
290
+ #返却値:: 領域が覆われていれば true を返す
291
+ def cover?(pos1, c2, pos2)
292
+ return CircleCollision.cover?(self, pos1, c2, pos2)
293
+ end
294
+
295
+ #===当たり判定を行う(レシーバがc2を覆っている)
296
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
297
+ #_c2_:: 判定対象のコリジョンインスタンス
298
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
299
+ #返却値:: 領域が覆われていれば true を返す
300
+ def covers?(pos1, c2, pos2)
301
+ return CircleCollision.covers?(self, pos1, c2, pos2)
302
+ end
303
+
304
+ #===当たり判定を行う(レシーバがc2に覆われている)
305
+ #_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
306
+ #_c2_:: 判定対象のコリジョンインスタンス
307
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
308
+ #返却値:: 領域が覆われていれば true を返す
309
+ def covered?(pos1, c2, pos2)
310
+ return CircleCollision.covered?(self, pos1, c2, pos2)
311
+ end
312
+
313
+ #===当たり判定間の距離を算出する
314
+ # 2つの当たり判定がどの程度離れているかを算出する。
315
+ # 返ってくる値は、衝突していなければ正の実数、衝突していれば負の実数で返ってくる
316
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
317
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
318
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
319
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
320
+ #返却値:: 当たり判定間の距離
321
+ def CircleCollision.interval(c1, pos1, c2, pos2)
322
+ #2点間の距離を求める
323
+ d = Math.sqrt((((c1.center[0].to_f + pos1[0].to_f) - (c2.center[0].to_f + pos2[0].to_f)) ** 2) +
324
+ (((c1.center[1].to_f + pos1[1].to_f) - (c2.center[1].to_f + pos2[1].to_f)) ** 2))
325
+ #半径の和を求める
326
+ r = c1.radius.to_f + c2.radius.to_f
327
+ distance = d - r
328
+ return distance.abs < Float::EPSILON ? 0.0 : distance
329
+ end
330
+
331
+ #===当たり判定を行う(領域が重なっている)
332
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
333
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
334
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
335
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
336
+ #返却値:: 1ピクセルでも重なっていれば true を返す
337
+ def CircleCollision.collision?(c1, pos1, c2, pos2)
338
+ #2点間の距離を求める
339
+ d = (((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2) +
340
+ (((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2)
341
+ #半径の和を求める
342
+ r = (c1.radius + c2.radius) ** 2
343
+ return d <= r
344
+ end
345
+
346
+ #===当たり判定を行う(領域がピクセル単位で隣り合っている)
347
+ # 但し、実際の矩形範囲が偶数の時は性格に判定できない場合があるため注意
348
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
349
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
350
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
351
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
352
+ #返却値:: 領域が隣り合っていれば true を返す
353
+ def CircleCollision.meet?(c1, pos1, c2, pos2)
354
+ #2点間の距離を求める
355
+ d = (((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2) +
356
+ (((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2)
357
+ #半径の和を求める
358
+ r = (c1.radius + c2.radius) ** 2
359
+ return d == r
360
+ end
361
+
362
+ #===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
363
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
364
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
365
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
366
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
367
+ #返却値:: 領域が覆われていれば true を返す
368
+ def CircleCollision.cover?(c1, pos1, c2, pos2)
369
+ #2点間の距離を求める
370
+ d = ((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2 +
371
+ ((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2
372
+ #半径の差分を求める
373
+ r = c1.radius ** 2 - 2 * (c1.radius * c2.radius) + c2.radius ** 2
374
+ return d <= r
375
+ end
376
+
377
+ #===当たり判定を行う(c1がc2を覆っている)
378
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
379
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
380
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
381
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
382
+ #返却値:: 領域が覆われていれば true を返す
383
+ def CircleCollision.covers?(c1, pos1, c2, pos2)
384
+ #2点間の距離を求める
385
+ d = ((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2 +
386
+ ((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2
387
+ #半径の差分を求める
388
+ r1 = c1.radius
389
+ r2 = c2.radius
390
+ r = r1 ** 2 - 2 * (r1 * r2) + r2 ** 2
391
+ return r1 >= r2 && d <= r
392
+ end
393
+
394
+ #===当たり判定を行う(c1がc2に覆われている)
395
+ #_c1_:: 判定対象のコリジョンインスタンス(1)
396
+ #_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
397
+ #_c2_:: 判定対象のコリジョンインスタンス(2)
398
+ #_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
399
+ #返却値:: 領域が覆われていれば true を返す
400
+ def CircleCollision.covered?(c1, pos1, c2, pos2)
401
+ #2点間の距離を求める
402
+ d = ((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2 +
403
+ ((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2
404
+ #半径の差分を求める
405
+ r1 = c1.radius
406
+ r2 = c2.radius
407
+ r = r2 ** 2 - 2 * (r1 * r2) + r1 ** 2
408
+ return r2 >= r1 && d <= r
409
+ end
410
+
411
+ #== インスタンスの内容を解放する
412
+ #返却値:: なし
413
+ def dispose
414
+ @point = nil
415
+ end
416
+ end
417
+
418
+ #==コリジョン管理クラス
419
+ # 複数のコリジョンと元オブジェクトを配列の様に一括管理できる
420
+ # 当たり判定を一括処理することで高速化を図る
421
+ class Collisions
422
+ include Enumerable
423
+ extend Forwardable
424
+
425
+ #===コリジョンのインスタンスを作成する
426
+ # points引数の各要素は、以下の3つの条件のどれかに適合する必要がある。しない場合は例外が発生する
427
+ # 1)[x,y]の要素を持つ配列
428
+ # 2)Point構造体、Rect構造体、もしくはSquare構造体
429
+ # 3)x,yメソッドを持つ
430
+ #_collisions_:: コリジョンの配列。デフォルトは []
431
+ #_points_:: 位置情報の配列。デフォルトは []
432
+ #返却値:: 作成されたインスタンス
433
+ def initialize(collisions=[], points=[])
434
+ @collisions = Array.new(collisions).zip(points)
435
+ end
436
+
437
+ def initialize_copy(obj) #:nodoc:
438
+ @collisions = @collisions.dup
439
+ end
440
+
441
+ def deep_dup_collision #:nodocs:
442
+ @collisions = @collisions.deep_dup
443
+ return self
444
+ end
445
+
446
+ #===要素も複製した複製インスタンスを返す
447
+ #返却値:: 複製したインスタンスを返す
448
+ def deep_dup
449
+ ret = self.dup
450
+ ret.deep_dup_collision
451
+ end
452
+
453
+ #===コリジョンと位置情報を追加する
454
+ # point引数は、以下の3つの条件のどれかに適合する必要がある。しない場合は例外が発生する
455
+ # 1)[x,y]の要素を持つ配列
456
+ # 2)Point構造体、Rect構造体、もしくはSquare構造体
457
+ # 3)x,yメソッドを持つ
458
+ #_collisions_:: コリジョン
459
+ #_point_:: 位置情報
460
+ #返却値:: 自分自身を返す
461
+ def add(collision, point)
462
+ @collisions << [collision, point]
463
+ return self
464
+ end
465
+
466
+ #===インスタンスに、コリジョンと位置情報の集合を追加する
467
+ # points引数の各要素は、以下の3つの条件のどれかに適合する必要がある。しない場合は例外が発生する
468
+ # 1)[x,y]の要素を持つ配列
469
+ # 2)Point構造体、Rect構造体、もしくはSquare構造体
470
+ # 3)x,yメソッドを持つ
471
+ #_collisions_:: コリジョンの配列
472
+ #_points_:: 位置情報の配列
473
+ #返却値:: 自分自身を返す
474
+ def append(collisions, points)
475
+ @collisions.concat(collisions.zip(points))
476
+ return self
477
+ end
478
+
479
+ #===インデックス形式でのコリジョン・本体の取得
480
+ #_idx_:: 配列のインデックス番号
481
+ #返却値:: インデックスに対応したコリジョンと位置情報との対。
482
+ #インデックスが範囲外の時はnilが返る
483
+ def [](idx)
484
+ return @collisions[idx]
485
+ end
486
+
487
+ #===コリジョン・本体の削除
488
+ #_idx_:: 配列のインデックス番号
489
+ #返却値:: 削除したコリジョンと本体との対
490
+ #インデックスが範囲外の時はnilが返る
491
+ def delete(idx)
492
+ return @collisions.delete_at(idx)
493
+ end
494
+
495
+ #===インデックス形式でのコリジョン・本体の取得
496
+ #_idx_:: 配列のインデックス番号
497
+ #返却値:: インデックスに対応したコリジョンと本体との対
498
+ def clear
499
+ @collisions.clear
500
+ return self
501
+ end
502
+
503
+ #===タッピングを行う
504
+ # ブロックを渡すことにより、タッピングを行う
505
+ # ブロック内の引数は、|コリジョン,本体|の2が渡される
506
+ #返却値:: 自分自身を返す
507
+ def each
508
+ @collisions.each{|cb| yield cb[0], cb[1] }
509
+ return self
510
+ end
511
+
512
+ #===タッピングを行う
513
+ # ブロックを渡すことにより、タッピングを行う
514
+ # ブロック内の引数は、|コリジョン,本体|の2が渡される
515
+ #_idx_:: 配列のインデックス
516
+ #返却値:: 自分自身を返す
517
+ def tap(idx)
518
+ yield @collisions[idx][0], @collisions[idx][1]
519
+ return self
520
+ end
521
+
522
+ #===当たり判定を行う(配列要素がcと重なっている)
523
+ # 重なったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
524
+ # 重なったコリジョンが無い場合はnilを返す
525
+ #_c_:: 判定対象のコリジョンインスタンス
526
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
527
+ #返却値:: コリジョンと本体の対。
528
+ def collision?(c, pos)
529
+ return @collisions.detect{|cc| c.collision?(pos, cc[0], cc[1])}
530
+ end
531
+
532
+ #===当たり判定を行う(配列要素のどれかがcとピクセル単位で隣り合っている)
533
+ # 隣り合ったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
534
+ # 隣り合ったコリジョンが無い場合はnilを返す
535
+ #_c_:: 判定対象のコリジョンインスタンス
536
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
537
+ #返却値:: 隣り合っていれば true を返す
538
+ def meet?(c, pos)
539
+ return @collisions.detect{|cc| c.meet?(pos, cc[0], cc[1])}
540
+ end
541
+
542
+ #===当たり判定を行う(配列要素とcのどちらかが、もう一方にすっぽり覆われている))
543
+ # 覆われたコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
544
+ # 覆われたコリジョンが無い場合はnilを返す
545
+ #_c_:: 判定対象のコリジョンインスタンス
546
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
547
+ #返却値:: 領域が覆われていれば true を返す
548
+ def cover?(c, pos)
549
+ return @collisions.detect{|cc| c.cover?(pos, cc[0], cc[1])}
550
+ end
551
+
552
+ #===当たり判定を行う(配列要素のどれかがcを覆っている))
553
+ # 覆われたコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
554
+ # 覆われたコリジョンが無い場合はnilを返す
555
+ #_c_:: 判定対象のコリジョンインスタンス
556
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
557
+ #返却値:: 領域が覆われていれば true を返す
558
+ def covers?(c, pos)
559
+ return @collisions.detect{|cc| c.covers?(pos, cc[0], cc[1])}
560
+ end
561
+
562
+ #===当たり判定を行う(配列要素のどれかがcに覆われている))
563
+ # 覆われたコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
564
+ # 覆われたコリジョンが無い場合はnilを返す
565
+ #_c_:: 判定対象のコリジョンインスタンス
566
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
567
+ #返却値:: 領域が覆われていれば true を返す
568
+ def covered?(c, pos)
569
+ return @collisions.detect{|cc| c.covered?(pos, cc[0], cc[1])}
570
+ end
571
+
572
+ #===当たり判定を行う(配列要素とcが重なっている)
573
+ # 重なったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
574
+ # 重なったコリジョンが無い場合はnilを返す
575
+ #_c_:: 判定対象のコリジョンインスタンス
576
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
577
+ #返却値:: コリジョンと本体の対の配列。
578
+ def collision_all?(c, pos)
579
+ return @collisions.select{|cc| c.collision?(pos, cc[0], cc[1])}
580
+ end
581
+
582
+ #===当たり判定を行う(配列要素がcとピクセル単位で隣り合っている)
583
+ # 隣り合ったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
584
+ # 隣り合ったコリジョンが無い場合はnilを返す
585
+ #_c_:: 判定対象のコリジョンインスタンス
586
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
587
+ #返却値:: コリジョンと本体の対の配列。
588
+ def meet_all?(c, pos)
589
+ return @collisions.select{|cc| c.meet?(pos, cc[0], cc[1])}
590
+ end
591
+
592
+ #===当たり判定を行う(配列要素かcがもう一方を覆っている))
593
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
594
+ # 覆われたコリジョンが無い場合はnilを返す
595
+ #_c_:: 判定対象のコリジョンインスタンス
596
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
597
+ #返却値:: コリジョンと本体の対の配列。
598
+ def cover_all?(c, pos)
599
+ return @collisions.select{|cc| c.cover?(pos, cc[0], cc[1])}
600
+ end
601
+
602
+ #===当たり判定を行う(配列要素が領域がcを覆っている))
603
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
604
+ # 覆われたコリジョンが無い場合はnilを返す
605
+ #_c_:: 判定対象のコリジョンインスタンス
606
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
607
+ #返却値:: コリジョンと本体の対の配列。
608
+ def covers_all?(c, pos)
609
+ return @collisions.select{|cc| c.covers?(pos, cc[0], cc[1])}
610
+ end
611
+
612
+ #===当たり判定を行う(配列要素がcに覆われている))
613
+ # 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
614
+ # 覆われたコリジョンが無い場合はnilを返す
615
+ #_c_:: 判定対象のコリジョンインスタンス
616
+ #_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
617
+ #返却値:: コリジョンと本体の対の配列。
618
+ def covered_all?(c, pos)
619
+ return @collisions.select{|cc| c.covered?(pos, cc[0], cc[1])}
620
+ end
621
+
622
+ #===インデックス形式でのコリジョン・本体の取得
623
+ # 判定に引っかかったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
624
+ # 当たり判定に引っかかったコリジョンが無い場合はnilを返す
625
+ #_idx_:: 配列のインデックス番号
626
+ #返却値:: インデックスに対応したコリジョンと本体との対
627
+ def [](idx)
628
+ return [@collisions[idx], @bodies[idx]]
629
+ end
630
+
631
+ #===オブジェクトを解放する
632
+ #返却値:: なし
633
+ def dispose
634
+ @collisions.clear
635
+ @collisions = nil
636
+ end
637
+ end
638
+ end