' From the book '2d game collision detection' ' line vs oriented rectangle collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' Here the line vs oriented rectangle collision Function line_oriented_rectangle_collide:Bool( l:line, r:orientedrectangle) Local lr:rectangle lr = New rectangle( New vector2d(0,0), multiply_vector(r.halfextend,2)) Local l1:line = New line( New vector2d(0,0), New vector2d(0,0)) l1.base = subtract_vector(l.base,r.center) l1.base = rotate_vector(l1.base,-r.rotation) l1.base = add_vector(l1.base,r.halfextend) l1.direction = rotate_vector(l.direction,-r.rotation) Return line_rectangle_collide(l1,lr) End Function ' The rectangle vs Line Collision ' needed for line vs oriented rectangle collion Function line_rectangle_collide:Bool(l:line,r:rectangle) Local n:vector2d = rotate_vector_90(l.direction) Local dp1:Float,dp2:Float Local dp3:Float,dp4:Float Local c1:vector2d = r.origin Local c2:vector2d = add_vector(c1,r.size) Local c3:vector2d = New vector2d(c2.x,c1.y) Local c4:vector2d = New vector2d(c1.x,c2.y) c1 = subtract_vector(c1,l.base) c2 = subtract_vector(c2,l.base) c3 = subtract_vector(c3,l.base) c4 = subtract_vector(c4,l.base) dp1 = dot_product(n,c1) dp2 = dot_product(n,c2) dp3 = dot_product(n,c3) dp4 = dot_product(n,c4) Return (dp1 * dp2 <= 0) Or (dp2 * dp3 <= 0) Or (dp3 * dp4 <= 0) End Function ' ' helper functions ' Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function Function rotate_vector_90:vector2d(v:vector2d) Local r:vector2d = New vector2d() r.x = -v.y r.y = v.x Return r End Function Function multiply_vector:vector2d(v:vector2d,scalar:Float) Local r:vector2d = New vector2d() r.x = v.x * scalar r.y = v.y * scalar Return r End Function ' Here is the function that rotates a vector. It returns the ' new rotated vector. ' Function rotate_vector:vector2d(v:vector2d,degrees:Float) Local r:vector2d = New vector2d() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class Class line ' base is a vector which holds the origin ' of the line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method Method draw() DrawLine base.x,base.y,direction.x,direction.y End Method End Class Class orientedrectangle Field center:vector2d Field halfextend:vector2d Field rotation:Float Method New(center:vector2d,halfextend:vector2d,rotation:Float) Self.center = center Self.halfextend = halfextend Self.rotation = rotation End Method Method draw() Local v1:vector2d,v2:vector2d,v3:vector2d,v4:vector2d 'topside v1 = New vector2d(-halfextend.x,-halfextend.y) v2 = New vector2d(halfextend.x,-halfextend.y) v1 = rotate_vector(v1,rotation) v2 = rotate_vector(v2,rotation) v1.x += center.x v1.y += center.y v2.x += center.x v2.y += center.y ' rightside v3 = New vector2d(halfextend.x,halfextend.y) v3 = rotate_vector(v3,rotation) v3.x += center.x v3.y += center.y ' bottom side v4 = New vector2d(-halfextend.x,halfextend.y) v4 = rotate_vector(v4,rotation) v4.x += center.x v4.y += center.y DrawLine v1.x,v1.y,v2.x,v2.y DrawLine v2.x,v2.y,v3.x,v3.y DrawLine v3.x,v3.y,v4.x,v4.y DrawLine v4.x,v4.y,v1.x,v1.y End Method Function rotate_vector:vector2d(v:vector2d,degrees:Float) Local r:vector2d = New vector2d() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Field angle:Float=0 Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() angle+=1 If angle > 360 Then angle=0 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 'set up the line Local line1:line = New line( New vector2d(0,0), New vector2d(MouseX,MouseY)) 'set up the oriented rectangle (base, halfextend(size),angle) Local orect1:orientedrectangle orect1 = New orientedrectangle( New vector2d(320,200), New vector2d(100,50), angle) ' Here we test for collision If col.line_oriented_rectangle_collide(line1,orect1) DrawText "Line vs Oriented Rectangle Collision",0,0 Else DrawText "Line vs Oriented Rectangle NO Collision",0,0 End If ' Here we draw the line and oriented ' rectangle. line1.draw orect1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Artificial intelligence/templates/examples/rts/rpg/strategy ect. in MonkeyX/CerberusX language. You can download the free version of MonkeyX from itch.io or Cerberus-x.com The Flash applets will stop working in around 2020.
Sunday, March 5, 2017
Monkey-X - Collision - Line vs Oriented Rectangle - code example
Monkey-X - Collision - Line vs Line Segment - code example
' From the book '2d game collision detection' ' line vs line segment collision #rem If a line collides with a segment you only need to know if the segments end points lie on the same side of the line. If they do then a collision is impossible. #end Import mojo ' This is the collision class. ' Class collision ' Collision function Function line_segment_collide:Bool(l:line,s:segment) Return Not on_one_side(l,s) End Function ' ' helper functions ' Function on_one_side:Bool(axis:line,s:segment) Local d1:vector2d = subtract_vector(s.point1,axis.base) Local d2:vector2d = subtract_vector(s.point2,axis.base) Local n:vector2d = rotate_vector_90(axis.direction) Return dot_product(n,d1) * dot_product(n,d2) > 0 End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function Function rotate_vector_90:vector2d(v:vector2d) Local r:vector2d = New vector2d() r.x = -v.y r.y = v.x Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line ' base is a vector which holds the origin ' of the line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method Method draw() DrawLine base.x,base.y,direction.x,direction.y End Method End Class Class segment ' point1 and point2 are two vectors. ' A vector has a x and y coordinate. Field point1:vector2d Field point2:vector2d Method New(point1:vector2d,point2:vector2d) Self.point1 = point1 Self.point2 = point2 End Method Method draw() DrawLine point1.x,point1.y,point2.x,point2.y End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 Local line1:line = New line( New vector2d(0,0), New vector2d(MouseX,MouseY)) Local segline1:segment = New segment( New vector2d(100,200), New vector2d(400,100)) ' Here we test for collision If col.line_segment_collide(line1,segline1) DrawText "Line vs Line Segment Collision",0,0 Else DrawText "Line vs Line Segment NO Collision",0,0 End If line1.draw segline1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey -X - Collision - Point vs Oriented Rectangle - code example
' From the book '2d game collision detection' ' point vs oriented rectangle collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' The point vs oriented rectangle collision Function oriented_rectangle_point_collide:Bool( r:orientedrectangle, p:vector2d) Local lr:rectangle lr = New rectangle( New vector2d(0,0), multiply_vector(r.halfextend,2)) Local lp:vector2d = subtract_vector(p,r.center) lp = rotate_vector(lp,-r.rotation) lp = add_vector(lp,r.halfextend) Return point_rectangle_collide(lp,lr) End Function ' The point vs rectangle Collision ' needed for point in oriented rectangle collision Function point_rectangle_collide:Bool(p:vector2d,r:rectangle) Local left:Float = r.origin.x Local right:Float = left + r.size.x Local bottom:Float = r.origin.y Local top:Float = bottom + r.size.y Return left <= p.x And bottom <= p.y And p.x <= right And p.y <= top End Function ' ' helper functions ' Function multiply_vector:vector2d(v:vector2d,scalar:Float) Local r:vector2d = New vector2d() r.x = v.x * scalar r.y = v.y * scalar Return r End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function ' Here is the function that rotates a vector. It returns the ' new rotated vector. ' Function rotate_vector:vector2d(v:vector2d,degrees:Float) Local r:vector2d = New vector2d() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class Class orientedrectangle Field center:vector2d Field halfextend:vector2d Field rotation:Float Method New(center:vector2d,halfextend:vector2d,rotation:Float) Self.center = center Self.halfextend = halfextend Self.rotation = rotation End Method Method draw() Local v1:vector2d,v2:vector2d,v3:vector2d,v4:vector2d 'topside v1 = New vector2d(-halfextend.x,-halfextend.y) v2 = New vector2d(halfextend.x,-halfextend.y) v1 = rotate_vector(v1,rotation) v2 = rotate_vector(v2,rotation) v1.x += center.x v1.y += center.y v2.x += center.x v2.y += center.y ' rightside v3 = New vector2d(halfextend.x,halfextend.y) v3 = rotate_vector(v3,rotation) v3.x += center.x v3.y += center.y ' bottom side v4 = New vector2d(-halfextend.x,halfextend.y) v4 = rotate_vector(v4,rotation) v4.x += center.x v4.y += center.y DrawLine v1.x,v1.y,v2.x,v2.y DrawLine v2.x,v2.y,v3.x,v3.y DrawLine v3.x,v3.y,v4.x,v4.y DrawLine v4.x,v4.y,v1.x,v1.y End Method Function rotate_vector:vector2d(v:vector2d,degrees:Float) Local r:vector2d = New vector2d() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App ' This variable we use to rotate ' the oriented rectangle. Field angle:Float=0 Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() angle+=1 If angle>359 Then angle = 0 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 Local center:vector2d = New vector2d(320,200) Local halfdivide:vector2d = New vector2d(100,50) Local orect1:orientedrectangle = New orientedrectangle( center, halfdivide, angle) ' Here we create a vector with the mouse it's coordinates. ' We use this point to test collsion with the orect. Local point:vector2d = New vector2d(MouseX,MouseY) ' Here we test for collision If col.oriented_rectangle_point_collide( orect1, point) DrawText "Point vs Oriented Rect Collision",0,0 Else DrawText "Point vs Oriented Rect NO Collision",0,0 End If orect1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Saturday, March 4, 2017
Monkey-X - Collision - Rectangle vs Line Segment - code example
' From the book '2d game collision detection' ' rectangle vs Line segment collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' Rectangle vs Line Segment Function Function rectangle_segment_collide:Bool(r:rectangle,s:segment) ' First we test the line vs rectangle collision Local sline:line = New line() sline.base = s.point1 sline.direction = subtract_vector( s.point2, s.point1) If (Not line_rectangle_collide(sline,r)) Then Return False End If ' Here we test the ranges of the line ' with the rectangle Local rrange:range = New range() Local srange:range = New range() rrange.minimum = r.origin.x rrange.maximum = r.origin.x + r.size.x srange.minimum = s.point1.x srange.maximum = s.point2.x srange = sort_range(srange) If(Not overlapping_ranges(rrange,srange)) Then Return False End If rrange.minimum = r.origin.y rrange.maximum = r.origin.y + r.size.y srange.minimum = s.point1.y srange.maximum = s.point2.y srange = sort_range(srange) Return overlapping_ranges(rrange,srange) End Function ' The rectangle vs Line Collision ' needed for rectangle vs line segment Function line_rectangle_collide:Bool(l:line,r:rectangle) Local n:vector2d = rotate_vector_90(l.direction) Local dp1:Float,dp2:Float Local dp3:Float,dp4:Float Local c1:vector2d = r.origin Local c2:vector2d = add_vector(c1,r.size) Local c3:vector2d = New vector2d(c2.x,c1.y) Local c4:vector2d = New vector2d(c1.x,c2.y) c1 = subtract_vector(c1,l.base) c2 = subtract_vector(c2,l.base) c3 = subtract_vector(c3,l.base) c4 = subtract_vector(c4,l.base) dp1 = dot_product(n,c1) dp2 = dot_product(n,c2) dp3 = dot_product(n,c3) dp4 = dot_product(n,c4) Return (dp1 * dp2 <= 0) Or (dp2 * dp3 <= 0) Or (dp3 * dp4 <= 0) End Function ' ' helper functions ' Function sort_range:range(r:range) Local sorted:range = r If (r.minimum > r.maximum) sorted.minimum = r.maximum sorted.maximum = r.minimum End If Return sorted End Function Function overlapping_ranges:Bool(a:range,b:range) Return overlapping( a.minimum, a.maximum, b.minimum, b.maximum) End Function Function overlapping:Bool(mina:Float,maxa:Float,minb:Float,maxb:Float) Return minb <= maxa And mina <= maxb End Function Function rotate_vector_90:vector2d(v:vector2d) Local r:vector2d = New vector2d() r.x = -v.y r.y = v.x Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method Method draw() DrawLine base.x,base.y,direction.x,direction.y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class Class range Field minimum:Float Field maximum:Float Method New(minimum:Float,maximum:Float) Self.minimum = minimum Self.maximum = maximum End Method End Class Class segment ' point1 and point2 are two vectors. ' A vector has a x and y coordinate. Field point1:vector2d Field point2:vector2d Method New(point1:vector2d,point2:vector2d) Self.point1 = point1 Self.point2 = point2 End Method Method draw() DrawLine point1.x,point1.y,point2.x,point2.y End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Field angle:Float Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() angle+=1 If angle > 360 Then angle = 0 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' this is a line segment setup Local point1:vector2d = New vector2d(MouseX,MouseY) Local point2:vector2d = New vector2d(MouseX+100,MouseY+100) ' ls is short for line segment Local ls:segment = New segment(point1,point2) ' ' This is the rectangle Local origin:vector2d = New vector2d(320,200) Local size:vector2d = New vector2d(100,50) Local rect1:rectangle = New rectangle(origin,size) ' Here we test for collision If col.rectangle_segment_collide(rect1,ls) DrawText "Rectangle vs Line Segment Collision",0,0 Else DrawText "Rectangle vs Line Segment NO Collision",0,0 End If ' Here we draw the line and rectangle ls.draw rect1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Rectangle vs Line - code example
' From the book '2d game collision detection' ' rectangle vs Line collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' The rectangle vs Line Collision Function line_rectangle_collide:Bool(l:line,r:rectangle) Local n:vector2d = rotate_vector_90(l.direction) Local dp1:Float,dp2:Float Local dp3:Float,dp4:Float Local c1:vector2d = r.origin Local c2:vector2d = add_vector(c1,r.size) Local c3:vector2d = New vector2d(c2.x,c1.y) Local c4:vector2d = New vector2d(c1.x,c2.y) c1 = subtract_vector(c1,l.base) c2 = subtract_vector(c2,l.base) c3 = subtract_vector(c3,l.base) c4 = subtract_vector(c4,l.base) dp1 = dot_product(n,c1) dp2 = dot_product(n,c2) dp3 = dot_product(n,c3) dp4 = dot_product(n,c4) Return (dp1 * dp2 <= 0) Or (dp2 * dp3 <= 0) Or (dp3 * dp4 <= 0) End Function ' ' helper functions ' Function rotate_vector_90:vector2d(v:vector2d) Local r:vector2d = New vector2d() r.x = -v.y r.y = v.x Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method Method draw() DrawLine base.x,base.y,direction.x,direction.y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Field angle:Float Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() angle+=1 If angle > 360 Then angle = 0 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' this is a line setup Local base:vector2d = New vector2d(0,0) Local direction:vector2d = New vector2d(MouseX,MouseY) Local line1:line = New line(base,direction) ' ' This is the rectangle Local origin:vector2d = New vector2d(320,200) Local size:vector2d = New vector2d(100,100) Local rect1:rectangle = New rectangle(origin,size) ' Here we test for collision If col.line_rectangle_collide(line1,rect1) DrawText "Line vs Rectangle Collision",0,0 Else DrawText "Line vs Rectangle NO Collision",0,0 End If ' Here we draw the line and rectangle line1.draw rect1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 DrawText "Info : Lines are infinite in length.",DeviceWidth/2,20 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Point vs Rectangle - code example
' From the book '2d game collision detection' ' point vs rectangle collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' The point vs rectangle Collision Function point_rectangle_collide:Bool(p:vector2d,r:rectangle) Local left:Float = r.origin.x Local right:Float = left + r.size.x Local bottom:Float = r.origin.y Local top:Float = bottom + r.size.y Return left <= p.x And bottom <= p.y And p.x <= right And p.y <= top End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Field angle:Float Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() angle+=1 If angle > 360 Then angle = 0 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' this is a point(vector) with the mouse coordinates Local point:vector2d = New vector2d(MouseX,MouseY) ' ' This is the rectangle Local origin:vector2d = New vector2d(320,200) Local size:vector2d = New vector2d(100,100) Local rect1:rectangle = New rectangle(origin,size) ' Here we test for collision If col.point_rectangle_collide(point,rect1) DrawText "Point vs Rectangle Collision",0,0 Else DrawText "Point vs Rectangle NO Collision",0,0 End If rect1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Circle vs Oriented Rectangle - code example
' From the book '2d game collision detection' ' circle vs oriented rectangle collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' the circle vs oriented rectangle collision Function circle_oriented_rectangle_collide:Bool(c:circle, r:orientedrectangle) Local origin:vector2d = New vector2d(0,0) Local size:vector2d = New vector2d(0,0) Local lr:rectangle = New rectangle(origin,size) lr.size = multiply_vector(r.halfextend,2) Local center:vector2d = New vector2d(0,0) Local lc:circle = New circle(center,c.radius) Local distance:vector2d = subtract_vector(c.center,r.center) distance = rotate_vector(distance,-r.rotation) lc.center = add_vector(distance,r.halfextend) Return circle_rectangle_collide(lc,lr) End Function ' needed for circle vs oriented rectangle collision Function circle_rectangle_collide:Bool(c:circle,r:rectangle) Local clamped:vector2d = clamp_on_rectangle(c.center,r) Return circle_point_collide(c,clamped) End Function ' Needed for circle_segment_collide Function circle_point_collide:Bool(c:circle,p:vector2d) Local distance:vector2d = subtract_vector(c.center,p) Return vector_length(distance) <= c.radius End Function ' Helper Functions ........ ' ' Function multiply_vector:vector2d(v:vector2d,scalar:Float) Local r:vector2d = New vector2d() r.x = v.x * scalar r.y = v.y * scalar Return r End Function Function clamp_on_rectangle:vector2d(p:vector2d,r:rectangle) Local clamp:vector2d = New vector2d() clamp.x = Clamp(p.x,r.origin.x,r.origin.x+r.size.x) clamp.y = Clamp(p.y,r.origin.y,r.origin.y+r.size.y) Return clamp End Function Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function ' Here is the function that rotates a vector. It returns the ' new rotated vector. ' Function rotate_vector:vector2d(v:vector2d,degrees:Float) Local r:vector2d = New vector2d() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class Class circle Field center:vector2d Field radius:Float Method New(center:vector2d,radius:Float) Self.center = center Self.radius = radius End Method Method draw() DrawCircle center.x,center.y,radius End Method End Class Class orientedrectangle Field center:vector2d Field halfextend:vector2d Field rotation:Float Method New(center:vector2d,halfextend:vector2d,rotation:Float) Self.center = center Self.halfextend = halfextend Self.rotation = rotation End Method Method draw() Local v1:vector2d,v2:vector2d,v3:vector2d,v4:vector2d 'topside v1 = New vector2d(-halfextend.x,-halfextend.y) v2 = New vector2d(halfextend.x,-halfextend.y) v1 = rotate_vector(v1,rotation) v2 = rotate_vector(v2,rotation) v1.x += center.x v1.y += center.y v2.x += center.x v2.y += center.y ' rightside v3 = New vector2d(halfextend.x,halfextend.y) v3 = rotate_vector(v3,rotation) v3.x += center.x v3.y += center.y ' bottom side v4 = New vector2d(-halfextend.x,halfextend.y) v4 = rotate_vector(v4,rotation) v4.x += center.x v4.y += center.y DrawLine v1.x,v1.y,v2.x,v2.y DrawLine v2.x,v2.y,v3.x,v3.y DrawLine v3.x,v3.y,v4.x,v4.y DrawLine v4.x,v4.y,v1.x,v1.y End Method Function rotate_vector:vector2d(v:vector2d,degrees:Float) Local r:vector2d = New vector2d() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Field angle:Float Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() angle+=1 If angle > 360 Then angle = 0 End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' Here we set up the circle where we test ' the collision with Local cc:vector2d = New vector2d(320,200) Local r:Float = 50 Local circle1:circle = New circle(cc,r) ' Here we set up the oriented rectangle Local orc:vector2d = New vector2d(MouseX,MouseY) Local ors:vector2d = New vector2d(100,50) 'size of the oriented rectangle Local orect:orientedrectangle = New orientedrectangle(orc,ors,angle) ' Collision test If col.circle_oriented_rectangle_collide(circle1,orect) DrawText "Circle vs Oriented rect Collide",0,0 Else DrawText "Circle vs Oriented rect NO Collision",0,0 End If orect.draw circle1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Circle vs Rectangle - code example
' From the book '2d game collision detection' ' circle vs rectangle collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' the circle vs rectangle segment collision Function circle_rectangle_collide:Bool(c:circle,r:rectangle) Local clamped:vector2d = clamp_on_rectangle(c.center,r) Return circle_point_collide(c,clamped) End Function ' Needed for circle_segment_collide Function circle_point_collide:Bool(c:circle,p:vector2d) Local distance:vector2d = subtract_vector(c.center,p) Return vector_length(distance) <= c.radius End Function ' Helper Functions ........ ' ' Function clamp_on_rectangle:vector2d(p:vector2d,r:rectangle) Local clamp:vector2d = New vector2d() clamp.x = Clamp(p.x,r.origin.x,r.origin.x+r.size.x) clamp.y = Clamp(p.y,r.origin.y,r.origin.y+r.size.y) Return clamp End Function Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class circle Field center:vector2d Field radius:Float Method New(center:vector2d,radius:Float) Self.center = center Self.radius = radius End Method Method draw() DrawCircle center.x,center.y,radius End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' Here we set up the circle where we test ' the collision with Local cc:vector2d = New vector2d(320,200) Local r:Float = 50 Local circle1:circle = New circle(cc,r) ' Here we set up the rectangle where we test ' the collision with Local origin:vector2d = New vector2d(MouseX,MouseY) Local size:vector2d = New vector2d(100,100) Local rect1:rectangle = New rectangle(origin,size) ' Here we call the collision function If col.circle_rectangle_collide(circle1,rect1) DrawText "Circle Rectangle Colliding",0,0 Else DrawText "Circle Rectangle NOT Colliding",0,0 End If ' Draw the circle and rectangle circle1.draw rect1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Circle vs Line Segment - code example
' From the book '2d game collision detection' ' circle vs line segment collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' the circle vs line segment collision Method circle_segment_collide:Bool(c:circle,s:segment) If (circle_point_collide(c,s.point1)) Then Return True If (circle_point_collide(c,s.point2)) Then Return True Local d:vector2d = subtract_vector(s.point2,s.point1) Local lc:vector2d = subtract_vector(c.center,s.point1) Local p:vector2d = project_vector(lc,d) Local nearest:vector2d = add_vector(s.point1,p) Return circle_point_collide(c,nearest) And vector_length(p) <= vector_length(d) And 0 <= dot_product(p,d) End Method ' Needed for circle_segment_collide Method circle_point_collide:Bool(c:circle,p:vector2d) Local distance:vector2d = subtract_vector(c.center,p) Return vector_length(distance) <= c.radius End Method ' Helper Functions ........ ' ' Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function project_vector:vector2d(project:vector2d, onto:vector2d) ' d is a float variable that holds the dot product ' of onto,onto Local d:Float = dot_product(onto,onto) If (0<d) ' dp is a variable that holds the dot product ' of project and onto Local dp:Float = dot_product(project, onto) Return multiply_vector(onto,dp/d) End If Return onto End Function Function multiply_vector:vector2d(v:vector2d,scalar:Float) Local r:vector2d = New vector2d() r.x = v.x * scalar r.y = v.y * scalar Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method Method draw() DrawLine base.x,base.y,direction.x,direction.y End Method End Class Class circle Field center:vector2d Field radius:Float Method New(center:vector2d,radius:Float) Self.center = center Self.radius = radius End Method Method draw() DrawCircle center.x,center.y,radius End Method End Class Class segment ' point1 and point2 are two vectors. ' A vector has a x and y coordinate. Field point1:vector2d Field point2:vector2d Method New(point1:vector2d,point2:vector2d) Self.point1 = point1 Self.point2 = point2 End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 Local cc:vector2d = New vector2d(320,200) Local r:Float = 50 Local circle1:circle = New circle(cc,r) Local a:vector2d = New vector2d(MouseX,MouseY) Local b:vector2d = New vector2d(MouseX+100,MouseY+100) Local s1:segment = New segment(a,b) If col.circle_segment_collide(circle1,s1) DrawText "Circle Line Collision",0,0 Else DrawText "Circle Line NO Collision",0,0 End If DrawLine a.x,a.y,b.x,b.y circle1.draw DrawText "Move the Mouse to test for Collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Circle vs Line - code example
' From the book '2d game collision detection' ' circle vs line collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' the circle vs line collision Method circle_line_collide:Bool(c:circle,l:line) Local lc:vector2d = subtract_vector(c.center,l.base) Local p:vector2d = project_vector(lc,l.direction) Local nearest:vector2d = add_vector(l.base,p) Return circle_point_collide(c,nearest) End Method Method circle_point_collide:Bool(c:circle,p:vector2d) Local distance:vector2d = subtract_vector(c.center,p) Return vector_length(distance) <= c.radius End Method ' Helper Functions ........ ' ' Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function project_vector:vector2d(project:vector2d, onto:vector2d) ' d is a float variable that holds the dot product ' of onto,onto Local d:Float = dot_product(onto,onto) If (0<d) ' dp is a variable that holds the dot product ' of project and onto Local dp:Float = dot_product(project, onto) Return multiply_vector(onto,dp/d) End If Return onto End Function Function multiply_vector:vector2d(v:vector2d,scalar:Float) Local r:vector2d = New vector2d() r.x = v.x * scalar r.y = v.y * scalar Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function add_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d(0,0) r.x = a.x + b.x r.y = a.y + b.y Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method Method draw() DrawLine base.x,base.y,direction.x,direction.y End Method End Class Class circle Field center:vector2d Field radius:Float Method New(center:vector2d,radius:Float) Self.center = center Self.radius = radius End Method Method draw() DrawCircle center.x,center.y,radius End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 Local cc:vector2d = New vector2d(320,200) Local r:Float = 50 Local circle1:circle = New circle(cc,r) Local base:vector2d = New vector2d(0,0) Local direction:vector2d = New vector2d(MouseX,MouseY) Local l:line = New line(base,direction) If col.circle_line_collide(circle1,l) DrawText "Circle and Line Colliding",0,0 Else DrawText "Circle and Line NOT Colliding",0,0 End If circle1.draw l.draw DrawText "Circle vs Line Collision",DeviceWidth/2,0 DrawText "Info : Lines are infinite in length.",DeviceWidth/2,20 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Circle vs Point - code example
' From the book '2d game collision detection' ' circle vs point collision Import mojo ' This is the collision class. ' Class collision ' Collision function ' the circle vs point collision Method circle_point_collide:Bool(c:circle,p:vector2d) Local distance:vector2d = subtract_vector(c.center,p) Return vector_length(distance) <= c.radius End Method ' Helper Functions ........ ' ' Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class circle Field center:vector2d Field radius:Float Method New(center:vector2d,radius:Float) Self.center = center Self.radius = radius End Method Method draw() DrawCircle center.x,center.y,radius End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(30) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' c is a vector where we create the circle with Local c:vector2d = New vector2d(320,200) ' r is a float variable that is the radius of the circle Local r:Float = 100 ' here we create a circle Local circle:circle = New circle(c,r) ' draw the circle circle.draw ' create a vector at the mouse pointer coordinates Local mousevector:vector2d = New vector2d(MouseX,MouseY) ' test collision If col.circle_point_collide(circle,mousevector) DrawText "Point Collision with circle",0,0 Else DrawText "Point NO Collision with circle",0,0 End If DrawText "Move the mouse around to test collision",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Line Segment vs Line Segment - code example
' From the book '2d game collision detection' ' Line Segment vs Line Segment Collision Import mojo ' This is the collision class. In this example with ' the line segment vs line segment. ' ' Class collision ' Collision function ' This is the line segments collision function Function segments_collide:Bool(a:segment,b:segment) Local axisa:line = New line() Local axisb:line = New line() axisa.base = a.point1 axisa.direction = subtract_vector(a.point2,a.point1) If (on_one_side(axisa,b)) Then Return False axisb.base = b.point1 axisb.direction = subtract_vector(b.point2,b.point1) If (on_one_side(axisb,a)) Then Return False If (parallel_vectors(axisa.direction,axisb.direction)) Local rangea:range = project_segment(a,axisa.direction) Local rangeb:range = project_segment(b,axisa.direction) Return overlapping_ranges(rangea,rangeb) Else Return True End If End Function ' Helper Functions ........ ', ' Function on_one_side:Bool(axis:line,s:segment) Local d1:vector2d = subtract_vector(s.point1,axis.base) Local d2:vector2d = subtract_vector(s.point2,axis.base) Local n:vector2d = rotate_vector_90(axis.direction) Return dot_product(n,d1) * dot_product(n,d2) > 0 End Function Function sort_range:range(r:range) Local sorted:range = r If (r.minimum > r.maximum) sorted.minimum = r.maximum sorted.maximum = r.minimum End If Return sorted End Function Function project_segment:range(s:segment,onto:vector2d) Local ontounit:vector2d = unit_vector(onto) Local r:range = New range() r.minimum = dot_product(ontounit,s.point1) r.maximum = dot_product(ontounit,s.point2) r = sort_range(r) Return r End Function Function overlapping_ranges:Bool(a:range,b:range) Return overlapping( a.minimum, a.maximum, b.minimum, b.maximum) End Function Function overlapping:Bool(mina:Float,maxa:Float,minb:Float,maxb:Float) Return minb <= maxa And mina <= maxb End Function Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function Function rotate_vector_90:vector2d(v:vector2d) Local r:vector2d = New vector2d() r.x = -v.y r.y = v.x Return r End Function Function unit_vector:vector2d(v:vector2d) Local length:Float = vector_length(v) If (0 < length) Return divide_vector(v,length) End If Return v End Function Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function parallel_vectors:Bool(a:vector2d,b:vector2d) Local na:vector2d = rotate_vector_90(a) Return (0 = Floor(dot_product(na,b))) End Function Function divide_vector:vector2d(v:vector2d,divisor:Float) Local r:vector2d = New vector2d() r.x = v.x / divisor r.y = v.y / divisor Return r End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line ' base is a vector which holds the origin ' of the line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method End Class Class range Field minimum:Float Field maximum:Float Method New(minimum:Float,maximum:Float) Self.minimum = minimum Self.maximum = maximum End Method End Class Class segment ' point1 and point2 are two vectors. ' A vector has a x and y coordinate. Field point1:vector2d Field point2:vector2d Method New(point1:vector2d,point2:vector2d) Self.point1 = point1 Self.point2 = point2 End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' Local a:vector2d = New vector2d(10,10) Local b:vector2d = New vector2d(320,200) Local c:vector2d = New vector2d(MouseX,MouseY) Local d:vector2d = New vector2d(MouseX+100,MouseY+100) ' segments are two vectors. point1 x and y ' and point2 x and y ' Local s1:segment = New segment(a,b) Local s2:segment = New segment(c,d) If col.segments_collide(s1,s2) DrawText "Lines s1 and s2 - Collision",0,0 Else DrawText "Lines s1 and s2 - No Collision",0,0 End If DrawLine a.x,a.y,b.x,b.y DrawLine c.x,c.y,d.x,d.y DrawText "Move the Mouse to move the line.",DeviceWidth/2,0 End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Line vs Line - code example
' From the book '2d game collision detection' ' Line vs Line Collision Import mojo ' This is the collision class. In this example with ' the line vs line method. ' ' Class collision ' Collision function Method lines_collide:Bool(a:line,b:line) If (parallel_vectors(a.direction,b.direction)) Return equivalent_lines(a,b) Else Return True End If End Method ' Helper Functions ........ ' ' Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function equivalent_lines:Bool(a:line,b:line) If (Not parallel_vectors(a.direction,b.direction)) Then Return False Local d:vector2d = subtract_vector(a.base,b.base) Return parallel_vectors(d,a.direction) End Function Function equal_vectors:Bool(a:vector2d,b:vector2d) Return a.x-b.x = 0 And a.y-b.y = 0 End Function Function parallel_vectors:Bool(a:vector2d,b:vector2d) Local na:vector2d = rotate_vector_90(a) Return (0 = Floor(dot_product(na,b))) End Function Function rotate_vector_90:vector2d(v:vector2d) Local r:vector2d = New vector2d() r.x = -v.y r.y = v.x Return r End Function Function dot_product:Float(a:vector2d,b:vector2d) Return a.x * b.x + a.y * b.y End Function End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class line Field base:vector2d Field direction:vector2d Method New(base:vector2d,direction:vector2d) Self.base = base Self.direction = direction End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' a,b and c are variables that are turned into vectors ' using the vector2d class Local a:vector2d = New vector2d(30,50) Local b:vector2d = New vector2d(30,20) Local c:vector2d = New vector2d(80,40) Local down:vector2d = New vector2d(50,-10) Local up:vector2d = New vector2d(50,20) Local l1:line = New line(a,down) Local l2:line = New line(a,up) Local l3:line = New line(b,up) Local l4:line = New line(c,down) If col.lines_collide(l1,l2) DrawText "Lines 1 and 2 Collide",0,0 Else DrawText "Lines 1 and 2 do not Collide",0,0 End If If col.lines_collide(l1,l3) DrawText "Lines 1 and 3 Collide",0,20 Else DrawText "Lines 1 and 3 do not Collide",0,20 End If If col.lines_collide(l2,l3) DrawText "Lines 2 and 3 Collide",0,40 Else DrawText "Lines 2 and 3 do not Collide",0,40 End If If col.lines_collide(l1,l4) DrawText "Lines 1 and 4 Collide",0,60 Else DrawText "Lines 1 and 4 do not Collide",0,60 End If ' DrawText "Line 1 base = "+l1.base.x+","+l1.base.y,100,100 DrawText "Line 1 direction = "+l1.direction.x+","+l1.direction.y,320,100 DrawText "Line 2 base = "+l2.base.x+","+l2.base.y,100,120 DrawText "Line 2 direction = "+l2.direction.x+","+l2.direction.y,320,120 DrawText "Line 3 base = "+l3.base.x+","+l3.base.y,100,140 DrawText "Line 3 direction = "+l3.direction.x+","+l3.direction.y,320,140 DrawText "Line 4 base = "+l4.base.x+","+l4.base.y,100,160 DrawText "Line 4 direction = "+l4.direction.x+","+l4.direction.y,320,160 ' DrawText "Line vs Line Collision",DeviceWidth/2,0 DrawText "Info : Lines are infinite in length",DeviceWidth/2,20 DrawText "in every direction...",DeviceWidth/2,40 ' End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Point vs Point - code example
' From the book '2d game collision detection' Import mojo ' This is the collision class. In this example with ' the point vs point method. ' ' Class collision Method points_collide:Bool(a:vector2d,b:vector2d) Return a.x = b.x And a.y = b.y End Method End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' a,b and c are variables that are turned into vectors ' using the vector2d class Local a:vector2d = New vector2d(100,100) Local b:vector2d = New vector2d(100,100) Local c:vector2d = New vector2d(101,100) ' DrawText "point a : "+a.x+","+a.y,0,100 DrawText "point b : "+b.x+","+b.y,0,120 DrawText "point c : "+c.x+","+c.y,0,140 ' If col.points_collide(a,b) DrawText "Points a vs b - Collision",0,0 Else DrawText "Points a vs b - No Collision",0,0 End If If col.points_collide(a,c) DrawText "Points a vs c - Collision",0,20 Else DrawText "Points a vs c - No Collision",0,20 End If End Method End Class Function Main() New MyGame() End Function
Monkey-X - Collision - Circle vs Circle - code example.
' From the book '2d game collision detection' Import mojo ' This is the collision class. In this example with ' the circles collide method. ' ' Class collision Method circles_collide:Bool(a:circle,b:circle) Local radiussum:Float = a.radius+b.radius Local distance:vector2d = subtract_vector(a.center,b.center) Return vector_length(distance) <= radiussum End Method End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class circle ' Center is a vector that holds the center of a circle. Field center:vector2d ' Radius is a float variable that holds the distance from ' the center of the circle to the edge. Field radius:Float Method New(center:vector2d,radius:Float) Self.center = center Self.radius = radius End Method Method draw() DrawCircle center.x,center.y,radius End Method End Class ' col is the caller of the class collision. ' we use it to use the collision methods. Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' Local center1:vector2d = New vector2d(320,200) Local radius1:Float = 50 Local c1:circle = New circle(center1,radius1) ' Local center2:vector2d = New vector2d(MouseX(),MouseY()) Local radius2:Float = 50 Local c2:circle = New circle(center2,radius2) If col.circles_collide(c1,c2) DrawText "Circles Collision - Collision",0,0 Else DrawText "Circles Collision - No Collision",0,0 End If DrawText "Move the Mouse to see if collision occurs",DeviceWidth/2,0 DrawText "Two Circles intersect when the distance between",0,DeviceHeight-60 DrawText "their centers is less then the sum of their radii.",0,DeviceHeight-40 c1.draw c2.draw End Method End Class Function subtract_vector:vector2d(a:vector2d,b:vector2d) Local r:vector2d = New vector2d() r.x = a.x - b.x r.y = a.y - b.y Return r End Function Function vector_length:Float(v:vector2d) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function Main() New MyGame() End Function
Friday, March 3, 2017
Monkey-X - Collision - Rectangle vs Rectangle - code example
' From the book '2d game collision detection' Import mojo ' This is the collision class. In this example with ' the rectangles collide method. ' ' Class collision Method overlapping:Bool(mina:Float,maxa:Float,minb:Float,maxb:Float) Return minb <= maxa And mina <= maxb End Method Method rectangles_collide:Bool(a:rectangle,b:rectangle) Local aleft:Float = a.origin.x Local aright:Float = aleft + a.size.x Local bleft:Float = b.origin.x Local bright:Float = bleft + b.size.x Local abottom:Float = a.origin.y Local atop:Float = abottom + a.size.y Local bbottom:Float = b.origin.y Local btop:Float = bbottom + b.size.y Return overlapping( aleft,aright, bleft,bright) And overlapping( abottom, atop, bbottom, btop) End Method End Class Class vector2d ' x and y hold the position of the vector Field x:Int,y:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class rectangle ' origin is a vector that holds the x and y coordinates ' of the rectangle Field origin:vector2d ' size is a vector that holds the x(width) and ' y(height) of the rectangle Field size:vector2d Method New(origin:vector2d,size:vector2d) Self.origin = origin Self.size = size End Method Method draw() ' x1,y1,w,h are used to hold the rectangle ' location and size. Local x1:Int=origin.x Local y1:Int=origin.y Local w:Int=size.x Local h:Int=size.y DrawRect x1,y1,w,h End Method End Class Global col:collision = New collision Class MyGame Extends App Method OnCreate() SetUpdateRate(60) End Method Method OnUpdate() End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 ' origin is a vector that we use to create ' the rectangle. It holds the x and y position. Local origin:vector2d=New vector2d(100,200) ' size is a vector that we use to create ' the rectangle. It holds the width and height. Local size:vector2d=New vector2d(100,100) ' r1 is a rectangle created with the origin and size ' vector variables Local r1:rectangle = New rectangle(origin,size) ' Here we create another recangle at the ' position of the mouse origin = New vector2d(MouseX(),MouseY()) size = New vector2d(50,50) Local r2:rectangle = New rectangle(origin,size) If col.rectangles_collide(r1,r2) = True Then DrawText "Collision",0,0 Else DrawText "No Collision",0,0 End If DrawText "Move the mouse to see if something collides",DeviceWidth/2,0 r1.draw r2.draw End Method End Class Function Main() New MyGame() End Function
Monkey-X - Beginners - Vector Projection Helper - code example
Import mojo ' This is the vector class. It has a ' x and y float variable. ' Class vectorf Field x:Float,y:Float Method New(x:Float = 0,y:Float = 0) Self.x = x Self.y = y End Method End Class Class MyGame Extends App ' Here we create the 'a,b' variables using the ' vectorf class Field a:vectorf,b:vectorf ' cx and cy contain the center x and center y ' coordinates of the screen. Field cx:Int Field cy:Int ' time is a variable used to change(refresh) ' the information on the screen. Field time:Int Method OnCreate() SetUpdateRate(1) ' randomize using the time function Seed = GetDate[4] + GetDate[5] cx = DeviceWidth()/2 cy = DeviceHeight()/2 ' Here we create new vectors (a,b) ' with random values a = New vectorf(Rnd(-10,10),Rnd(10,10)) b = New vectorf(Rnd(-5,5),Rnd(5,5)) End Method Method OnUpdate() ' time+=1 If time>5 Then time=0 a = New vectorf(Rnd(-10,10),Rnd(-10,10)) b = New vectorf(Rnd(-5,5),Rnd(5,5)) End If End Method Method OnRender() ' pointx and y hold the coordinates ' that are used to draw on the screen. Local pointx:Int Local pointy:Int Cls 0,0,0 SetColor 255,255,255 ' Here we draw the helper screen part. DrawLine cx,0,cx,DeviceHeight DrawLine 0,cy,DeviceWidth,cy DrawText "-X",0,cy DrawText "+X",DeviceWidth()-30,cy DrawText "-Y",cx,0 DrawText "+Y",cx,DeviceHeight()-30 DrawText "0,0",cx,cy,.5,.5 DrawText "Origin",cx+5,cy-20 ' ' Here we draw the vector a. SetColor 255,255,255 pointx = (a.x*13) + cx pointy = (a.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "a",pointx,pointy,.5,.5 ' ' Here we draw the vector b. SetColor 255,255,255 pointx = (b.x*13) + cx pointy = (b.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "b",pointx,pointy,.5,.5 ' ' Here we create the projected vector ' We project vector b onto a. Local c:vectorf = project_vector(b,a) ' ' Here we draw the projected vector SetColor 255,255,0 pointx = (c.x*13) + cx pointy = (c.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "c",pointx,pointy,.5,.5 ' ' Here we draw the Screen info SetColor 255,255,255 Scale 1.2,1.2 SetAlpha 1 ' ' String(mystring)[0..4] creates a string with 4 ' characters. [ 0,1,2,3 ] Left to right. ' DrawText "Vector Projection b onto a",0,0 DrawText "A projection is a vector mapped onto another vector.",0,20 DrawText "",0,40 SetAlpha 0.6 DrawText "Vector Projection :",cx-30,DeviceHeight-160 DrawText "d = dot_product(a,a)",cx-20,DeviceHeight-140 DrawText "dp = dot_product(b,a)",cx-20,DeviceHeight-120 SetColor 255,255,0 DrawText "c = multiply_vector(a,dp/d)",cx-20,DeviceHeight-100 End Method End Class ' This function return the dot product of two vectors. ' It returns a value. ' Function dot_product:Float(a:vectorf,b:vectorf) Return a.x * b.x + a.y * b.y End Function ' This function multiplies a vector. ' It returns a vector. ' Function multiply_vector:vectorf(v:vectorf,scalar:Float) Local r:vectorf = New vectorf() r.x = v.x * scalar r.y = v.y * scalar Return r End Function ' This function maps a vector onto the input vector. ' It returns a vector ' Function project_vector:vectorf(project:vectorf, onto:vectorf) ' d is a float variable that holds the dot product ' of onto,onto Local d:Float = dot_product(onto,onto) If (0<d) ' dp is a variable that holds the dot product ' of project and onto Local dp:Float = dot_product(project, onto) Return multiply_vector(onto,dp/d) End If Return onto End Function Function Main() New MyGame() End Function
Monkey-X - Beginners - Vector Rotation Helper - code example
Import mojo ' This is the vector class. It has a ' x and y float variable. ' Class vectorf Field x:Float,y:Float Method New(x:Float = 0,y:Float = 0) Self.x = x Self.y = y End Method End Class Class MyGame Extends App ' Here we create a 'a' variable using the ' vectorf class Field a:vectorf ' ' Field angle:Float ' cx and cy contain the center x and center y ' coordinates of the screen. Field cx:Int Field cy:Int ' time is a variable used to change(refresh) ' the information on the screen. Field time:Int Method OnCreate() SetUpdateRate(60) Seed = GetDate[4] + GetDate[5] cx = DeviceWidth()/2 cy = DeviceHeight()/2 ' Here we create a new vector in ' a with a new value(x and y) a = New vectorf(Rnd(-10,10),Rnd(10,10)) End Method Method OnUpdate() ' ' angle+=3 If angle>359 Then angle=0 ' time+=1 If time>300 Then time=0 a = New vectorf(Rnd(-10,10),Rnd(-10,10)) End If End Method Method OnRender() ' pointx and y hold the coordinates ' that are used to draw on the screen. Local pointx:Int Local pointy:Int Cls 0,0,0 SetColor 255,255,255 ' Here we draw the helper screen part. DrawLine cx,0,cx,DeviceHeight DrawLine 0,cy,DeviceWidth,cy DrawText "-X",0,cy DrawText "+X",DeviceWidth()-30,cy DrawText "-Y",cx,0 DrawText "+Y",cx,DeviceHeight()-30 DrawText "0,0",cx,cy,.5,.5 DrawText "Origin",cx+5,cy-20 ' ' Here we draw the vector a. SetColor 255,255,255 pointx = (a.x*13) + cx pointy = (a.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "a",pointx,pointy,.5,.5 DrawText String(a.x)[0..4]+","+String(a.y)[0..4],pointx+5,pointy+10,.5,.5 ' ' Here we draw the rotated vector (b) SetColor 255,255,0 Local b:vectorf = New vectorf() b = rotate_vector(a,angle) pointx = (b.x*13) + cx pointy = (b.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "b",pointx,pointy,.5,.5 ' ' Here we draw the Screen info SetColor 255,255,255 Scale 1.2,1.2 SetAlpha 1 ' ' String(mystring)[0..4] creates a string with 4 ' characters. [ 0,1,2,3 ] Left to right. ' DrawText "Vector Rotation Degrees : "+angle,0,0 DrawText "Vector rotation changes the direction in which",0,20 DrawText "a vector points. The vector length stays the same.",0,40 SetAlpha 0.6 DrawText "Vector Rotation :",cx-30,DeviceHeight-160 DrawText "b.x = v.x * Cos(degrees) - v.y * Sin(degrees)",cx-100,DeviceHeight-140 DrawText "r.y = v.x * Sin(degrees) + v.y * Cos(degrees)",cx-100,DeviceHeight-120 End Method End Class ' ' Here is the function that rotates a vector. It returns the ' new rotated vector. ' Function rotate_vector:vectorf(v:vectorf,degrees:Float) Local r:vectorf = New vectorf() r.x = v.x * Cos(degrees) - v.y * Sin(degrees) r.y = v.x * Sin(degrees) + v.y * Cos(degrees) Return r End Function Function Main() New MyGame() End Function
Monkey-X - Beginners - Unit Vector Helper - code example
Import mojo ' This is the vector class. It has a ' x and y float variable. ' Class vectorf Field x:Float,y:Float Method New(x:Float = 0,y:Float = 0) Self.x = x Self.y = y End Method End Class Class MyGame Extends App ' Here we create a 'a' variable using the ' vectorf class Field a:vectorf ' cx and cy contain the center x and center y ' coordinates of the screen. Field cx:Int Field cy:Int ' time is a variable used to change(refresh) ' the information on the screen. Field time:Int Method OnCreate() SetUpdateRate(1) Seed = GetDate[4] + GetDate[5] cx = DeviceWidth()/2 cy = DeviceHeight()/2 ' Here we create a new vector in ' a with a new value(x and y) a = New vectorf(Rnd(-10,10),Rnd(10,10)) End Method Method OnUpdate() time+=1 If time>5 Then time=0 a = New vectorf(Rnd(-10,10),Rnd(-10,10)) End If End Method Method OnRender() ' pointx and y hold the coordinates ' that are used to draw on the screen. Local pointx:Int Local pointy:Int Cls 0,0,0 SetColor 255,255,255 ' Here we draw the helper screen part. DrawLine cx,0,cx,DeviceHeight DrawLine 0,cy,DeviceWidth,cy DrawText "-X",0,cy DrawText "+X",DeviceWidth()-30,cy DrawText "-Y",cx,0 DrawText "+Y",cx,DeviceHeight()-30 DrawText "0,0",cx,cy,.5,.5 DrawText "Origin",cx+5,cy-20 ' ' Here we draw the vector a. SetColor 255,255,0 pointx = (a.x*13) + cx pointy = (a.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "a",pointx,pointy,.5,.5 DrawText String(a.x)[0..4]+","+String(a.y)[0..4],pointx+5,pointy+10,.5,.5 ' ' Here we draw the Screen info SetColor 255,255,255 Scale 1.2,1.2 SetAlpha 1 ' ' String(mystring)[0..4] creates a string with 4 ' characters. [ 0,1,2,3 ] Left to right. ' Local v:vectorf = unit_vector(a) Local x:String=String(v.x)[0..4] Local y:String=String(v.y)[0..4] DrawText "Unit vector is : "+x+","+y,0,0 DrawText "The size of unit vector is",0,20 DrawText "Bigger then -1 and smaller then 1.",0,40 SetAlpha 0.6 DrawText "Unit Vector :",cx-30,DeviceHeight-160 DrawText "vector divided by length",cx-30,DeviceHeight-140 End Method End Class ' Here is the function that returns the length of ' the origin(0,0) to it's tip. ' Function vector_length:Float(v:vectorf) Return Sqrt(v.x * v.x + v.y * v.y) End Function ' This function divides a vector by ' a value. (scaling it) ' Function divide_vector:vectorf(v:vectorf,divisor:Float) Local r:vectorf = New vectorf() r.x = v.x / divisor r.y = v.y / divisor Return r End Function ' This function turns a vector in a unit ' vector. Size <1 and >-1. ' Function unit_vector:vectorf(v:vectorf) Local length:Float = vector_length(v) If (0 < length) Return divide_vector(v,length) End If Return v End Function Function Main() New MyGame() End Function
Monkey-X - Beginners - Vector Length Helper - code example
Import mojo ' This is the vector class. It has a ' x and y float variable. ' Class vectorf Field x:Float,y:Float Method New(x:Float = 0,y:Float = 0) Self.x = x Self.y = y End Method End Class Class MyGame Extends App ' Here we create a 'a' variable using the ' vectorf class Field a:vectorf ' cx and cy contain the center x and center y ' coordinates of the screen. Field cx:Int Field cy:Int ' time is a variable used to change(refresh) ' the information on the screen. Field time:Int Method OnCreate() SetUpdateRate(1) Seed = GetDate[4] + GetDate[5] cx = DeviceWidth()/2 cy = DeviceHeight()/2 ' Here we create a new vector in ' a with a new value(x and y) a = New vectorf(Rnd(-10,10),Rnd(10,10)) End Method Method OnUpdate() time+=1 If time>5 Then time=0 a = New vectorf(Rnd(-10,10),Rnd(-10,10)) End If End Method Method OnRender() ' pointx and y hold the coordinates ' that are used to draw on the screen. Local pointx:Int Local pointy:Int Cls 0,0,0 SetColor 255,255,255 ' Here we draw the helper screen part. DrawLine cx,0,cx,DeviceHeight DrawLine 0,cy,DeviceWidth,cy DrawText "-X",0,cy DrawText "+X",DeviceWidth()-30,cy DrawText "-Y",cx,0 DrawText "+Y",cx,DeviceHeight()-30 DrawText "0,0",cx,cy,.5,.5 DrawText "Origin",cx+5,cy-20 ' ' Here we draw the vector a. SetColor 255,255,0 pointx = (a.x*13) + cx pointy = (a.y*13) + cy DrawCircle pointx,pointy,7 DrawLine cx,cy,pointx,pointy DrawText "a",pointx,pointy,.5,.5 DrawText String(a.x)[0..4]+","+String(a.y)[0..4],pointx+5,pointy+10,.5,.5 ' SetColor 155,155,155 DrawLine pointx,pointy,pointx,cy ' Here we draw the Screen info SetColor 255,255,255 Scale 1.2,1.2 SetAlpha 1 ' ' String(mystring)[0..4] creates a string with 4 ' characters. [ 0,1,2,3 ] Left to right. ' DrawText "Vector Length is : "+String(vector_length(a))[0..4],0,0 DrawText "The length of a vector is from",0,20 DrawText "the origin to its tip.",0,40 SetAlpha 0.6 DrawText "Vector Length :",cx-30,DeviceHeight-160 DrawText "d = Sqrt(a.x * a.x + a.y * a.y)",cx-30,DeviceHeight-140 End Method End Class ' Here is the function that returns the length of ' the origin(0,0) to it's tip. ' Function vector_length:Float(v:vectorf) Return Sqrt(v.x * v.x + v.y * v.y) End Function Function Main() New MyGame() End Function
Subscribe to:
Posts (Atom)