summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2005-10-17 22:44:26 +0000
committerIan C <ianc@noddybox.co.uk>2005-10-17 22:44:26 +0000
commitb2d05b4d6b59a7ddc83b74e16da62c1b40718b55 (patch)
treec265305d48c0f73e97190d3064b1c2e23848125b
parent601e7807f49ada0d0be612c530b5f9c310c17e6e (diff)
Improved collision processing so that the points, objects and lines that cause collisions can be got.
-rw-r--r--vectorgfx.mod/vectorgfx.bmx210
1 files changed, 164 insertions, 46 deletions
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
@@ -67,8 +72,50 @@ Function VectorGfxSetCustom(linedraw:TVectorGfxLineStyle)
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
@@ -106,34 +152,50 @@ Type TVectorGfxCollisionMap
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 Or x>=xoff+width Or y<yoff 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 Or x>=xoff+width Or y<yoff 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 <u>cannot</u> 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