cyross-ruby-miyako 2.0.0 → 2.0.5.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.
- data/README +106 -154
- data/defines.h +144 -0
- data/{miyako_no_katana/extconf.rb → extconf.rb} +10 -0
- data/extern.h +29 -0
- data/install_miyako.rb +26 -14
- data/lib/Miyako/API/audio.rb +2 -2
- data/lib/Miyako/API/basic_data.rb +183 -41
- data/lib/Miyako/API/bitmap.rb +474 -2
- data/lib/Miyako/API/choices.rb +215 -48
- data/lib/Miyako/API/collision.rb +267 -251
- data/lib/Miyako/API/diagram.rb +58 -70
- data/lib/Miyako/API/drawing.rb +93 -52
- data/lib/Miyako/API/fixedmap.rb +233 -120
- data/lib/Miyako/API/font.rb +59 -40
- data/lib/Miyako/API/input.rb +34 -27
- data/lib/Miyako/API/layout.rb +154 -172
- data/lib/Miyako/API/map.rb +285 -159
- data/lib/Miyako/API/map_event.rb +4 -4
- data/lib/Miyako/API/modules.rb +1 -1
- data/lib/Miyako/API/movie.rb +8 -5
- data/lib/Miyako/API/parts.rb +44 -9
- data/lib/Miyako/API/plane.rb +37 -2
- data/lib/Miyako/API/screen.rb +90 -22
- data/lib/Miyako/API/shape.rb +118 -37
- data/lib/Miyako/API/sprite.rb +475 -61
- data/lib/Miyako/API/sprite_animation.rb +83 -63
- data/lib/Miyako/API/spriteunit.rb +47 -13
- data/lib/Miyako/API/story.rb +123 -47
- data/lib/Miyako/API/textbox.rb +361 -132
- data/lib/Miyako/API/utility.rb +388 -0
- data/lib/Miyako/API/viewport.rb +54 -349
- data/lib/Miyako/API/yuki.rb +570 -353
- data/lib/Miyako/EXT/miyako_cairo.rb +5 -3
- data/lib/Miyako/EXT/slides.rb +22 -1
- data/lib/Miyako/miyako.rb +12 -13
- data/logo/EGSR_logo.png +0 -0
- data/logo/EGSR_logo_bg.png +0 -0
- data/logo/EGSR_logo_fg.png +0 -0
- data/logo/EGSR_title_banner.png +0 -0
- data/logo/EGSR_title_logo.png +0 -0
- data/logo/miyako.png +0 -0
- data/logo/miyako_banner.png +0 -0
- data/logo/space.png +0 -0
- data/miyako_basicdata.c +590 -0
- data/miyako_bitmap.c +1225 -0
- data/miyako_collision.c +403 -0
- data/miyako_drawing.c +187 -0
- data/miyako_font.c +334 -0
- data/miyako_hsv.c +830 -0
- data/miyako_layout.c +191 -0
- data/miyako_no_katana.c +1074 -0
- data/miyako_transform.c +438 -0
- data/miyako_utility.c +288 -0
- data/sample/Animation1/m1ku.rb +10 -31
- data/sample/Animation1/readme.txt +6 -6
- data/sample/Animation2/lex.rb +1 -0
- data/sample/Animation2/readme.txt +6 -6
- data/sample/Diagram_sample/diagram_sample_yuki2.rb +152 -48
- data/sample/Diagram_sample/readme.txt +9 -6
- data/sample/Room3/blue.rb +234 -187
- data/sample/Room3/ending.rb +68 -63
- data/sample/Room3/green.rb +159 -124
- data/sample/Room3/main.rb +50 -32
- data/sample/Room3/main_component.rb +3 -2
- data/sample/Room3/readme.txt +6 -6
- data/sample/Room3/red.rb +161 -134
- data/sample/Room3/room3.rb +1 -0
- data/sample/Room3/title.rb +75 -62
- data/sample/ball_action_sample.rb +204 -0
- data/sample/blit_rop.rb +70 -0
- data/sample/cairo_sample.rb +25 -0
- data/sample/circle_collision_test.rb +66 -0
- data/sample/collision_test.rb +33 -0
- data/sample/collision_test2.rb +108 -0
- data/sample/fixed_map_test/fixed_map_sample.rb +23 -32
- data/sample/fixed_map_test/readme.txt +38 -38
- data/sample/map_test/chara.rb +17 -9
- data/sample/map_test/main_parts.rb +30 -9
- data/sample/map_test/main_scene.rb +57 -41
- data/sample/map_test/map_manager.rb +13 -30
- data/sample/map_test/map_test.rb +2 -2
- data/sample/map_test/oasis.rb +17 -11
- data/sample/map_test/readme.txt +50 -48
- data/sample/map_test/route.rb +46 -33
- data/sample/map_test/town.rb +19 -13
- data/sample/polygon_test.rb +35 -0
- data/sample/rasterscroll.rb +25 -0
- data/sample/takahashi.rb +42 -0
- data/sample/text.png +0 -0
- data/sample/textbox_sample.rb +190 -0
- data/sample/transform.rb +54 -0
- data/sample/utility_test.rb +73 -0
- data/sample/utility_test2.rb +61 -0
- data/sample/utility_test3.rb +64 -0
- data/sample/utility_test4.rb +73 -0
- data/uninstall_miyako.rb +19 -0
- data/win/miyako_no_katana.so +0 -0
- metadata +165 -148
- data/miyako.png +0 -0
- data/miyako_banner.png +0 -0
- data/miyako_no_katana/miyako_no_katana.c +0 -3301
- data/sample/fixed_map_test/map_sample.rb +0 -121
data/lib/Miyako/API/choices.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
=begin
|
3
3
|
--
|
4
4
|
Miyako v2.0
|
5
|
-
Copyright (C) 2007-
|
5
|
+
Copyright (C) 2007-2009 Cyross Makoto
|
6
6
|
|
7
7
|
This library is free software; you can redistribute it and/or
|
8
8
|
modify it under the terms of the GNU Lesser General Public
|
@@ -22,10 +22,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
22
22
|
|
23
23
|
module Miyako
|
24
24
|
#==選択肢構造体
|
25
|
-
|
25
|
+
# 選択肢を構成する要素の集合
|
26
26
|
#
|
27
|
-
|
28
|
-
|
27
|
+
# 複数のChoice構造体のインスタンスをまとめて、配列として構成されている
|
28
|
+
# 選択肢を表示させるときは、body 自体の表示位置を変更させる必要がある
|
29
29
|
#
|
30
30
|
#_body_:: 選択肢を示す画像
|
31
31
|
#_body_selected_:: 選択肢を示す画像(選択時)
|
@@ -37,10 +37,14 @@ module Miyako
|
|
37
37
|
#_up_:: 上方向を選択したときに参照するChoice構造体のインスタンス
|
38
38
|
#_down_:: 下方向を選択したときに参照するChoice構造体のインスタンス
|
39
39
|
#_base_:: 構造体が要素となっている配列
|
40
|
-
|
40
|
+
#_attribute_:: 属性を示すハッシュ
|
41
|
+
#_end_select_proc_:: この選択肢を選択したときに優先的に処理するブロック。
|
42
|
+
#ブロックは1つの引数を取る(コマンド選択テキストボックス))。
|
43
|
+
#デフォルトはnil(何もしない)
|
44
|
+
Choice = Struct.new(:body, :body_selected, :condition, :selected, :result, :left, :right, :up, :down, :base, :attribute, :end_select_proc)
|
41
45
|
|
42
46
|
#==選択肢を管理するクラス
|
43
|
-
|
47
|
+
# 選択肢は、Shapeクラスから生成したスプライトもしくは画像で構成される
|
44
48
|
class Choices
|
45
49
|
include Layout
|
46
50
|
include SpriteBase
|
@@ -48,18 +52,34 @@ module Miyako
|
|
48
52
|
include Enumerable
|
49
53
|
extend Forwardable
|
50
54
|
|
55
|
+
attr_accessor :visible #レンダリングの可否(true->描画 false->非描画)
|
56
|
+
|
51
57
|
# インスタンスを生成する
|
52
58
|
# 返却値:: 生成された Choices クラスのインスタンス
|
53
59
|
def initialize
|
60
|
+
init_layout
|
54
61
|
@choices = []
|
55
62
|
@now = nil
|
56
63
|
@non_select = false
|
57
64
|
@last_selected = nil
|
65
|
+
@result = nil
|
66
|
+
@visible = true
|
67
|
+
set_layout_size(1, 1)
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_layout_position #:nodoc:
|
71
|
+
dx = @layout.pos[0] - rect[0]
|
72
|
+
dy = @layout.pos[1] - rect[1]
|
73
|
+
@choices.each{|ch|
|
74
|
+
ch.each{|cc|
|
75
|
+
cc.body.move(dx, dy)
|
76
|
+
cc.body_selected.move(dx, dy) if cc.body_selected && cc.body != cc.body_selected
|
77
|
+
}
|
78
|
+
}
|
58
79
|
end
|
59
80
|
|
60
81
|
# 選択肢を作成する
|
61
82
|
# Choice 構造体のインスタンスを作成する
|
62
|
-
#
|
63
83
|
# 構造体には、引数bodyと、必ず true を返す条件ブロックが登録されている。残りは nil
|
64
84
|
#_body_:: 選択肢を示す画像
|
65
85
|
#_body_selected_:: 選択肢を示す画像(選択時)。デフォルトはnil
|
@@ -67,7 +87,7 @@ module Miyako
|
|
67
87
|
#返却値:: 生成された Choice構造体のインスタンス
|
68
88
|
def Choices.create_choice(body, body_selected = nil, selected = false)
|
69
89
|
choice = Choice.new(body, body_selected, Proc.new{ true }, selected,
|
70
|
-
nil, nil, nil, nil, nil, nil)
|
90
|
+
nil, nil, nil, nil, nil, nil, {}, nil)
|
71
91
|
choice.left = choice
|
72
92
|
choice.right = choice
|
73
93
|
choice.up = choice
|
@@ -80,6 +100,8 @@ module Miyako
|
|
80
100
|
choices.each{|v| v.base = choices}
|
81
101
|
@choices.push(choices)
|
82
102
|
@last_selected = @choices[0][0] if (@choices.length == 1 && @last_selcted == nil)
|
103
|
+
rect = self.broad_rect
|
104
|
+
set_layout_size(rect.w, rect.h)
|
83
105
|
return self
|
84
106
|
end
|
85
107
|
|
@@ -96,32 +118,76 @@ module Miyako
|
|
96
118
|
|
97
119
|
def_delegators(:@choices, :push, :pop, :shift, :unshift, :[], :[]=, :clear, :length)
|
98
120
|
|
121
|
+
#===選択を開始しているかどうかを問い合わせる
|
122
|
+
# start_choiceメソッドを呼び出して、コマンド選択が始まっているかどうかを問い合わせ、始まっているときはtrueを返す
|
123
|
+
#返却値:: 選択を開始しているときはtrueを返す
|
124
|
+
def choicing?
|
125
|
+
return @now != nil
|
126
|
+
end
|
127
|
+
|
99
128
|
#===選択を開始する
|
100
|
-
|
129
|
+
# 選択肢の初期位置を指定することができる
|
130
|
+
# 第1引数にnilを渡すと、最後に選択した選択肢が最初に選択状態にある選択肢となる
|
131
|
+
# (例)
|
132
|
+
# choices.start_choice # [0][0]で示す位置の選択肢を選択する
|
133
|
+
# choices.start_choice(5,1) # [5][1]で示す位置の選択肢を選択する
|
134
|
+
# choices.start_choice(nil) # 最後に選択した選択肢を選択する(未選択だったときは全省略時の呼び出しと等価)
|
101
135
|
#_x_:: 初期位置(x 座標)。規定値は 0。nilを渡すと、最後に選択した選択肢が選ばれる。
|
102
136
|
#_y_:: 初期位置(y 座標)。規定値は 0
|
103
137
|
def start_choice(x = 0, y = 0)
|
104
|
-
raise MiyakoError, "Illegal choice position! [#{x}][#{y}]" if (x != nil && x < 0 || x >= @choices.length || y < 0 || y >= @choices[x].length)
|
138
|
+
raise MiyakoError, "Illegal choice position! [#{x}][#{y}]" if (x != nil && (x < 0 || x >= @choices.length || y < 0 || y >= @choices[x].length))
|
105
139
|
@now = x ? @choices[x][y] : @last_selected
|
106
140
|
@now.selected = true
|
107
141
|
@last_selected = @now
|
108
142
|
@non_select = false
|
143
|
+
@result = nil
|
144
|
+
end
|
145
|
+
|
146
|
+
#===選択を終了する
|
147
|
+
# 選択の終了処理を行う
|
148
|
+
# 引数に選択に使用したテキストボックスを渡し、選択状態にあるしたChoice構造体に
|
149
|
+
#end_select_procブロックを渡しているとき、そのブロックを評価する
|
150
|
+
# (そのとき、引数とした渡ってきたテキストボックスをブロック引数に取る)。
|
151
|
+
#
|
152
|
+
#_command_box_:: 選択に使用したテキストボックス。デフォルトはnil
|
153
|
+
def end_choice(command_box = nil)
|
154
|
+
return unless @now
|
155
|
+
return @now.end_select_proc.call(command_box) if (command_box != nil && @now.end_select_proc != nil)
|
156
|
+
@result = @now.result
|
157
|
+
@now.selected = false
|
158
|
+
@last_selected = @now
|
159
|
+
@now = nil
|
160
|
+
@non_select = true
|
109
161
|
end
|
110
162
|
|
111
163
|
#===選択肢本体を取得する
|
112
|
-
|
113
|
-
|
164
|
+
# 選択肢の表示対象となるインスタンスを取得する
|
165
|
+
# Choice構造体にbody_selectedが設定されている時はbody_selected、そうでなければbodyを返す
|
166
|
+
# まだ選択が開始されていなければnilが返る
|
167
|
+
#返却値:: 選択肢本体(選択時)
|
114
168
|
def body
|
169
|
+
return nil unless @now
|
115
170
|
return @now.body_selected ? @now.body_selected : @now.body
|
116
171
|
end
|
117
172
|
|
118
173
|
#===選択結果を取得する
|
119
|
-
|
174
|
+
# 現在の選択肢が所持している結果インスタンスを返す
|
175
|
+
# まだ選択が開始されていなければnilが返る
|
120
176
|
#返却値:: 選択結果
|
121
177
|
def result
|
178
|
+
return @result unless @now
|
122
179
|
return @now.result
|
123
180
|
end
|
124
181
|
|
182
|
+
#===現在選択している選択肢の属性をアクセスする
|
183
|
+
# 属性を編集・参照できるハッシュを取得する
|
184
|
+
# まだ選択が開始されていなければnilが返る
|
185
|
+
#返却値:: 属性(対応するChoice#attributeメソッドの値)
|
186
|
+
def attribute
|
187
|
+
return nil unless @now
|
188
|
+
return @now.attribute
|
189
|
+
end
|
190
|
+
|
125
191
|
def update_choices(org, nxt) #:nodoc:
|
126
192
|
obase = org.base
|
127
193
|
nbase = nxt.base
|
@@ -143,27 +209,73 @@ module Miyako
|
|
143
209
|
#現在の選択状態を、全部選択していない状態にする
|
144
210
|
#返却値:: 自分自身を返す
|
145
211
|
def non_select
|
146
|
-
@now.base.each{|c| c.selected = false }
|
212
|
+
@now.base.each{|c| c.selected = false } if @now
|
147
213
|
@non_select = true
|
148
214
|
return self
|
149
215
|
end
|
150
216
|
|
217
|
+
#===選択肢が選択状態かを問い合わせる
|
218
|
+
#現在、選択肢が選択状態か非選択状態(non_selectメソッド呼び出しなど)かを問い合わせる
|
219
|
+
#返却値:: 選択状態ならtrue、非選択状態ならfalseを返す
|
220
|
+
def any_select?
|
221
|
+
return !@non_select
|
222
|
+
end
|
223
|
+
|
151
224
|
#===選択肢を変更する
|
152
|
-
|
225
|
+
#指定の位置の現在の選択状態を、選択状態にする
|
153
226
|
#_x_:: x方向位置
|
154
227
|
#_y_:: y方向位置
|
155
228
|
#返却値:: 自分自身を返す
|
156
229
|
def select(x, y)
|
230
|
+
raise MiyakoError, "Not select yet!" unless @now
|
157
231
|
raise MiyakoError, "Illegal choice position! [#{x}][#{y}]" if (x < 0 || x >= @choices.length || y < 0 || y >= @choices[x].length)
|
158
|
-
@
|
232
|
+
@non_select = false
|
233
|
+
@last_selected = @now
|
234
|
+
@now.selected = false
|
235
|
+
obj = @choices[x][y]
|
236
|
+
update_choices(@now, obj)
|
237
|
+
@now = obj
|
238
|
+
@now.selected = true
|
159
239
|
return self
|
160
240
|
end
|
161
241
|
|
242
|
+
#===画面上の座標から、該当する選択肢を変更する
|
243
|
+
#マウスカーソル位置などの座標から、座標を含む選択肢を選択状態にする
|
244
|
+
#該当する場所が無ければfalseを返す
|
245
|
+
#まだ選択を開始していないときはfalseを返す
|
246
|
+
#_x_:: x方向位置
|
247
|
+
#_y_:: y方向位置
|
248
|
+
#返却値:: 選択肢が見つかったときはtrue、見つからなかったときはfalseを返す
|
249
|
+
def attach(x, y)
|
250
|
+
return false unless @now
|
251
|
+
obj = @now.base.detect{|ch| ch.selected ? ch.body_selected.broad_rect.in_range?(x, y) : ch.body.broad_rect.in_range?(x, y) }
|
252
|
+
return false unless obj
|
253
|
+
@non_select = false
|
254
|
+
@last_selected = @now
|
255
|
+
@now.selected = false
|
256
|
+
update_choices(@now, obj)
|
257
|
+
@now = obj
|
258
|
+
@now.selected = true
|
259
|
+
return true
|
260
|
+
end
|
261
|
+
|
262
|
+
#===画面上の座標から、該当する選択肢があるかどうかを問い合わせる
|
263
|
+
#マウスカーソル位置などの座標から、座標を含む選択肢があるときはtrue、無いときはfalseを返す
|
264
|
+
#まだ選択を開始していないときはfalseを返す
|
265
|
+
#_x_:: x方向位置
|
266
|
+
#_y_:: y方向位置
|
267
|
+
#返却値:: 選択肢が見つかったときはtrue、見つからなかったときはfalseを返す
|
268
|
+
def attach?(x, y)
|
269
|
+
return false unless @now
|
270
|
+
obj = @now.base.detect{|ch| ch.selected ? ch.body_selected.broad_rect.in_range?(x, y) : ch.body.broad_rect.in_range?(x, y) }
|
271
|
+
return obj ? true : false
|
272
|
+
end
|
273
|
+
|
162
274
|
#===選択肢を非選択状態に変更する
|
163
275
|
#現在の選択状態を、全部選択していない状態にする
|
164
276
|
#返却値:: 自分自身を返す
|
165
277
|
def non_select
|
166
|
-
@now.base.each{|c| c.selected = false }
|
278
|
+
@now.base.each{|c| c.selected = false } if @now
|
167
279
|
@non_select = true
|
168
280
|
return self
|
169
281
|
end
|
@@ -172,8 +284,11 @@ module Miyako
|
|
172
284
|
#現在表示できる選択肢を、現在の状態で描画するよう指示する
|
173
285
|
#ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る。
|
174
286
|
#ブロックの引数は、|インスタンスのSpriteUnit, 画面のSpriteUnit|となる。
|
287
|
+
#visibleメソッドの値がfalseのとき、選択が開始されていない時は描画されない。
|
175
288
|
#返却値:: 自分自身を返す
|
176
289
|
def render(&block)
|
290
|
+
return unless @visible
|
291
|
+
return self unless @now
|
177
292
|
@now.base.each{|c|
|
178
293
|
((c.body_selected && c.selected) ?
|
179
294
|
c.body_selected.render(&block) :
|
@@ -186,9 +301,12 @@ module Miyako
|
|
186
301
|
#現在表示できる選択肢を、現在の状態で描画するよう指示する
|
187
302
|
#ブロック付きで呼び出し可能(レシーバに対応したSpriteUnit構造体が引数として得られるので、補正をかけることが出来る。
|
188
303
|
#ブロックの引数は、|インスタンスのSpriteUnit, 画像のSpriteUnit|となる。
|
304
|
+
#visibleメソッドの値がfalseのとき、選択が開始されていない時は描画されない。
|
189
305
|
#_dst_:: 描画対象の画像インスタンス
|
190
306
|
#返却値:: 自分自身を返す
|
191
307
|
def render_to(dst, &block)
|
308
|
+
return self unless @visible
|
309
|
+
return self unless @now
|
192
310
|
@now.base.each{|c|
|
193
311
|
((c.body_selected && c.selected) ?
|
194
312
|
c.body_selected.render_to(dst, &block) :
|
@@ -199,35 +317,55 @@ module Miyako
|
|
199
317
|
|
200
318
|
#===スプライトに変換した画像を表示する
|
201
319
|
#すべてのパーツを貼り付けた、1枚のスプライトを返す
|
320
|
+
#引数1個のブロックを渡せば、スプライトに補正をかけることが出来る
|
321
|
+
#ただし、選択が開始されていなければnilを返す
|
202
322
|
#返却値:: 生成したスプライト
|
203
323
|
def to_sprite
|
324
|
+
return nil unless @now
|
204
325
|
rect = self.broad_rect
|
205
326
|
sprite = Sprite.new(:size=>rect.to_a[2,2], :type=>:ac)
|
327
|
+
Drawing.fill(sprite, [0,0,0])
|
328
|
+
Bitmap.ck_to_ac!(sprite, [0,0,0])
|
206
329
|
self.render_to(sprite){|sunit, dunit| sunit.x -= rect.x; sunit.y -= rect.y }
|
330
|
+
yield sprite if block_given?
|
207
331
|
return sprite
|
208
332
|
end
|
209
333
|
|
210
|
-
|
211
|
-
|
212
|
-
|
334
|
+
#===現在登録している選択肢の最大の大きさを矩形で取得する
|
335
|
+
# 現在インスタンスが所持している選択肢全てから左上座標、右下座標を取得し、矩形の形式で返す
|
336
|
+
# 但し、選択肢が一つも登録されていない時はRect(0,0,1,1)を返す
|
213
337
|
#返却値:: 生成された矩形(Rect構造体のインスタンス)
|
214
338
|
def broad_rect
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
339
|
+
return Rect.new(0, 0, 1, 1) if @choices.length == 0
|
340
|
+
xx = []
|
341
|
+
yy = []
|
342
|
+
@choices.each{|ch|
|
343
|
+
ch.each{|cc|
|
344
|
+
xx << cc.body.x
|
345
|
+
yy << cc.body.y
|
346
|
+
if cc.body_selected
|
347
|
+
xx << cc.body_selected.x
|
348
|
+
yy << cc.body_selected.y
|
349
|
+
end
|
350
|
+
}
|
351
|
+
}
|
352
|
+
min_x, max_x = xx.minmax
|
353
|
+
min_y, max_y = yy.minmax
|
354
|
+
return Rect.new(min_x, min_y, max_x-min_x+1, max_y-min_y+1)
|
355
|
+
end
|
356
|
+
|
357
|
+
#===現在登録している選択肢の大きさを矩形で取得する
|
358
|
+
# 内容はbroad_rectメソッドの結果と同じ
|
359
|
+
#返却値:: 生成された矩形(Rect構造体のインスタンス)
|
360
|
+
def rect
|
361
|
+
return self.broad_rect
|
362
|
+
end
|
363
|
+
|
364
|
+
#===選択肢を左移動させる
|
365
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
229
366
|
# 返却値:: 自分自身を返す
|
230
|
-
def
|
367
|
+
def left_choice
|
368
|
+
return self unless @now
|
231
369
|
@last_selected = @now
|
232
370
|
@now.selected = false
|
233
371
|
obj = @now.left
|
@@ -237,9 +375,11 @@ module Miyako
|
|
237
375
|
return self
|
238
376
|
end
|
239
377
|
|
240
|
-
|
378
|
+
#===選択肢を右移動させる
|
379
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
241
380
|
# 返却値:: 自分自身を返す
|
242
|
-
def
|
381
|
+
def right_choice
|
382
|
+
return self unless @now
|
243
383
|
@last_selected = @now
|
244
384
|
@now.selected = false
|
245
385
|
obj = @now.right
|
@@ -249,9 +389,11 @@ module Miyako
|
|
249
389
|
return self
|
250
390
|
end
|
251
391
|
|
252
|
-
|
392
|
+
#===選択肢を上移動させる
|
393
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
253
394
|
# 返却値:: 自分自身を返す
|
254
|
-
def
|
395
|
+
def up_choice
|
396
|
+
return self unless @now
|
255
397
|
@last_selected = @now
|
256
398
|
@now.selected = false
|
257
399
|
obj = @now.up
|
@@ -261,9 +403,11 @@ module Miyako
|
|
261
403
|
return self
|
262
404
|
end
|
263
405
|
|
264
|
-
|
406
|
+
#===選択肢を下移動させる
|
407
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
265
408
|
# 返却値:: 自分自身を返す
|
266
|
-
def
|
409
|
+
def down_choice
|
410
|
+
return self unless @now
|
267
411
|
@last_selected = @now
|
268
412
|
@now.selected = false
|
269
413
|
obj = @now.down
|
@@ -273,31 +417,54 @@ module Miyako
|
|
273
417
|
return self
|
274
418
|
end
|
275
419
|
|
276
|
-
|
420
|
+
#===選択肢のアニメーションを開始する
|
421
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
277
422
|
# 返却値:: 自分自身を返す
|
278
423
|
def start
|
279
|
-
|
424
|
+
return self unless @now
|
425
|
+
@now.base.each{|c|
|
426
|
+
if c.condition.call
|
427
|
+
c.body.start
|
428
|
+
c.body_selected.start if c.body != c.body_selected
|
429
|
+
end
|
430
|
+
}
|
280
431
|
return self
|
281
432
|
end
|
282
433
|
|
283
|
-
|
434
|
+
#===選択肢のアニメーションを終了させる
|
435
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
284
436
|
# 返却値:: 自分自身を返す
|
285
437
|
def stop
|
286
|
-
|
438
|
+
return self unless @now
|
439
|
+
@now.base.each{|c|
|
440
|
+
if c.condition.call
|
441
|
+
c.body.stop
|
442
|
+
c.body_selected.stop if c.body != c.body_selected
|
443
|
+
end
|
444
|
+
}
|
287
445
|
return self
|
288
446
|
end
|
289
447
|
|
290
|
-
|
448
|
+
#===選択肢のアニメーションの再生位置を最初に戻す
|
449
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
291
450
|
# 返却値:: 自分自身を返す
|
292
451
|
def reset
|
293
|
-
|
452
|
+
return self unless @now
|
453
|
+
@now.base.each{|c|
|
454
|
+
if c.condition.call
|
455
|
+
c.body.reset
|
456
|
+
c.body_selected.reset if c.body != c.body_selected
|
457
|
+
end
|
458
|
+
}
|
294
459
|
return self
|
295
460
|
end
|
296
461
|
|
297
|
-
|
462
|
+
#===選択肢のアニメーションを更新させる
|
298
463
|
# (手動で更新する必要があるときに呼び出す)
|
464
|
+
# 但し、まだ選択が開始されていなければ何もしない
|
299
465
|
# 返却値:: 自分自身を返す
|
300
466
|
def update_animation
|
467
|
+
return self unless @now
|
301
468
|
@now.base.each{|c|
|
302
469
|
((c.body_selected && c.selected) ?
|
303
470
|
c.body_selected.update_animation :
|
data/lib/Miyako/API/collision.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
=begin
|
3
3
|
--
|
4
4
|
Miyako v2.0
|
5
|
-
Copyright (C) 2007-
|
5
|
+
Copyright (C) 2007-2009 Cyross Makoto
|
6
6
|
|
7
7
|
This library is free software; you can redistribute it and/or
|
8
8
|
modify it under the terms of the GNU Lesser General Public
|
@@ -21,135 +21,74 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
21
21
|
=end
|
22
22
|
|
23
23
|
module Miyako
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
#==矩形当たり判定領域(コリジョン)クラス
|
25
|
+
# コリジョンの範囲は、元データ(スプライト等)の左上端を[0.0,0.0]として考案する
|
26
|
+
# コリジョンで使用する値は、実数での設定が可能
|
27
27
|
class Collision
|
28
28
|
extend Forwardable
|
29
29
|
|
30
30
|
# コリジョンの範囲([x,y,w,h])
|
31
|
-
|
32
|
-
#
|
33
|
-
attr_accessor :pos
|
34
|
-
# 移動方向([dx,dy], dx,dy:-1,0,1)
|
35
|
-
attr_accessor :direction
|
36
|
-
# 移動量([w,h])
|
37
|
-
attr_accessor :amount
|
31
|
+
attr_reader :rect
|
32
|
+
# 移動時イベントブロック配列
|
38
33
|
|
39
34
|
#===コリジョンのインスタンスを作成する
|
35
|
+
# 幅・高さが0以下のときは例外が発生する
|
36
|
+
# 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
|
37
|
+
# そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。
|
38
|
+
# circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。
|
40
39
|
#_rect_:: コリジョンを設定する範囲
|
41
|
-
#
|
40
|
+
#_circum_:: 矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue
|
42
41
|
#返却値:: 作成されたコリジョン
|
43
|
-
def initialize(rect,
|
42
|
+
def initialize(rect, circum = true)
|
44
43
|
@rect = Rect.new(*(rect.to_a[0..3]))
|
45
|
-
@
|
46
|
-
@
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
#_dx_:: 変換する方向(x軸方向、-1,0,1の3種類)
|
52
|
-
#_dy_:: 変換する方向(y軸方向、-1,0,1の3種類)
|
53
|
-
#返却値:: 自分自身を返す
|
54
|
-
def turn(dx, dy)
|
55
|
-
@direction = Point.new(dx, dy)
|
56
|
-
return self
|
57
|
-
end
|
58
|
-
|
59
|
-
#===コリジョンの移動量を変更する
|
60
|
-
#_mx_:: 変更する移動量(x軸方向)
|
61
|
-
#_my_:: 変更する移動量(y軸方向)
|
62
|
-
#返却値:: 自分自身を返す
|
63
|
-
def adjust(mx, my)
|
64
|
-
@amount = Size.new(mx, my)
|
65
|
-
return self
|
44
|
+
raise MiyakoError, "Illegal width! #{@rect[2]}" if @rect[2] < Float::EPSILON
|
45
|
+
raise MiyakoError, "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
|
66
50
|
end
|
67
51
|
|
68
52
|
#===当たり判定を行う(領域が重なっている)
|
53
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
69
54
|
#_c2_:: 判定対象のコリジョンインスタンス
|
55
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
70
56
|
#返却値:: 1ピクセルでも重なっていれば true を返す
|
71
|
-
def collision?(c2)
|
72
|
-
return Collision.collision?(self, c2)
|
57
|
+
def collision?(pos1, c2, pos2)
|
58
|
+
return Collision.collision?(self, pos1, c2, pos2)
|
73
59
|
end
|
74
60
|
|
75
|
-
#===当たり判定を行う(
|
61
|
+
#===当たり判定を行う(領域がピクセル単位で隣り合っている)
|
62
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
76
63
|
#_c2_:: 判定対象のコリジョンインスタンス
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
#===当たり判定を行う(移動後に領域が重なっている(移動前は重なっていない))
|
83
|
-
#_c2_:: 判定対象のコリジョンインスタンス
|
84
|
-
#返却値:: 1ピクセルでも重なっていれば true を返す
|
85
|
-
def into?(c2)
|
86
|
-
return Collision.into?(self, c2)
|
87
|
-
end
|
88
|
-
|
89
|
-
#===当たり判定を行う(移動後に領域が離れている(移動前は重なっている))
|
90
|
-
#_c2_:: 判定対象のコリジョンインスタンス
|
91
|
-
#返却値:: 1ピクセルでも重なっていれば true を返す
|
92
|
-
def out?(c2)
|
93
|
-
return Collision.out?(self, c2)
|
64
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
65
|
+
#返却値:: 領域が隣り合っていれば true を返す
|
66
|
+
def meet?(pos1, c2, pos2)
|
67
|
+
return Collision.meet?(self, pos1, c2, pos2)
|
94
68
|
end
|
95
69
|
|
96
70
|
#===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
|
71
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
97
72
|
#_c2_:: 判定対象のコリジョンインスタンス
|
73
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
98
74
|
#返却値:: 領域が覆われていれば true を返す
|
99
|
-
def cover?(c2)
|
100
|
-
return Collision.cover?(self, c2)
|
101
|
-
end
|
102
|
-
|
103
|
-
#===コリジョンをの位置を、指定の移動量で移動する
|
104
|
-
#_x_:: 移動量(x方向)。単位はピクセル
|
105
|
-
#_y_:: 移動量(y方向)。単位はピクセル
|
106
|
-
#返却値:: 自分自身を返す
|
107
|
-
def move(x, y)
|
108
|
-
@pos.move(x, y)
|
109
|
-
return self
|
110
|
-
end
|
111
|
-
|
112
|
-
#===コリジョンをの位置を、指定の位置へ移動する
|
113
|
-
#_x_:: 移動先の位置(x方向)。単位はピクセル
|
114
|
-
#_y_:: 移動先の位置(y方向)。単位はピクセル
|
115
|
-
#返却値:: 自分自身を返す
|
116
|
-
def move_to(x, y)
|
117
|
-
@pos.move_to(x, y)
|
118
|
-
return self
|
75
|
+
def cover?(pos1, c2, pos2)
|
76
|
+
return Collision.cover?(self, pos1, c2, pos2)
|
119
77
|
end
|
120
78
|
|
121
79
|
#===当たり判定を行う(領域が重なっている)
|
122
80
|
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
81
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
123
82
|
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
83
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
124
84
|
#返却値:: 1ピクセルでも重なっていれば true を返す
|
125
|
-
def Collision.collision?(c1, c2)
|
126
|
-
l1 =
|
127
|
-
t1 =
|
128
|
-
r1 = l1 + c1.rect[2] - 1
|
129
|
-
b1 = t1 + c1.rect[3] - 1
|
130
|
-
l2 = c2.pos[0] + c2.rect[0]
|
131
|
-
t2 = c2.pos[1] + c2.rect[1]
|
132
|
-
r2 = l2 + c2.rect[2] - 1
|
133
|
-
b2 = t2 + c2.rect[3] - 1
|
134
|
-
v = 0
|
135
|
-
v |= 1 if l1 <= l2 && l2 <= r1
|
136
|
-
v |= 1 if l1 <= r2 && r2 <= r1
|
137
|
-
v |= 2 if t1 <= t2 && t2 <= b1
|
138
|
-
v |= 2 if t1 <= b2 && b2 <= b1
|
139
|
-
return v == 3
|
140
|
-
end
|
141
|
-
|
142
|
-
#===当たり判定を行う(移動後の領域が重なっている)
|
143
|
-
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
144
|
-
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
145
|
-
#返却値:: 1ピクセルでも重なっていれば true を返す
|
146
|
-
def Collision.collision_with_move?(c1, c2)
|
147
|
-
l1 = c1.pos[0] + c1.rect[0] + c1.direction[0] * c1.amount[0]
|
148
|
-
t1 = c1.pos[1] + c1.rect[1] + c1.direction[1] * c1.amount[1]
|
85
|
+
def Collision.collision?(c1, pos1, c2, pos2)
|
86
|
+
l1 = pos1[0] + c1.rect[0]
|
87
|
+
t1 = pos1[1] + c1.rect[1]
|
149
88
|
r1 = l1 + c1.rect[2] - 1
|
150
89
|
b1 = t1 + c1.rect[3] - 1
|
151
|
-
l2 =
|
152
|
-
t2 =
|
90
|
+
l2 = pos2[0] + c2.rect[0]
|
91
|
+
t2 = pos2[1] + c2.rect[1]
|
153
92
|
r2 = l2 + c2.rect[2] - 1
|
154
93
|
b2 = t2 + c2.rect[3] - 1
|
155
94
|
v = 0
|
@@ -160,17 +99,19 @@ module Miyako
|
|
160
99
|
return v == 3
|
161
100
|
end
|
162
101
|
|
163
|
-
#===当たり判定を行う(
|
102
|
+
#===当たり判定を行う(領域がピクセル単位で隣り合っている)
|
164
103
|
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
104
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
165
105
|
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
106
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
107
|
+
#返却値:: 領域が隣り合っていれば true を返す
|
108
|
+
def Collision.meet?(c1, pos1, c2, pos2)
|
109
|
+
l1 = pos1[0] + c1.rect[0]
|
110
|
+
t1 = pos1[1] + c1.rect[1]
|
170
111
|
r1 = l1 + c1.rect[2]
|
171
112
|
b1 = t1 + c1.rect[3]
|
172
|
-
l2 =
|
173
|
-
t2 =
|
113
|
+
l2 = pos2[0] + c2.rect[0]
|
114
|
+
t2 = pos2[1] + c2.rect[1]
|
174
115
|
r2 = l2 + c2.rect[2]
|
175
116
|
b2 = t2 + c2.rect[3]
|
176
117
|
v = 0
|
@@ -181,104 +122,231 @@ module Miyako
|
|
181
122
|
return v == 1
|
182
123
|
end
|
183
124
|
|
184
|
-
#===当たり判定を行う(
|
125
|
+
#===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
|
185
126
|
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
127
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
186
128
|
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
129
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
130
|
+
#返却値:: 領域が覆われていれば true を返す
|
131
|
+
def Collision.cover?(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 l1 >= l2 && r2 <= r1
|
142
|
+
v |= 2 if t1 >= t2 && b2 <= b1
|
143
|
+
v |= 4 if l2 >= l1 && r1 <= r2
|
144
|
+
v |= 8 if t2 >= t1 && b1 <= b2
|
145
|
+
return v & 3 == 3 || v & 12 == 12
|
146
|
+
end
|
147
|
+
|
148
|
+
#== インスタンスの内容を解放する
|
149
|
+
#返却値:: なし
|
150
|
+
def dispose
|
151
|
+
@rect = nil
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
#==円形当たり判定領域(サークルコリジョン)クラス
|
156
|
+
# 円形の当たり判定を実装する。
|
157
|
+
# コリジョンは中心位置と半径で構成され、円形当たり判定同士で衝突判定を行う
|
158
|
+
# コリジョンで使用する値は、実数での設定が可能
|
159
|
+
class CircleCollision
|
160
|
+
extend Forwardable
|
161
|
+
|
162
|
+
# コリジョンの中心点([x,y])
|
163
|
+
attr_reader :center
|
164
|
+
# コリジョンの半径
|
165
|
+
attr_reader :radius
|
166
|
+
# 移動時イベントブロック配列
|
167
|
+
|
168
|
+
#===コリジョンのインスタンスを作成する
|
169
|
+
# コリジョンの半径が0もしくはマイナスのとき例外が発生する
|
170
|
+
# 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。
|
171
|
+
# そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。
|
172
|
+
# circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。
|
173
|
+
#_center_:: コリジョンを設定する範囲
|
174
|
+
#_radius_:: コリジョンの半径
|
175
|
+
#_circum_:: 矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue
|
176
|
+
#返却値:: 作成されたコリジョン
|
177
|
+
def initialize(center, radius, circum = true)
|
178
|
+
raise MiyakoError, "illegal radius! #{radius}" if radius < Float::EPSILON
|
179
|
+
@center = Point.new(*(center.to_a[0..1]))
|
180
|
+
@radius = radius
|
181
|
+
if circum
|
182
|
+
rad = @radius.to_f / Math.sqrt(2.0)
|
183
|
+
@rect = Rect.new(@center[0]-rad, @center[1]-rad, rad*2.0, rad*2.0)
|
184
|
+
else
|
185
|
+
@rect = Rect.new(@center[0]-@radius, @center[1]-@radius, @radius*2.0, @radius*2.0)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
#===当たり判定間の距離を算出する
|
190
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
191
|
+
#_c2_:: 判定対象のコリジョンインスタンス
|
192
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
193
|
+
#返却値:: 1ピクセルでも重なっていれば true を返す
|
194
|
+
def interval(pos1, c2, pos2)
|
195
|
+
return CircleCollision.interval(self, pos1, c2, pos2)
|
196
|
+
end
|
197
|
+
|
198
|
+
#===当たり判定を行う(領域が重なっている)
|
199
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
200
|
+
#_c2_:: 判定対象のコリジョンインスタンス
|
201
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
187
202
|
#返却値:: 1ピクセルでも重なっていれば true を返す
|
188
|
-
def
|
189
|
-
|
190
|
-
f2 = Collision.collision_with_move?(c1, c2)
|
191
|
-
return !f1 & f2
|
203
|
+
def collision?(pos1, c2, pos2)
|
204
|
+
return CircleCollision.collision?(self, pos1, c2, pos2)
|
192
205
|
end
|
193
206
|
|
194
|
-
#===当たり判定を行う(
|
207
|
+
#===当たり判定を行う(領域がピクセル単位で隣り合っている)
|
208
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
209
|
+
#_c2_:: 判定対象のコリジョンインスタンス
|
210
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
211
|
+
#返却値:: 領域が隣り合っていれば true を返す
|
212
|
+
def meet?(pos1, c2, pos2)
|
213
|
+
return CircleCollision.meet?(self, pos1, c2, pos2)
|
214
|
+
end
|
215
|
+
|
216
|
+
#===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
|
217
|
+
#_pos1_:: 自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
218
|
+
#_c2_:: 判定対象のコリジョンインスタンス
|
219
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
220
|
+
#返却値:: 領域が覆われていれば true を返す
|
221
|
+
def cover?(pos1, c2, pos2)
|
222
|
+
return CircleCollision.cover?(self, pos1, c2, pos2)
|
223
|
+
end
|
224
|
+
|
225
|
+
#===当たり判定間の距離を算出する
|
226
|
+
# 2つの当たり判定がどの程度離れているかを算出する。
|
227
|
+
# 返ってくる値は、衝突していなければ正の実数、衝突していれば負の実数で返ってくる
|
195
228
|
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
229
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
196
230
|
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
231
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
232
|
+
#返却値:: 当たり判定間の距離
|
233
|
+
def CircleCollision.interval(c1, pos1, c2, pos2)
|
234
|
+
#2点間の距離を求める
|
235
|
+
d = Math.sqrt((((c1.center[0].to_f + pos1[0].to_f) - (c2.center[0].to_f + pos2[0].to_f)) ** 2) +
|
236
|
+
(((c1.center[1].to_f + pos1[1].to_f) - (c2.center[1].to_f + pos2[1].to_f)) ** 2))
|
237
|
+
#半径の和を求める
|
238
|
+
r = c1.radius.to_f + c2.radius.to_f
|
239
|
+
distance = d - r
|
240
|
+
return distance.abs < Float::EPSILON ? 0.0 : distance
|
241
|
+
end
|
242
|
+
|
243
|
+
#===当たり判定を行う(領域が重なっている)
|
244
|
+
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
245
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
246
|
+
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
247
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
197
248
|
#返却値:: 1ピクセルでも重なっていれば true を返す
|
198
|
-
def
|
199
|
-
|
200
|
-
|
201
|
-
|
249
|
+
def CircleCollision.collision?(c1, pos1, c2, pos2)
|
250
|
+
#2点間の距離を求める
|
251
|
+
d = (((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2) +
|
252
|
+
(((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2)
|
253
|
+
#半径の和を求める
|
254
|
+
r = (c1.radius + c2.radius) ** 2
|
255
|
+
return d <= r
|
256
|
+
end
|
257
|
+
|
258
|
+
#===当たり判定を行う(領域がピクセル単位で隣り合っている)
|
259
|
+
# 但し、実際の矩形範囲が偶数の時は性格に判定できない場合があるため注意
|
260
|
+
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
261
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
262
|
+
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
263
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
264
|
+
#返却値:: 領域が隣り合っていれば true を返す
|
265
|
+
def CircleCollision.meet?(c1, pos1, c2, pos2)
|
266
|
+
#2点間の距離を求める
|
267
|
+
d = (((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2) +
|
268
|
+
(((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2)
|
269
|
+
#半径の和を求める
|
270
|
+
r = (c1.radius + c2.radius) ** 2
|
271
|
+
return d == r
|
202
272
|
end
|
203
273
|
|
204
274
|
#===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
|
205
275
|
#_c1_:: 判定対象のコリジョンインスタンス(1)
|
276
|
+
#_pos1_:: c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
206
277
|
#_c2_:: 判定対象のコリジョンインスタンス(2)
|
278
|
+
#_pos2_:: c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)
|
207
279
|
#返却値:: 領域が覆われていれば true を返す
|
208
|
-
def
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
r2 = l2 + c2.rect[2]
|
216
|
-
b2 = t2 + c2.rect[3]
|
217
|
-
v = 0
|
218
|
-
v |= 1 if l1 <= l2 && r2 <= r1
|
219
|
-
v |= 2 if t1 <= t2 && b2 <= b1
|
220
|
-
v |= 4 if l2 <= l1 && r1 <= r2
|
221
|
-
v |= 8 if t2 <= t1 && b1 <= b2
|
222
|
-
return v == 3 || v == 12
|
280
|
+
def CircleCollision.cover?(c1, pos1, c2, pos2)
|
281
|
+
#2点間の距離を求める
|
282
|
+
d = ((c1.center[0] + pos1[0]) - (c2.center[0] + pos2[0])) ** 2 +
|
283
|
+
((c1.center[1] + pos1[1]) - (c2.center[1] + pos2[1])) ** 2
|
284
|
+
#半径の差分を求める
|
285
|
+
r = c1.radius ** 2 - 2 * (c1.radius * c2.radius) + c2.radius ** 2
|
286
|
+
return d <= r
|
223
287
|
end
|
224
288
|
|
225
|
-
|
226
|
-
#返却値::
|
289
|
+
#== インスタンスの内容を解放する
|
290
|
+
#返却値:: なし
|
227
291
|
def dispose
|
228
|
-
@
|
229
|
-
@pos = nil
|
230
|
-
@rect.clear
|
231
|
-
@rect = nil
|
232
|
-
@amount.clear
|
233
|
-
@amount = nil
|
234
|
-
@direction.clear
|
235
|
-
@direction = nil
|
292
|
+
@point = nil
|
236
293
|
end
|
237
294
|
end
|
238
295
|
|
239
296
|
#==コリジョン管理クラス
|
240
|
-
|
241
|
-
|
297
|
+
# 複数のコリジョンと元オブジェクトを配列の様に一括管理できる
|
298
|
+
# 当たり判定を一括処理することで高速化を図る
|
242
299
|
class Collisions
|
243
300
|
include Enumerable
|
244
301
|
extend Forwardable
|
245
302
|
|
246
303
|
#===コリジョンのインスタンスを作成する
|
304
|
+
# points引数の各要素は、以下の3つの条件のどれかに適合する必要がある。しない場合は例外が発生する
|
305
|
+
# 1)[x,y]の要素を持つ配列
|
306
|
+
# 2)Point構造体、Rect構造体、もしくはSquare構造体
|
307
|
+
# 3)x,yメソッドを持つ
|
247
308
|
#_collisions_:: コリジョンの配列。デフォルトは []
|
248
|
-
#
|
309
|
+
#_points_:: 位置情報の配列。デフォルトは []
|
249
310
|
#返却値:: 作成されたインスタンス
|
250
|
-
def initialize(collisions=[],
|
251
|
-
@collisions = Array.new(collisions).zip(
|
311
|
+
def initialize(collisions=[], points=[])
|
312
|
+
@collisions = Array.new(collisions).zip(points)
|
252
313
|
end
|
253
314
|
|
254
|
-
|
315
|
+
#===コリジョンと位置情報を追加する
|
316
|
+
# point引数は、以下の3つの条件のどれかに適合する必要がある。しない場合は例外が発生する
|
317
|
+
# 1)[x,y]の要素を持つ配列
|
318
|
+
# 2)Point構造体、Rect構造体、もしくはSquare構造体
|
319
|
+
# 3)x,yメソッドを持つ
|
255
320
|
#_collisions_:: コリジョン
|
256
|
-
#
|
321
|
+
#_point_:: 位置情報
|
257
322
|
#返却値:: 自分自身を返す
|
258
|
-
def add(collision,
|
259
|
-
@collisions << [collision,
|
323
|
+
def add(collision, point)
|
324
|
+
@collisions << [collision, point]
|
260
325
|
return self
|
261
326
|
end
|
262
327
|
|
263
|
-
|
328
|
+
#===インスタンスに、コリジョンと位置情報の集合を追加する
|
329
|
+
# points引数の各要素は、以下の3つの条件のどれかに適合する必要がある。しない場合は例外が発生する
|
330
|
+
# 1)[x,y]の要素を持つ配列
|
331
|
+
# 2)Point構造体、Rect構造体、もしくはSquare構造体
|
332
|
+
# 3)x,yメソッドを持つ
|
264
333
|
#_collisions_:: コリジョンの配列
|
265
|
-
#
|
334
|
+
#_points_:: 位置情報の配列
|
266
335
|
#返却値:: 自分自身を返す
|
267
|
-
def append(collisions,
|
268
|
-
@collisions.concat(collisions.zip(
|
336
|
+
def append(collisions, points)
|
337
|
+
@collisions.concat(collisions.zip(points))
|
269
338
|
return self
|
270
339
|
end
|
271
340
|
|
272
341
|
#===インデックス形式でのコリジョン・本体の取得
|
273
342
|
#_idx_:: 配列のインデックス番号
|
274
|
-
#返却値::
|
343
|
+
#返却値:: インデックスに対応したコリジョンと位置情報との対。
|
275
344
|
#インデックスが範囲外の時はnilが返る
|
276
345
|
def [](idx)
|
277
346
|
return @collisions[idx]
|
278
347
|
end
|
279
348
|
|
280
349
|
#===コリジョン・本体の削除
|
281
|
-
#対応したインデックスのコリジョンと
|
282
350
|
#_idx_:: 配列のインデックス番号
|
283
351
|
#返却値:: 削除したコリジョンと本体との対
|
284
352
|
#インデックスが範囲外の時はnilが返る
|
@@ -295,8 +363,8 @@ module Miyako
|
|
295
363
|
end
|
296
364
|
|
297
365
|
#===タッピングを行う
|
298
|
-
|
299
|
-
|
366
|
+
# ブロックを渡すことにより、タッピングを行う
|
367
|
+
# ブロック内の引数は、|コリジョン,本体|の2が渡される
|
300
368
|
#返却値:: 自分自身を返す
|
301
369
|
def each
|
302
370
|
@collisions.each{|cb| yield cb[0], cb[1] }
|
@@ -304,138 +372,86 @@ module Miyako
|
|
304
372
|
end
|
305
373
|
|
306
374
|
#===タッピングを行う
|
307
|
-
|
308
|
-
|
375
|
+
# ブロックを渡すことにより、タッピングを行う
|
376
|
+
# ブロック内の引数は、|コリジョン,本体|の2が渡される
|
309
377
|
#_idx_:: 配列のインデックス
|
310
378
|
#返却値:: 自分自身を返す
|
311
379
|
def tap(idx)
|
312
380
|
yield @collisions[idx][0], @collisions[idx][1]
|
313
381
|
return self
|
314
382
|
end
|
315
|
-
|
316
|
-
#===すべてのコリジョンの方向を転換する
|
317
|
-
#_dx_:: 変換する方向(x軸方向、-1,0,1の3種類)
|
318
|
-
#_dy_:: 変換する方向(y軸方向、-1,0,1の3種類)
|
319
|
-
#返却値:: 自分自身を返す
|
320
|
-
def turn(dx, dy)
|
321
|
-
@collisions.each{|cs| cs.turn(dx, dy) }
|
322
|
-
return self
|
323
|
-
end
|
324
|
-
|
325
|
-
#===すべてのコリジョンの移動量を変更する
|
326
|
-
#_mx_:: 変更する移動量(x軸方向)
|
327
|
-
#_my_:: 変更する移動量(y軸方向)
|
328
|
-
#返却値:: 自分自身を返す
|
329
|
-
def adjust(mx, my)
|
330
|
-
@collisions.each{|cs| cs.adjust(mx, my) }
|
331
|
-
return self
|
332
|
-
end
|
333
383
|
|
334
|
-
#===当たり判定を行う(
|
335
|
-
|
336
|
-
|
384
|
+
#===当たり判定を行う(配列のどれかの領域が重なっている)
|
385
|
+
# 重なったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
|
386
|
+
# 重なったコリジョンが無い場合はnilを返す
|
337
387
|
#_c_:: 判定対象のコリジョンインスタンス
|
388
|
+
#_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
|
338
389
|
#返却値:: コリジョンと本体の対。
|
339
|
-
def collision?(c)
|
340
|
-
return @collisions.detect{|cc| c.collision?(cc[0])}
|
390
|
+
def collision?(c, pos)
|
391
|
+
return @collisions.detect{|cc| c.collision?(pos, cc[0], cc[1])}
|
341
392
|
end
|
342
393
|
|
343
|
-
#===当たり判定を行う(
|
344
|
-
|
345
|
-
|
394
|
+
#===当たり判定を行う(配列のどれかの領域がピクセル単位で隣り合っている)
|
395
|
+
# 隣り合ったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
|
396
|
+
# 隣り合ったコリジョンが無い場合はnilを返す
|
346
397
|
#_c_:: 判定対象のコリジョンインスタンス
|
347
|
-
|
348
|
-
#返却値::
|
349
|
-
def meet?(c)
|
350
|
-
return @collisions.detect{|cc| c.meet?(cc[0])}
|
351
|
-
end
|
352
|
-
|
353
|
-
#===当たり判定を行う(移動後に領域が重なっている(移動前は重なっていない))
|
354
|
-
#判定に引っかかったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
|
355
|
-
#当たり判定に引っかかったコリジョンが無い場合はnilを返す
|
356
|
-
#_c_:: 判定対象のコリジョンインスタンス
|
357
|
-
#返却値:: コリジョンと本体の対。
|
358
|
-
#返却値:: 1ピクセルでも重なっていれば true を返す
|
359
|
-
def into?(c)
|
360
|
-
return @collisions.detect{|cc| c.into?(cc[0])}
|
361
|
-
end
|
362
|
-
|
363
|
-
#===当たり判定を行う(移動後に領域が離れている(移動前は重なっている))
|
364
|
-
#判定に引っかかったコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
|
365
|
-
#当たり判定に引っかかったコリジョンが無い場合はnilを返す
|
366
|
-
#_c_:: 判定対象のコリジョンインスタンス
|
367
|
-
#返却値:: コリジョンと本体の対。
|
368
|
-
#返却値:: 1ピクセルでも重なっていれば true を返す
|
369
|
-
def out?(c)
|
370
|
-
return @collisions.detect{|cc| c.out?(cc[0])}
|
398
|
+
#_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
|
399
|
+
#返却値:: 隣り合っていれば true を返す
|
400
|
+
def meet?(c, pos)
|
401
|
+
return @collisions.detect{|cc| c.meet?(pos, cc[0], cc[1])}
|
371
402
|
end
|
372
403
|
|
373
404
|
#===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
|
374
|
-
|
375
|
-
|
405
|
+
# 覆われたコリジョンが一つでもあれば、最初に引っかかったコリジョンを返す
|
406
|
+
# 覆われたコリジョンが無い場合はnilを返す
|
376
407
|
#_c_:: 判定対象のコリジョンインスタンス
|
377
|
-
|
408
|
+
#_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
|
378
409
|
#返却値:: 領域が覆われていれば true を返す
|
379
|
-
def cover?(c)
|
380
|
-
return @collisions.detect{|cc| c.cover?(cc[0])}
|
410
|
+
def cover?(c, pos)
|
411
|
+
return @collisions.detect{|cc| c.cover?(pos, cc[0], cc[1])}
|
381
412
|
end
|
382
413
|
|
383
414
|
#===当たり判定を行う(領域が重なっている)
|
384
|
-
|
385
|
-
|
386
|
-
#_c_:: 判定対象のコリジョンインスタンス
|
387
|
-
#返却値:: コリジョンと本体の対の配列。
|
388
|
-
def collision_all?(c)
|
389
|
-
return @collisions.select{|cc| c.collision?(cc[0])}
|
390
|
-
end
|
391
|
-
|
392
|
-
#===当たり判定を行う(領域が当たっている(重なっていない))
|
393
|
-
#判定に引っかかったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
|
394
|
-
#当たり判定に引っかかったコリジョンが無い場合はnilを返す
|
395
|
-
#_c_:: 判定対象のコリジョンインスタンス
|
396
|
-
#返却値:: コリジョンと本体の対の配列。
|
397
|
-
def meet_all?(c)
|
398
|
-
return @collisions.select{|cc| c.meet?(cc[0])}
|
399
|
-
end
|
400
|
-
|
401
|
-
#===当たり判定を行う(移動後に領域が重なっている(移動前は重なっていない))
|
402
|
-
#判定に引っかかったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
|
403
|
-
#当たり判定に引っかかったコリジョンが無い場合はnilを返す
|
415
|
+
# 重なったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
|
416
|
+
# 重なったコリジョンが無い場合はnilを返す
|
404
417
|
#_c_:: 判定対象のコリジョンインスタンス
|
418
|
+
#_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
|
405
419
|
#返却値:: コリジョンと本体の対の配列。
|
406
|
-
def
|
407
|
-
return @collisions.select{|cc| c.
|
420
|
+
def collision_all?(c, pos)
|
421
|
+
return @collisions.select{|cc| c.collision?(pos, cc[0], cc[1])}
|
408
422
|
end
|
409
423
|
|
410
|
-
#===当たり判定を行う(
|
411
|
-
|
412
|
-
|
424
|
+
#===当たり判定を行う(領域がピクセル単位で隣り合っている)
|
425
|
+
# 隣り合ったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
|
426
|
+
# 隣り合ったコリジョンが無い場合はnilを返す
|
413
427
|
#_c_:: 判定対象のコリジョンインスタンス
|
428
|
+
#_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
|
414
429
|
#返却値:: コリジョンと本体の対の配列。
|
415
|
-
def
|
416
|
-
return @collisions.select{|cc| c.
|
430
|
+
def meet_all?(c, pos)
|
431
|
+
return @collisions.select{|cc| c.meet?(pos, cc[0], cc[1])}
|
417
432
|
end
|
418
433
|
|
419
434
|
#===当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))
|
420
|
-
|
421
|
-
|
435
|
+
# 覆われたコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
|
436
|
+
# 覆われたコリジョンが無い場合はnilを返す
|
422
437
|
#_c_:: 判定対象のコリジョンインスタンス
|
438
|
+
#_pos_:: cの位置(Point/Rect/Square構造体、もしくは2要素の配列)
|
423
439
|
#返却値:: コリジョンと本体の対の配列。
|
424
|
-
def cover_all?(c)
|
425
|
-
return @collisions.select{|cc| c.cover?(cc[0])}
|
440
|
+
def cover_all?(c, pos)
|
441
|
+
return @collisions.select{|cc| c.cover?(pos, cc[0], cc[1])}
|
426
442
|
end
|
427
443
|
|
428
444
|
#===インデックス形式でのコリジョン・本体の取得
|
429
|
-
|
430
|
-
|
445
|
+
# 判定に引っかかったコリジョンが一つでもあれば、すべてのコリジョンの配列を返す
|
446
|
+
# 当たり判定に引っかかったコリジョンが無い場合はnilを返す
|
431
447
|
#_idx_:: 配列のインデックス番号
|
432
448
|
#返却値:: インデックスに対応したコリジョンと本体との対
|
433
449
|
def [](idx)
|
434
450
|
return [@collisions[idx], @bodies[idx]]
|
435
451
|
end
|
436
452
|
|
437
|
-
|
438
|
-
#返却値::
|
453
|
+
#===オブジェクトを解放する
|
454
|
+
#返却値:: なし
|
439
455
|
def dispose
|
440
456
|
@collisions.clear
|
441
457
|
@collisions = nil
|