#encoding:utf-8
#==============================================================================
# ■ Sprite_精灵像素碰撞v2.0 By_QQEat
#------------------------------------------------------------------------------
#
# 说明:检测精灵像素碰撞
# 注:
# 1)、支持 src_rect、mirror、ox、oy 等属性。
# 不支持 angle、zoom_x、zoom_y 等属性。
# 2)、两个精灵需在同一端口下。
#
# 使用方法:
# s1.pixel_coll?(s2)
#
# 更新日志:
# 1)、支持 mirror 属性。
# 2)、修复精灵src_rect属性超出检测异常的bug。
# 3)、修复检测相交矩形的错误。
# 4)、效率优化。
#
#==============================================================================
class Sprite
#--------------------------------------------------------------------------
# ● 像素碰撞
#--------------------------------------------------------------------------
def pixel_coll?(o2)
o1 = self
# 取位图宽高
temp = o1.bitmap
o1_bw = temp.width
o1_bh = temp.height
temp = o2.bitmap
o2_bw = temp.width
o2_bh = temp.height
# 取精灵x/y
o1_x = o1.x
o1_y = o1.y
o2_x = o2.x
o2_y = o2.y
# 取精灵ox/oy
o1_ox = o1.ox
o1_oy = o1.oy
o2_ox = o2.ox
o2_oy = o2.oy
# src坐标
temp = o1.src_rect
o1_sx = temp.x
o1_sy = temp.y
temp = o2.src_rect
o2_sx = temp.x
o2_sy = temp.y
# src宽高
temp = o1.src_rect
o1_w = temp.width
o1_h = temp.height
temp = o2.src_rect
o2_w = temp.width
o2_h = temp.height
# 取是否左右反转
o1_mirror = o1.mirror
o2_mirror = o2.mirror
# src_rect 宽高为0
return false if o1_w == 0 or o1_h == 0 or o2_w == 0 or o2_h == 0
# src_rect 坐标超出原图
return false if o1_sx >= o1_bw or o1_sy >= o1_bh
return false if o2_sx >= o2_bw or o2_sy >= o2_bh
# src_rect 宽高超出位图修复
o1_w = o1_bw - o1_sx if o1_w > o1_bw - o1_sx
o1_h = o1_bh - o1_sy if o1_h > o1_bh - o1_sy
o2_w = o2_bw - o2_sx if o2_w > o2_bw - o2_sx
o2_h = o2_bh - o2_sy if o2_h > o2_bh - o2_sy
# 矩形相交检测
x_coll = (o1_x + o1_w - o1_ox > o2_x - o2_ox and o1_x - o1_ox < o2_x + o2_w - o2_ox)
y_coll = (o1_y + o1_h - o1_oy > o2_y - o2_oy and o1_y - o1_oy < o2_y + o2_h - o2_oy)
if x_coll and y_coll
t1_x = o1_x - o1_ox
t2_x = o2_x - o2_ox
t1_r = t1_x + o1_w
t2_r = t2_x + o2_w
if t1_x < t2_x
if t1_r > t2_r
w = o2_w
x1 = t2_x - t1_x
else
w = (t1_r - t2_x).abs
x1 = o1_w - w
end
x2 = 0
x1 = o1_w - x1 if o1_mirror
x2 = o2_w if o2_mirror
else
if t1_r < t2_r
w = o1_w
x2 = t1_x - t2_x
else
w = (t2_r - t1_x).abs
x2 = o2_w - w
end
x1 = 0
x1 = o1_w if o1_mirror
x2 = o2_w - x2 if o2_mirror
end
t1_y = o1_y - o1_oy
t2_y = o2_y - o2_oy
t1_d = t1_y + o1_h
t2_d = t2_y + o2_h
if t1_y < t2_y
if t1_d > t2_d
h = o2_h
y1 = t2_y - t1_y
else
h = (t1_d - t2_y).abs
y1 = o1_h - h
end
y2 = 0
else
if t1_d < t2_d
h = o1_h
y2 = t1_y - t2_y
else
h = (t2_d - t1_y).abs
y2 = o2_h - h
end
y1 = 0
end
# p "#{x1},#{y1},#{x2},#{y2},#{w},#{h}"
w.times do |x|
h.times do |y|
if o1.bitmap.get_pixel(o1_sx+x1+(o1_mirror ? -x : x), o1_sy+y1+y).alpha != 0 and
o2.bitmap.get_pixel(o2_sx+x2+(o2_mirror ? -x : x), o2_sy+y2+y).alpha != 0
return true
end
end
end
end
return false
end
end