Class: Miyako::Collision

Inherits:
Object show all
Defined in:
lib/Miyako/API/collision.rb

Overview

矩形当たり判定領域(コリジョン)クラス

コリジョンの範囲は、元データ(スプライト等)の左上端をとして考案する コリジョンで使用する値は、実数での設定が可能

Direct Known Subclasses

CollisionEx

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rect, circum = true) ⇒ Collision

コリジョンのインスタンスを作成する

幅・高さが0以下のときは例外が発生する 内部では、矩形当たり判定相手の時でも対応できるように矩形情報に変換して同時に持っている。 そのとき、引数circumがtrueのときは、円を矩形の外接円と認識して、内部の矩形(正方形)の長さを算出する。 circumがfalseのときは、円を矩形の内接円と認識して、内部の矩形(正方形)の長さを算出する。

rect

コリジョンを設定する範囲

circum

矩形当たり判定とみなす時、円を外接円とするときはtrueを設定する。デフォルトはtrue

返却値

作成されたコリジョン

Raises:



45
46
47
48
49
50
51
52
53
54
# File 'lib/Miyako/API/collision.rb', line 45

def initialize(rect, circum = true)
  @rect = Rect.new(*(rect.to_a[0..3]))
  raise MiyakoValueError, "Illegal width! #{@rect[2]}" if @rect[2] < Float::EPSILON
  raise MiyakoValueError, "Illegal height! #{@rect[3]}" if @rect[3] < Float::EPSILON
  w = @rect[2].to_f
  h = @rect[2].to_f
  @center = Point.new(@rect[0].to_f + w / 2.0, @rect[1].to_f + h / 2.0)
  @radius = circum ? Math.sqrt(w ** 2 + h ** 2) / 2.0 : [w, h].min / 2.0
  @body = nil
end

Instance Attribute Details

#bodyObject (readonly)

関連づけられたインスタンス



29
30
31
# File 'lib/Miyako/API/collision.rb', line 29

def body
  @body
end

#centerObject (readonly)



33
34
35
# File 'lib/Miyako/API/collision.rb', line 33

def center
  @center
end

#radiusObject (readonly)

コリジョンの半径



35
36
37
# File 'lib/Miyako/API/collision.rb', line 35

def radius
  @radius
end

#rectObject (readonly)



31
32
33
# File 'lib/Miyako/API/collision.rb', line 31

def rect
  @rect
end

Class Method Details

.collision?(c1, pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(領域が重なっている)

c1

判定対象のコリジョンインスタンス(1)

pos1

c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス(2)

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

1ピクセルでも重なっていれば true を返す

Returns:

  • (Boolean)


132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/Miyako/API/collision.rb', line 132

def Collision.collision?(c1, pos1, c2, pos2)
  l1 = pos1[0] + c1.rect[0]
  t1 = pos1[1] + c1.rect[1]
  r1 = l1 + c1.rect[2] - 1
  b1 = t1 + c1.rect[3] - 1
  l2 = pos2[0] + c2.rect[0]
  t2 = pos2[1] + c2.rect[1]
  r2 = l2 + c2.rect[2] - 1
  b2 = t2 + c2.rect[3] - 1
  v =  0
  v |= 1 if l1 <= l2 && l2 <= r1
  v |= 1 if l1 <= r2 && r2 <= r1
  v |= 2 if t1 <= t2 && t2 <= b1
  v |= 2 if t1 <= b2 && b2 <= b1
  return v == 3
end

.cover?(c1, pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))

c1

判定対象のコリジョンインスタンス(1)

pos1

c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス(2)

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が覆われていれば true を返す

Returns:

  • (Boolean)


178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/Miyako/API/collision.rb', line 178

def Collision.cover?(c1, pos1, c2, pos2)
  l1 = pos1[0] + c1.rect[0]
  t1 = pos1[1] + c1.rect[1]
  r1 = l1 + c1.rect[2]
  b1 = t1 + c1.rect[3]
  l2 = pos2[0] + c2.rect[0]
  t2 = pos2[1] + c2.rect[1]
  r2 = l2 + c2.rect[2]
  b2 = t2 + c2.rect[3]
  v =  0
  v |= 1 if l1 >= l2 && r1 <= r2
  v |= 2 if t1 >= t2 && b1 <= b2
  v |= 4 if l2 >= l1 && r2 <= r1
  v |= 8 if t2 >= t1 && b2 <= b1
  return v & 3 == 3 || v & 12 == 12
end

