SHARE
TWEET

Ruby collision classes

KoBeWi Oct 12th, 2013 (edited) 357 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top