UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on May 12, 2012, 05:27:25 PM

Title: Object Management
Post by: kevin on May 12, 2012, 05:27:25 PM
  Object Management

     This is another variation of how we can store 'game objects/characters' in a typed array, which if you've looked through forum examples  crops up pretty frequently.   It's one of those things where the number of solutions is only limited by your creativity really.   Here we have a slight variation on the standard style of loop, where we have a FOR / NEXT running through all the cells in the array, and query to see if this object is alive or not.  

     A bit like this

[pbcode]

     For lp =1 to GetArrayElements(BadGuys())

          ; check if there's a allocated structure at this position in the array
          if BadGuy(lp)
                    ; This object exists, so here we update it
          endif

     next

[/pbcode]
     
     Generally if you use the above approach, you end up with an array that has holes in it over time.   So you could be looping through a bunch of objects that don't exit.   What impact that has on your programs performance is debatable, since the object counts are generally only in the double, or barely triple digits and we're not running on Vic-20's anymore.

     Anyway, the idea in the following example is to keep the array of objects in a solid bank of 'alive' objects at the start of the array.   To do this means we have to move items when something needs to be deleted.    There's a few ways we can do this, but first we'll look through a brute force solution.     In this version, when any objects needs to be deleted, we copy all the following objects back up and over themselves using the CopyArrayCells command.   Depending upon the size of the array and the frequency of deletion this as as good a solution as any really.  But if had to delete a large groups of objects each frame, then the copying will no doubt have impact at some point.  

       EXAMPLE #1

 
[pbcode]

   ; -------------------------------------------------------------
   ; Declare type to hold the properties of our game character
   ; -------------------------------------------------------------
   Type tObject
         x#
         y#   
         angle#
         Speed#
         Size
         Colour
   EndType


   ; Create an array with 100 cells of type tObject
   Dim Objects(100) as tObject
   
   

   ; ----------------------------------------------------------------
   ;   >> MAIN LOOP
   ; ----------------------------------------------------------------
   Do
   
      ;  Clear The Screen
      Cls
   

      ; Run Through and update/draw and kill the charcters in the object array
      ProcessObjects()
      


      ; randomly add new batchs of objects to the list      
      if Rnd(1000)>500
         for lp =0 to rnd(10)
            SpawnObject()
         next
      endif
      
      ; show the screen to the user   
      Sync
   loop EscKey()=true
   
   
   End






   ; -------------------------------------------------------------
   ; This sub routine randomly spawns a single object.
   ; -------------------------------------------------------------

Psub SpawnObject()

   index =GetFreeCell(Objects())
   
   Objects(Index)=new tObject

   Objects(Index).x         =rnd(800)
   Objects(Index).y         =rnd(600)
   Objects(Index).Angle      =rnd(360)
   Objects(Index).Speed      =rndRange#(1,5)
   Objects(Index).Size      =rndRange#(10,20)
   Objects(Index).Colour   =rndrgB()
   

EndPsub


   ; -------------------------------------------------------------
   ; This sub routine randomly spawns a single object.
   ; -------------------------------------------------------------