.covered?(c1, pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(c1がc2に覆われている)

c1

判定対象のコリジョンインスタンス(1)

pos1

c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス(2)

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が覆われていれば true を返す

Returns:

  • (Boolean)


222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/Miyako/API/collision.rb', line 222

def Collision.covered?(c1, pos1, c2, pos2)
  l1 = pos1[0] + c1.rect[0]
  t1 = pos1[1] + c1.rect[1]
  r1 = l1 + c1.rect[2]
  b1 = t1 + c1.rect[3]
  l2 = pos2[0] + c2.rect[0]
  t2 = pos2[1] + c2.rect[1]
  r2 = l2 + c2.rect[2]
  b2 = t2 + c2.rect[3]
  v =  0
  v |= 1 if l1 >= l2 && r1 <= r2
  v |= 2 if t1 >= t2 && b1 <= b2
  return v & 3 == 3
end

.covers?(c1, pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(c1がc2を覆っている)

c1

判定対象のコリジョンインスタンス(1)

pos1

c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス(2)

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が覆われていれば true を返す

Returns:

  • (Boolean)


201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/Miyako/API/collision.rb', line 201

def Collision.covers?(c1, pos1, c2, pos2)
  l1 = pos1[0] + c1.rect[0]
  t1 = pos1[1] + c1.rect[1]
  r1 = l1 + c1.rect[2]
  b1 = t1 + c1.rect[3]
  l2 = pos2[0] + c2.rect[0]
  t2 = pos2[1] + c2.rect[1]
  r2 = l2 + c2.rect[2]
  b2 = t2 + c2.rect[3]
  v =  0
  v |= 1 if l2 >= l1 && r2 <= r1
  v |= 2 if t2 >= t1 && b2 <= b1
  return v & 3 == 3
end

.meet?(c1, pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(領域がピクセル単位で隣り合っている)

c1

判定対象のコリジョンインスタンス(1)

pos1

c1の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス(2)

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が隣り合っていれば true を返す

Returns:

  • (Boolean)


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/Miyako/API/collision.rb', line 155

def Collision.meet?(c1, pos1, c2, pos2)
  l1 = pos1[0] + c1.rect[0]
  t1 = pos1[1] + c1.rect[1]
  r1 = l1 + c1.rect[2]
  b1 = t1 + c1.rect[3]
  l2 = pos2[0] + c2.rect[0]
  t2 = pos2[1] + c2.rect[1]
  r2 = l2 + c2.rect[2]
  b2 = t2 + c2.rect[3]
  v =  0
  v |= 1 if r1 == l2
  v |= 1 if b1 == t2
  v |= 1 if l1 == r2
  v |= 1 if t1 == b2
  return v == 1
end

Instance Method Details

#bind(obj) ⇒ Object

当たり判定とインスタンスを関連づける

当たり判定と、それをもとにしたインスタンスとの関連がわかりにくいときに使用する 引数にcollision=メソッドの有無を調査して、持っているときは、collision=メソッドを 自分自身を引数にして呼び出す(collision=メソッドを持っているのは現状でSpriteクラスのみ)

obj

関連づける元のインスタンス

返却値

自分自身を帰す



67
68
69
70
71
# File 'lib/Miyako/API/collision.rb', line 67

def bind(obj)
  @body = obj
  @body.collision = self if @body.class.method_defined?(:collision=)
  return self
end

#collision?(pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(領域が重なっている)

pos1

自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

1ピクセルでも重なっていれば true を返す

Returns:

  • (Boolean)


86
87
88
# File 'lib/Miyako/API/collision.rb', line 86

def collision?(pos1, c2, pos2)
  return Collision.collision?(self, pos1, c2, pos2)
end

#cover?(pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(どちらかの領域がもう一方にすっぽり覆われている))

pos1

自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が覆われていれば true を返す

Returns:

  • (Boolean)


104
105
106
# File 'lib/Miyako/API/collision.rb', line 104

def cover?(pos1, c2, pos2)
  return Collision.cover?(self, pos1, c2, pos2)
end

#covered?(pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(レシーバがc2に覆われている)

pos1

自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が覆われていれば true を返す

Returns:

  • (Boolean)


122
123
124
# File 'lib/Miyako/API/collision.rb', line 122

def covered?(pos1, c2, pos2)
  return Collision.covered?(self, pos1, c2, pos2)
end

#covers?(pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(レシーバがc2を覆っている)

pos1

自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が覆われていれば true を返す

Returns:

  • (Boolean)


113
114
115
# File 'lib/Miyako/API/collision.rb', line 113

def covers?(pos1, c2, pos2)
  return Collision.covers?(self, pos1, c2, pos2)
end

#disposeObject

インスタンスの内容を解放する

返却値

なし



239
240
241
# File 'lib/Miyako/API/collision.rb', line 239

def dispose
  @rect = nil
end

#initialize_copy(obj) ⇒ Object

:nodoc:



56
57
58
59
# File 'lib/Miyako/API/collision.rb', line 56

def initialize_copy(obj) #:nodoc:
  @rect = @rect.dup
  @center = @center.dup
end

#meet?(pos1, c2, pos2) ⇒ Boolean

当たり判定を行う(領域がピクセル単位で隣り合っている)

pos1

自分自身の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

c2

判定対象のコリジョンインスタンス

pos2

c2の位置(Point/Rect/Square構造体、2要素以上の配列、もしくはx,yメソッドを持つインスタンス)

返却値

領域が隣り合っていれば true を返す

Returns:

  • (Boolean)


95
96
97
# File 'lib/Miyako/API/collision.rb', line 95

def meet?(pos1, c2, pos2)
  return Collision.meet?(self, pos1, c2, pos2)
end

#to_ex(pos = [0,0]) ⇒ Object

CollisionExクラスのインスタンスを生成する

自分自身に位置情報を渡してCollisionExクラスのインスタンスを生成する

pos

CollisionEx生成時に渡す位置。省略時は

返却値

CollisionEx構造体



77
78
79
# File 'lib/Miyako/API/collision.rb', line 77

def to_ex(pos=[0,0])
  CollisionEx.new(@rect, pos)
end