KoBeWi

Ruby collision classes

Oct 12th, 2013
451
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class Collision_Box
  2.   attr_reader :x,:y,:w,:h,:a,:vectors
  3.   attr_writer :w,:h
  4.   def initialize(x,y,w,h,a=0)
  5.     @x,@y,@w,@h,@a=x,y,w,h,(180-a)
  6.     set_vectors
  7.   end
  8.    
  9.   def collides?(col)
  10.     return if col==self
  11.    
  12.     if col.class==Collision_Box
  13.       4.times{|i|
  14.         if i==0
  15.           axisx=@vectors[2]-@vectors[0]
  16.           axisy=@vectors[3]-@vectors[1]
  17.         elsif i==1
  18.           axisx=@vectors[2]-@vectors[4]
  19.           axisy=@vectors[3]-@vectors[5]
  20.         elsif i==2
  21.           axisx=col.vectors[0]-col.vectors[6]
  22.           axisy=col.vectors[1]-col.vectors[7]
  23.         elsif i==3
  24.           axisx=col.vectors[0]-col.vectors[2]
  25.           axisy=col.vectors[1]-col.vectors[3]
  26.         end
  27.        
  28.         values1=[]
  29.         values2=[]
  30.         4.times{|p|
  31.         values1 << ((@vectors[p*2] * axisx + @vectors[p*2+1] * axisy) / (axisx ** 2 + axisy ** 2)) * axisx ** 2 + ((@vectors[p*2] * axisx + @vectors[p*2+1] * axisy) / (axisx ** 2 + axisy ** 2)) * axisy ** 2
  32.         values2 << ((col.vectors[p*2] * axisx + col.vectors[p*2+1] * axisy) / (axisx ** 2 + axisy ** 2))* axisx ** 2 + ((col.vectors[p*2] * axisx + col.vectors[p*2+1] * axisy) / (axisx ** 2 + axisy ** 2))* axisy ** 2
  33.         }
  34.        
  35.         return if not values2.min<=values1.max && values2.max>=values1.min
  36.       }
  37.       true
  38.     elsif col.class== Collision_Ball
  39.       a=Math::PI*(@a/180.0)
  40.       x = Math.cos(a) * (col.x - @x) - Math.sin(a) * (col.y - @y) + @x
  41.       y = Math.sin(a) * (col.x - @x) + Math.cos(a) * (col.y - @y) + @y
  42.      
  43.       if x < @x - @w/2
  44.         cx = @x - @w/2
  45.       elsif x > @x + @w/2
  46.         cx = @x + @w/2
  47.       else
  48.         cx = x
  49.       end
  50.      
  51.       if y < @y - @h/2
  52.         cy = @y - @h/2
  53.       elsif y > @y + @h/2
  54.         cy = @y + @h/2
  55.       else
  56.         cy = y
  57.       end
  58.      
  59.       distance(x,y,cx,cy)<col.r
  60.     elsif col.class==Collision_Group
  61.       col.collides?(self)
  62.     end
  63.   end
  64.  
  65.   def set(x,y,a=@a)
  66.     @x,@y,@a=x,y,a
  67.     set_vectors
  68.   end
  69.  
  70.   def move(x=0,y=0,a=0)
  71.     @x+=x
  72.     @y+=y
  73.     @a-=a
  74.     set_vectors
  75.   end
  76.  
  77.   def set_vectors
  78.     d=Math.sqrt(@w**2+@h**2)/2
  79.     a=Math::PI*(angle(0,0,@w,@h)/180.0)
  80.     a1=Math::PI*(@a/180.0)
  81.     @vectors=[@x+Math.sin(a1-a)*d, @y+Math.cos(a1-a)*d, @x+Math.sin(a1+a)*d, @y+Math.cos(a1+a)*d, @x+Math.sin(a1+Math::PI-a)*d, @y+Math.cos(a1+Math::PI-a)*d, @x+Math.sin(a1+Math::PI+a)*d, @y+Math.cos(a1+Math::PI+a)*d]
  82.   end
  83. end
  84.  
  85. class Collision_Ball
  86.   attr_reader :x,:y,:r
  87.   attr_writer :r
  88.   def initialize(x,y,r)
  89.     @x,@y,@r=x,y,r
  90.   end
  91.  
  92.   def collides?(col)
  93.     return if col==self
  94.     if col.class==Collision_Box
  95.       a=Math::PI*(col.a/180.0)
  96.       x = Math.cos(a) * (@x - col.x) - Math.sin(a) * (@y - col.y) + col.x
  97.       y = Math.sin(a) * (@x - col.x) + Math.cos(a) * (@y - col.y) + col.y
  98.      
  99.       if x < col.x - col.w/2
  100.         cx = col.x - col.w/2
  101.       elsif x > col.x + col.w/2
  102.         cx = col.x + col.w/2
  103.       else
  104.         cx = x
  105.       end
  106.      
  107.       if y < col.y - col.h/2
  108.         cy = col.y - col.h/2
  109.       elsif y > col.y + col.h/2
  110.         cy = col.y + col.h/2
  111.       else
  112.         cy = y
  113.       end
  114.      
  115.       distance(x,y,cx,cy)<@r
  116.     elsif col.class== Collision_Ball
  117.       distance(@x,@y,col.x,col.y)<@r+col.r
  118.     elsif col.class==Collision_Group
  119.       col.collides?(self)
  120.     end
  121.   end
  122.  
  123.   def set(x,y)
  124.     @x,@y=x,y
  125.   end
  126.  
  127.   def move(x=0,y=0)
  128.     @x+=x
  129.     @y+=y
  130.   end
  131. end
  132.  
  133. class Collision_Group
  134.   attr_reader :x,:y,:a,:c
  135.   def initialize(x,y,a,*c)
  136.     @x,@y,@a,@c=x,y,(180-a),c
  137.   end
  138.  
  139.   def collides?(col)
  140.     return if col==self
  141.     if col.class==Collision_Group
  142.       return true if @c.find{|c| col.find{|c2| c2.collides?(c)}}
  143.     else
  144.       return true if @c.find{|c| c.collides?(col)}
  145.     end
  146.   end
  147.  
  148.   def set(x,y,a=@a)
  149.     @c.each{|c| c.class==Collision_Ball ? c.move(x-@x,y-@y) : c.move(x-@x,y-@y,a-@a)}
  150.     @x,@y=x,y
  151.    
  152.     @c.each{|c| dist=distance(@x,@y,c.x,c.y) ; rot=angle(@x,@y,c.x,c.y)
  153.       c.set(@x+offset_x(rot+(a-@a),dist),@y+offset_y(rot+(a-@a),dist))
  154.     }
  155.     @a=a
  156.   end
  157.  
  158.   def move(x=0,y=0,a=0)
  159.     @c.each{|c| c.class==Collision_Ball ? c.move(x,y) : c.move(x,y,a)}
  160.     @x+=x
  161.     @y+=y
  162.     @a+=a
  163.    
  164.     @c.each{|c| dist=distance(@x,@y,c.x,c.y) ; rot=angle(@x,@y,c.x,c.y)
  165.       c.set(@x+offset_x(rot+a,dist),@y+offset_y(rot+a,dist))}
  166.   end
  167. end
RAW Paste Data