Psub ProcessObjects()


   ; Work out a clipping area that all characters will be clipped against
   pad=50
   ViewPortX1=-Pad
   ViewPortY1=-Pad
   ViewPortX2=GetScreenWidth()+Pad
   ViewPortY2=GetScreenHeight()+Pad
   
   
   ; lock the screen buffer, to help with drawing batches of circles
   lockbuffer

   ; for through all array from Index #1 to it's highest
   For lp=1 to GetArrayElements(objects())


      ; Check this type exists ?  If so, we update the object
      ; if not we can stop looping, since we're at the end of the
      ; objects     
      if Objects(lp)
      
            
            ; get this objects angle and speed
            Angle#=Objects(lp).Angle
            Speed#=Objects(lp).Speed

            ; calc the objects new position            
            x#=Objects(lp).X+Cos(Angle#)*Speed#
            y#=Objects(lp).y+Sin(Angle#)*Speed#
            

            ; check if the object still in legal space          
            if PointInBox(X#,y#,ViewPortX1,ViewPortY1,ViewPortX2,ViewPortY2)=false

               ; Kill this object can copy the following cells up
               RemoveObject(lp)
               
               ; Subtract one from the LP counter,so we don't step over any objects
               ; that may have been copied back
               lp--
               
               ; Jump to the end of this loop and continue for loop
               Continue
            endif


            ; it's alive so we draw it
            Circlec x#,y#,Objects(lp).size,true,Objects(lp).Colour

            ; store it's new position
            Objects(lp).X=x#
            Objects(lp).Y=Y#
      
      
      else
      
         ; if the objects doesn't, then we're at the end of the active objects
         ; so we can exit this for loop now
         Exitfor

      endif   
   
   next

   ; release our lock of screen
   unlockbuffer

EndPsub



   ; This object copies (well scrolls) all the cells bellow it up one slot

Psub RemoveObject(Index)

   Size=GetArrayElements(Objects())
   if Index>=1 and Index<=Size
   
      ; Copy the following cells up one place
      CopyArrayCells  Objects(),Index+1,1,Objects(),Index,1,Size


      ; KILL the last object just in case something was there
      Objects(Size)   = NULL
   endif      

EndPsub

[/pbcode]



       EXAMPLE #2

       This version doesn't bother reclaiming delete indexes like the previous version, this allows the object to persist in the same location within the array , but we get some extra looping overhead of when the array contains null objects.    if the Object count in the game was going to fluctuates a lot, then it'd be handy to monitor the size of array every now and then and shrinking it where possible.  


[pbcode]


   ; -------------------------------------------------------------
   ; Declare type to hold the properties of our game character
   ; -------------------------------------------------------------
   Type tObject
         x#
         y#   
         angle#
         Speed#
         Size
         Colour
   EndType


   ; Create an array with 100 cells of type tObject
   Dim Objects(100) as tObject
   
   

   ; ----------------------------------------------------------------
   ;   >> MAIN LOOP
   ; ----------------------------------------------------------------
   Do
   
      ;  Clear The Screen
      Cls
   

      ; Run Through and update/draw and kill the charcters in the object array
      ProcessObjects()
      


      ; randomly add new batchs of objects to the list      
      if Rnd(1000)>500
         for lp =0 to rnd(10)
            SpawnObject()
         next
      endif
      
      
      ; show the screen to the user   
      Sync
   loop EscKey()=true
   
   
   End






   ; -------------------------------------------------------------
   ; This sub routine randomly spawns a single object.
   ; -------------------------------------------------------------

Psub SpawnObject()

   index =GetFreeCell(Objects())
   
   Objects(Index)=new tObject

   Objects(Index).x         =rnd(800)
   Objects(Index).y         =rnd(600)
   Objects(Index).Angle      =rnd(360)
   Objects(Index).Speed      =rndRange#(1,5)
   Objects(Index).Size      =rndRange#(10,20)
   Objects(Index).Colour   =rndrgB()
   

EndPsub


   ; -------------------------------------------------------------
   ; This sub routine randomly spawns a single object.
   ; -------------------------------------------------------------


Psub ProcessObjects()


   ; Work out a clipping area that all charcters will be clipped against
   pad=50
   ViewPortX1=-Pad
   ViewPortY1=-Pad
   ViewPortX2=GetScreenWidth()+Pad
   ViewPortY2=GetScreenHeight()+Pad
   
   
   ; lock the screen buffer, to help with drawing batches of circles
   lockbuffer

   ; for through all array from Index #1 to it's highest
   For lp=1 to GetArrayElements(objects())


      ; Check this type exists ?  If so, we update the object
      ; if not we can stop looping, since we're at the end of the
      ; objects     
      if Objects(lp)
      
            
            ; get this objects angle and speed
            Angle#=Objects(lp).Angle
            Speed#=Objects(lp).Speed

            ; calc the objects new position            
            x#=Objects(lp).X+Cos(Angle#)*Speed#
            y#=Objects(lp).y+Sin(Angle#)*Speed#
            

            ; check if the object still in legal space          
            if PointInBox(X#,y#,ViewPortX1,ViewPortY1,ViewPortX2,ViewPortY2)=false

               ; Kill this object
               Objects(lp)=NUll
               
               
               ; Jump to the end of this loop and continue for loop
               Continue
            endif


            ; it's alive so we draw it
            Circlec x#,y#,Objects(lp).size,true,Objects(lp).Colour

            ; store it's new position
            Objects(lp).X=x#
            Objects(lp).Y=Y#
      
      
      endif   
   
   next

   ; release our lock of screen
   unlockbuffer


EndPsub

[/pbcode]
 

 

     Related Examples:

      * Object Management (Character Life Cycles)  (http://www.underwaredesign.com/forums/index.php?topic=3274.0)
      * Manual Type Caching  (http://www.underwaredesign.com/forums/index.php?topic=3284.0)
      * Array Allocation Management Examples (http://www.underwaredesign.com/forums/index.php?topic=2555.0)
      * Linked List / SpriteHit  Game Frame Work Example (http://www.underwaredesign.com/forums/index.php?topic=2259.0)
      * Linked List of Typed Pointers (http://www.underwaredesign.com/forums/index.php?topic=2052.0)
      * Type List Example (http://www.underwaredesign.com/forums/index.php?topic=1730.0)
      * Manual Link Lists  (http://www.underwaredesign.com/forums/index.php?topic=1026.0)