From b2d05b4d6b59a7ddc83b74e16da62c1b40718b55 Mon Sep 17 00:00:00 2001 From: Ian C Date: Mon, 17 Oct 2005 22:44:26 +0000 Subject: Improved collision processing so that the points, objects and lines that cause collisions can be got. --- vectorgfx.mod/vectorgfx.bmx | 210 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 164 insertions(+), 46 deletions(-) (limited to 'vectorgfx.mod/vectorgfx.bmx') diff --git a/vectorgfx.mod/vectorgfx.bmx b/vectorgfx.mod/vectorgfx.bmx index 00e3959..098d9b2 100644 --- a/vectorgfx.mod/vectorgfx.bmx +++ b/vectorgfx.mod/vectorgfx.bmx @@ -24,10 +24,15 @@ EndRem Type TVectorGfxLineStyle Abstract Rem bbdoc: Draws a vector line. - returns: The or'ed mask of all collision IDs overwritten in @colmap by this line. - about: This routine must draw a line from @x1, @y1 to @x2, @y2 using the colour @r,@g,@b. @id must be written into the collision map @colmap. + returns: The or'ed mask of all collision IDs overwritten in @colmap by this line, or zero if @colmap is null. + about: This routine must draw a line from @x1, @y1 to @x2, @y2 using the colour @r,@g,@b. + about: @id, @obj and @line must be written into the collision map @colmap if @colmap is not null and @actor is false. + about: If @colmap is set and @actor true, then collisions must be returned but no points written into the collision map. + about: If @colmap is set, @actor is true and @list is not null then any collisions should be recorded into this list + about: (no requirement for duplicate checking). + about: For an example of creating a line drawing routine view the LineSolid type in the private section of this module. EndRem - Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap) Abstract + Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList) Abstract End Type Rem @@ -66,9 +71,51 @@ Function VectorGfxSetCustom(linedraw:TVectorGfxLineStyle) Static.linedraw=linedraw End Function +Rem +bbdoc: Defines a point in the vector graphics collision map. +EndRem +Type TVectorGfxCollision + Rem + bbdoc: The X co-ordinate of this collision (in the object co-ordinate space). + EndRem + Field x:Int + + Rem + bbdoc: The Y co-ordinate of this collision (in the object co-ordinate space). + EndRem + Field y:Int + + Rem + bbdoc: The collision masks at this point. + EndRem + Field mask:Int + + Rem + bbdoc: The last vector object that wrote at this point. + EndRem + Field obj:TVectorGfxObject + + Rem + bbdoc: The index of the line in the last vector object that wrote at this point. + EndRem + Field line:Int + + Function Create:TVectorGfxCollision(x:Int, y:Int, mask:Int, obj:TVectorGfxObject, line:Int) + Local o:TVectorGfxCollision=New TVectorGfxCollision + o.x=x + o.y=y + o.mask=mask + o.obj=obj + o.line=line + Return o + End Function +End Type + + Rem bbdoc: Defines a vector graphics collision map. -about: Collisions in the library a defined using a bitmask (allowing 32 collision masks). Note that with the way that lines are drawn in an object you are likely +about: Collisions in the library are defined using a bitmask (allowing 32 collision masks). +about: Note that with the way that lines are drawn in an object you are likely about: to receive collisions for the IDs used by the lines in the object. EndRem Type TVectorGfxCollisionMap @@ -77,7 +124,7 @@ Type TVectorGfxCollisionMap Field height:Int Field xoff:Int Field yoff:Int - Field data:Int[,] + Field data:TVectorGfxCollision[,] Rem bbdoc: Create a collision map. @@ -91,8 +138,7 @@ Type TVectorGfxCollisionMap o.height=height o.xoff=0 o.yoff=0 - o.data=New Int[width,height] - + o.Clear() Return o End Function @@ -105,35 +151,51 @@ Type TVectorGfxCollisionMap yoff=y End Method + Rem + bbdoc: Get a collision point. + returns: The collision point, or null if nothing drawn there. + about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space) + EndRem + Method GetCollision:TVectorGfxCollision(x:Int, y:Int) + If x=xoff+width Or y=yoff+height + Return Null + Else + Return data[x-xoff,y-yoff] + EndIf + End Method + Rem bbdoc: Set a collision point. returns: The current collision mask for that point, or zero if the point is out of the map's range. about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space) EndRem - Method SetCollision(x:Int, y:Int, id:Int) + Method SetCollision:Int(x:Int, y:Int, id:Int, obj:TVectorGfxObject, line:Int) If x=xoff+width Or y=yoff+height Return 0 EndIf - x:-xoff - y:-yoff + Local ax:Int=x-xoff + Local ay:Int=y-yoff - Local cur:Int=data[x,y] - - data[x,y]:|id + Local cur:TVectorGfxCollision=data[ax,ay] + + If Not cur + cur=TVectorGfxCollision.Create(x,y,id,obj,line) + data[ax,ay]=cur + Else + cur.mask:|id + cur.obj=obj + cur.line=line + EndIf - Return cur + Return cur.mask End Method Rem bbdoc: Clear the collision map EndRem Method Clear() - For Local x:Int=0 Until width - For Local y:Int=0 Until height - data[x,y]=0 - Next - Next + data=New TVectorGfxCollision[width,height] End Method End Type @@ -301,9 +363,12 @@ Type TVectorGfxObject Rem bbdoc: Draw the object. returns: A bitmask of collisions. - about: Draws the object. @colmap cannot be null - use a small collision map instead if you're uninterested in collisions. + about: Draws the object. If @colmap is null then no collision processing takes place. + about: If @actor is true then collision processing takes place, but the object will + about: not write into the collision map. + about: If @list is not null then any collisions will be written into this list. This only applies if @colmap is set and @actor true. EndRem - Method Draw:Int(colmap:TVectorGfxCollisionMap) + Method Draw:Int(colmap:TVectorGfxCollisionMap=Null, actor:Int=False, list:TList=Null) Local col:Int=0 rotated=New TVectorGfxPoint[points.length] @@ -313,8 +378,11 @@ Type TVectorGfxObject rotated[f]=TVectorGfxPoint.Create(p.x,p.y) Next + Local i:Int=0 + For Local l:TVectorGfxLine=EachIn lines - col:|Static.linedraw.draw(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,l.id,colmap) + col:|Static.linedraw.draw(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,l.id,Self,i,colmap,actor,list) + i:+1 Next Return col @@ -340,9 +408,6 @@ Type TVectorGfxPoint Return o End Function - Rem - bbdoc: This is for internal library use. - EndRem Function Load:TVectorGfxPoint(s:TStream) Local o:TVectorGfxPoint o=New TVectorGfxPoint @@ -351,9 +416,6 @@ Type TVectorGfxPoint Return o End Function - Rem - bbdoc: This is for internal library use. - EndRem Method Save(s:TStream) s.WriteInt(x) s.WriteInt(y) @@ -389,9 +451,6 @@ Type TVectorGfxLine Return o End Function - Rem - bbdoc: This is for internal library use. - EndRem Function Load:TVectorGfxLine(s:TStream) Local o:TVectorGfxLine o=New TVectorGfxLine @@ -404,9 +463,6 @@ Type TVectorGfxLine Return o End Function - Rem - bbdoc: This is for internal library use. - EndRem Method Save:TVectorGfxLine(s:TStream) s.WriteInt(i1) s.WriteInt(i2) @@ -428,14 +484,27 @@ Type Static End Type Type LineSolid Extends TVectorGfxLineStyle - Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap) + Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList) Local mask:Int=0 Local lp:TList=DoLine(x1,y1,x2,y2) SetColor(r,g,b) For Local p:TAlgoPoint=EachIn lp - mask:|colmap.SetCollision(p.x,p.y,id) + If colmap + If actor + Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y) + + If c + mask:|c.mask + If list + list.AddLast(c) + EndIf + EndIf + Else + mask:|colmap.SetCollision(p.x,p.y,id,obj,line) + EndIf + EndIf Plot(p.x,p.y) Next @@ -447,7 +516,7 @@ Type LineAlpha Extends TVectorGfxLineStyle Field la:Double Field ea:Double - Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap) + Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList) Local mask:Int=0 Local lp:TList=DoLine(x1,y1,x2,y2) Local p:TAlgoPoint @@ -458,7 +527,20 @@ Type LineAlpha Extends TVectorGfxLineStyle p=TAlgoPoint(lp.RemoveFirst()) - mask:|colmap.SetCollision(p.x,p.y,id) + If colmap + If actor + Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y) + + If c + mask:|c.mask + If list + list.AddLast(c) + EndIf + EndIf + Else + mask:|colmap.SetCollision(p.x,p.y,id,obj,line) + EndIf + EndIf Plot(p.x,p.y) If lp.Count()=0 @@ -467,13 +549,39 @@ Type LineAlpha Extends TVectorGfxLineStyle p=TAlgoPoint(lp.RemoveLast()) - mask:|colmap.SetCollision(p.x,p.y,id) + If colmap + If actor + Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y) + + If c + mask:|c.mask + If list + list.AddLast(c) + EndIf + EndIf + Else + mask:|colmap.SetCollision(p.x,p.y,id,obj,line) + EndIf + EndIf Plot(p.x,p.y) SetAlpha(la) For Local p:TAlgoPoint=EachIn lp - mask:|colmap.SetCollision(p.x,p.y,id) + If colmap + If actor + Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y) + + If c + mask:|c.mask + If list + list.AddLast(c) + EndIf + EndIf + Else + mask:|colmap.SetCollision(p.x,p.y,id,obj,line) + EndIf + EndIf Plot(p.x,p.y) Next @@ -489,22 +597,32 @@ Type ThickAlpha Extends TVectorGfxLineStyle Method PlotPoint(x,y) SetAlpha(a) - DrawLine(x-1,y-1,x+1,y-1,False) - DrawLine(x+1,y-1,x+1,y+1,False) - DrawLine(x+1,y+1,x-1,y+1,False) - DrawLine(x-1,y+1,x-1,y-1,False) + DrawRect(x-1,y-1,3,3) SetAlpha(1.0) Plot(x,y) End Method - Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap) + Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList) Local mask:Int=0 Local lp:TList=DoLine(x1,y1,x2,y2) SetColor(r,g,b) For Local p:TAlgoPoint=EachIn lp - mask:|colmap.SetCollision(p.x,p.y,id) + If colmap + If actor + Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y) + + If c + mask:|c.mask + If list + list.AddLast(c) + EndIf + EndIf + Else + mask:|colmap.SetCollision(p.x,p.y,id,obj,line) + EndIf + EndIf PlotPoint(p.x,p.y) Next -- cgit v1.2.3