Attaching Shapes To Characters for Multiple Collision Zones
In this quickly slapped together example, we're attaching a group of randomly created and grouped shapes to our 'dude' character. Using multiple shapes allows the programmer to not only detect impacts with the main character as a whole, but locate more specific impact upon a particular zone, such as arms, legs, body.. or whatever components within the image you're interested in.
[pbcode]
; PROJECT : Attached-Shape-Collision-Zones
; AUTHOR : Kevin Picone
; CREATED : 1/15/2013
; EDITED : 1/15/2013
; ---------------------------------------------------------------------
; ---------------------------------------------------
; Define the character structure this program will use
; ---------------------------------------------------
Type tBody
; SCreen Coordinates of this dude
Xpos#
Ypos#
; rotation offset
HandleX#
HandleY#
; image index to use as it's representation on screen
IMage
; angle of this character
Angle#
; Turn Speed
TurnSpeed#
; Colour the attached collision shapes
ShapeColour
; number of the collision shapes attached to this dude
ShapeCount
; array with thye shape indexs in them
Shapes(16)
EndType
; ---------------------------------------------------
; The Global array of dudes the scene with use
; ---------------------------------------------------
Dim Dude(0) as tBody
; ---------------------------------------------------
; create a bunch of dudes for this scene. Each dude
; has randomly created with random number of
; ---------------------------------------------------
For lp=1 to 10
; create dude /character
size=rndrange(128,256)
INdex=NewDude(rnd(800),rnd(600),size,size)
for rects=0 to 3+rnd(5)
ShapeSize=rndrange(20,30)
offsetX=rndrange(0,Size-ShapeSize)
OffsetY=rndrange(0,Size-ShapeSize)
ThisShape=NewConvexShape(ShapeSize,3+rnd(6))
ShiftSHape ThisShape,OffsetX,OffsetY
AddDudeShape(Index,ThisShape)
next
OffsetX#=Size/-2.0
OffsetY#=Size/-2.0
ShiftDudeHandle(index,OffsetX#,OffsetY#)
next
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ MAIN LOOP ] -----------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; limit app speed to a max of 30 frames per second
Setfps 30
; create an FX image the size of the screen
Screen=NewIMage(800,600,2)
Do
rendertoimage screen
; clear the backdrop
cls $304050
; draw the all the dudes
Draw_ALL_DUdes()
; render the screen image to actual screen
rendertoscreen
drawimage screen,0,0,false
; flip back buffer to front
Sync
loop esckey()=true
End
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ Draw All The Dudes in the scene (linear) ] -----------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function Draw_ALL_DUdes()
For lp =1 to GetArrayElements(Dude())
if Dude(lp)
x#=Dude(lp).Xpos
y#=Dude(lp).Ypos
HandleX#=Dude(lp).HandleX
HandleY#=Dude(lp).HandleY
Angle#=wrapangle(Dude(lp).angle,Dude(lp).TurnSpeed)
img=Dude(lp).IMage
Width#=GetImageWidth(Img)
Height#=GetImageHeight(Img)
DrawRotatedIMage Img,x#,y#,Angle#,1,1,HandleX#,HandleY#,false+8
Dude(lp).angle=Angle#
; draw the rects
zzz_DrawDudesCollisionRects(lp)
endif
next
EndFunction
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ CReate a New Dude ] ---------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function NewDude(X#,y#,Width,Height)
Index=Getfreecell(Dude())
Dude(index) = New tBody
Dude(index).Xpos =x#
Dude(index).Ypos =y#
Dude(index).HandleX =0
Dude(index).HandleY =0
Dude(index).TurnSpeed =rndRange#(1,5)
Dude(index).ShapeColour =rndrgb()
; create an image to represent this 'character'
img=NewIMage(Width,Height,2)
; draw a phone pattern upon it
RenderPhongImage img,Width/2,Height/2,$ffffff,200,2.0
; remember the image indexc
Dude(index).IMage=img
EndFunction Index
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ Delete the DUDE ] ---------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function DeleteDude(Index)
if Index>0
if Dude(index)
; free this dudes image
IMg=Dude(index).IMage
If GetImageStatus(img)
deleteIMage Img
endif
; free the shapes attached to this dude
ShapeCount=Dude(index).ShapeCount
For lp=0 to ShapeCount-1
ThisSHape=Dude(index).Shapes(lp)
if getshapestatus(ThisSHape)
deleteshape ThisShape
endif
Next
; free dude from this position in the array
Dude(index) = Null
endif
endif
EndFUnction
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ Shift Dudes Rotation Axis ] ---------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function ShiftDudeHandle(index,OffsetX#,OffsetY#)
if Index>0
if Dude(index)
ShapeCount=Dude(index).ShapeCount
Dude(index).HandleX#+=OffsetX#
Dude(index).HandleY#+=OffsetY#
For lp=0 to ShapeCount-1
ThisSHape=Dude(index).Shapes(lp)
ShiftShape ThisShape,OffsetX#,OffsetY#
Next
endif
endif
EndFunction
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ Add Collision Shape to this dude ] ---------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function AddDudeShape(Index,ThisShape)
if Index>0
if Dude(index)
ShapeCount=Dude(index).ShapeCount
if ShapeCount<16
Dude(index).Shapes(ShapeCount)=ThisShape
Dude(index).ShapeCount=ShapeCount+1
endif
endif
endif
EndFunction
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; --[ Draw Dudes COllision Shapes ] ---------------------------------------------
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
Function zzz_DrawDudesCollisionRects(index)
if Index>0
if Dude(index)
ShapeCount=Dude(index).ShapeCount
x#=Dude(index).Xpos
y#=Dude(index).Ypos
OldCOlour=GetInk()
Ink Dude(index).ShapeColour
Inkmode 1+32
Angle#=Dude(index).Angle
For lp=0 to ShapeCount-1
ThisSHape=Dude(index).Shapes(lp)
RotateShape ThisShape,Angle#,1
DrawShape ThisShape,x#,y#,2
Next
inkmode 1
ink OldColour
endif
endif
EndFunction
[/pbcode]