UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on January 14, 2013, 09:14:57 AM

Title: Attaching Shapes To Characters for Multiple Collision Zones
Post by: kevin on January 14, 2013, 09:14:57 AM
  
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]