UnderwareDESIGN

PlayBASIC => Resources => Tutorials => Topic started by: kevin on November 27, 2009, 11:59:22 AM

Title: Object Management (Character Life Cycles)
Post by: kevin on November 27, 2009, 11:59:22 AM

(http://www.underwaredesign.com/PlayBasicSig.png)

Object Management (Character Life Cycles):

Document Revision: V0.01



Q. What is this ?  


      A.  This tutorial introduces a concept of  managing the life cycles of a many characters within our game.     If we think about it, the characters in our games will generally all have three main life states.

   
They're Born,   they live out their purpose and ultimately they die.

    So in this following post we're going to use Typed Array to hold handle various game characters.  The initially version starts out simple, and shows how we can presents characters in typed arrays,  with each revision we progress the code until we've create create a frame work that can allow us to manage as many characters as need be.    
 




Q. Typed Arrays are for handling Many Objects ?  


     A.  Generally Yes.      If your game needs to control more than one moving object, then variables are not the way approach this.   Variables are good for storing individual bits of information about a single game character, but they soon become a nightmare when  we wish to expand beyond handling one character to handling many characters.    For this we need arrays

         An array is simply a collection(container) of many variables that we can access through an numeric index.    Bellow is an example that uses a TYPED ARRAY to store and display two game characters (as circles).



 
Example #1


  Refer to the HELP under ABOUT -> TYPES and ABOUT -> ARRAYS..

   This example sets up the frame work that

[pbcode]


   ; Declare a type that will describe all the of required properties that
   ; each of our game character will have

   Type tObject
         x#,y#       ; it's position on screen
         size         ; size of the object
         colour      ; colour of this object
   EndType
   
   ; create an array with space for 10 objects to be stored within
   Dim Ball(10) as tObject


   ; When we dim an array it's contents are empty,  so next well manually create 2 ball objects

   ; --------------------
   ; Create Object #1
   ; --------------------

   ;  This ball with be position in the center of the default screen, has 40 pixel radius
   ; an be RED
   
   Ball(1) = New Tobject
   Ball(1).x# = 400
   Ball(1).y# = 300
   Ball(1).size = 40
   Ball(1).colour =rgb(255,0,0)  ; set colour to red
   
   
   


   ; --------------------
   ; Create Object #2
   ; --------------------

   ;  This ball with be positioned in the top left part of the screen,
   ; it'll be 20 pixel radius and be coloured green.
   
   Ball(2) = New Tobject
   Ball(2).x# = 100
   Ball(2).y# = 100
   Ball(2).size = 20
   Ball(2).colour =rgb(0,255,0)  ; set colour to green
   

   

   ; ------------------------------------------------------------
   ; Draw all of the objects in our array as circles on the screen
   ; ------------------------------------------------------------

   for Obj=1 to 10
      ; check if this ball object exists ?? - We only created 2 objects, and our array
      ; has space for 10. So we only want to di8splay the one's that exist.
      if Ball(Obj)

            ; get this balls X# & Y# position
            x#=ball(obj).x
            y#=ball(obj).y
            ; get its size, which we'll use the circles radius
            Radius=ball(obj).size

            ; get it's colour
            colour=ball(obj).colour   

            ; draw a circle to represent this character on screen
            circlec x#,y#,radius,true,colour

      endif   
   next

   Print "Done"
   Sync
   waitkey
   

[/pbcode]




 
Example #2 - Basic Character Management


   This version builds upon the version above,  the main difference is that this version adds some speed fields to the character properties.  These properties are used as the speed this particular  character  is moving in.  

   So unlike the first example, this time when we draw the characters,  we're also adding the speed parameters to the position.  This will move the character in whatever direction/speed was set.   After we add the old position with the speed, we draw the character at it's new position then store it's new position back in the array.   So each time this process is executed, the characters will appear to move in whatever direction  they're set to.



[pbcode]

   ; Declare a type that will describe all the of required properties that
   ; each of our game character will have

   Type tObject
         x#,y#       ; it's position on screen
         SpeedX#      ; The Speed (along the X axis) the character is moving
         SpeedY#      ; The Speed (along the y axis) the character is moving
         size         ; size of the object
         colour      ; colour of this object
   EndType
   
   ; create an array with space for 10 objects to stored within
   Dim Ball(10) as tObject


   ; When we dim an array it's contents are empty,  so next well manually create 2 objects

   ; --------------------
   ; Create Object #1
   ; --------------------

   ;  This ball with be position in the cventer of the default screen, has 40 pixel radius
   ; an be RED
   
   Ball(1) = New Tobject
   Ball(1).x# = 400
   Ball(1).y# = 300
   Ball(1).speedx# = 1
   Ball(1).speedy# = 0

   Ball(1).size = 40
   Ball(1).colour =rgb(255,0,0)  ; set colour to red
   
   
   


   ; --------------------
   ; Create Object #2
   ; --------------------

   ;  This ball with be positioned in the top left part of the screen,
   ; it'll be 20 pixel radius and be coloured green.
   
   Ball(2) = New Tobject
   Ball(2).x# = 100
   Ball(2).y# = 100
   Ball(2).speedx# = 0
   Ball(2).speedy# = 1
   Ball(2).size = 20
   Ball(2).colour =rgb(0,255,0)  ; set colour to green
   




   ; Tell PB to limit the refresh rate (The number of syncs per second) to 30 frames per second
   Setfps 30



Do

   Cls 0
   
   ; ------------------------------------------------------------
   ; Draw all of the objects in our array as circles on the screen
   ; ------------------------------------------------------------

   for Obj=1 to 10
      ; check if this ball object exists ?? - We only created 2 objects, and our array
      ; has space for 10. So we only want to di8splay the one's that exist.
      if Ball(Obj)

            ; get this balls X# & Y# position  & and his objects Speed values to it
            x#=ball(obj).x+ball(obj).Speedx
            y#=ball(obj).y+ball(obj).Speedy

            ; get its size, which we'll use the circles radius
            Radius=ball(obj).size

            ; get it's colour
            colour=ball(obj).colour   

            ; draw a circle to represent this character on screen at it's current position
            circlec x#,y#,radius,true,colour

            ; store the characters new position (the position it was drawn in)
            ball(obj).x=x#
            ball(obj).y=y#

      endif   
   next

   Sync
loop
[/pbcode]


 
Example #3


   This version builds upon the example #2.  The main changes are we're monitoring the X# & y# coordinate of each character.  if the character leaves the screen,  then we reset it's position.  So the character appears to moving infinitely. (never dies)


[pbcode]

   ; Declare a type that will describe all of the required properties that
   ; each of our game character will have

   Type tObject
         x#,y#       ; it's position on screen
         SpeedX#      ; The Speed (along the X axis) the character is moving
         SpeedY#      ; The Speed (along the y axis) the character is moving
         size         ; size of the object
         colour      ; colour of this object
   EndType
   
   ; create an array with space for 10 objects to stored within
   Dim Ball(10) as tObject


   ; When we dim an array it's contents are empty,  so next well manually create 2 objects

   ; --------------------
   ; Create Object #1
   ; --------------------

   ;  This ball with be position in the cventer of the default screen, has 40 pixel radius
   ; an be RED
   
   Ball(1) = New Tobject
   Ball(1).x# = 400
   Ball(1).y# = 300
   Ball(1).speedx# = -2
   Ball(1).speedy# = 0

   Ball(1).size = 40
   Ball(1).colour =rgb(255,0,0)  ; set colour to red
   
   
   


   ; --------------------
   ; Create Object #2
   ; --------------------

   ;  This ball with be positioned in the top left part of the screen,
   ; it'll be 20 pixel radius and be coloured green.
   
   Ball(2) = New Tobject
   Ball(2).x# = 100
   Ball(2).y# = 100
   Ball(2).speedx# = 2
   Ball(2).speedy# = 1
   Ball(2).size = 20
   Ball(2).colour =rgb(0,255,0)  ; set colour to green
   




   ; Tell PB to limit the refresh rate (The number of syncs per second) to 30 frames per second
   Setfps 60



Do

   Cls 0
   

   ; ------------------------------------------------------------
   ; Draw all of the objects in our array as circles on the screen
   ; ------------------------------------------------------------

   for Obj=1 to 10
      ; check if this ball object exists ?? - We only created 2 objects, and our array
      ; has space for 10. So we only want to display the one's that actually exist within this array.
      if Ball(Obj)

            ; get this balls X# & Y# position  & and his objects Speed values to it
            x#=ball(obj).x+ball(obj).Speedx
            y#=ball(obj).y+ball(obj).Speedy

            ; check if the X# position is within the screen bounds
            if x#<0 then x#=800
            if x#>800 then x#=0

            if y#<0 then y#=800
            if y#>600 then y#=0


            ; get its size, which we'll use the circles radius
            Radius=ball(obj).size

            ; get it's colour
            colour=ball(obj).colour   

            ; draw a circle to represent this character on screen at it's current position
            circlec x#,y#,radius,true,colour






            ; store the characters new position (the position it was drawn in)
            ball(obj).x=x#
            ball(obj).y=y#

      endif   
   next



   Sync
loop
   

[/pbcode]




 
Example #4  (Character Life Cycles)


   This version builds upon the example #2 & 3.  Except this version introduces the concept of character life cycles.  In this version, when a character leaves the screen,  rather than rebound it's position,  we're KILLING it.   When we kill something,  we're removing it from the Array.  

    What this sample shows us how we can create characters, manage/draw and ultimately kill them.   This is an important principal to grasp as it's found in virtually every video game ever made.


[pbcode]

   ; Declare a type that will describe all of the required properties that
   ; each of our game character will have

   Type tObject
         x#,y#       ; it's position on screen
         SpeedX#      ; The Speed (along the X axis) the character is moving
         SpeedY#      ; The Speed (along the y axis) the character is moving
         size         ; size of the object
         colour      ; colour of this object
   EndType
   
   ; create an array with space for 10 objects to stored within
   Dim Ball(10) as tObject


   ; When we dim an array it's contents are empty,  so next well manually create 2 objects

   ; --------------------
   ; Create Object #1
   ; --------------------

   ;  This ball with be position in the cventer of the default screen, has 40 pixel radius
   ; an be RED
   
   Ball(1) = New Tobject
   Ball(1).x# = 400
   Ball(1).y# = 300
   Ball(1).speedx# = -2
   Ball(1).speedy# = 0

   Ball(1).size = 40
   Ball(1).colour =rgb(255,0,0)  ; set colour to red
   
   
   


   ; --------------------
   ; Create Object #2
   ; --------------------

   ;  This ball with be positioned in the top left part of the screen,
   ; it'll be 20 pixel radius and be coloured green.
   
   Ball(2) = New Tobject
   Ball(2).x# = 100
   Ball(2).y# = 100
   Ball(2).speedx# = 2
   Ball(2).speedy# = 1
   Ball(2).size = 20
   Ball(2).colour =rgb(0,255,0)  ; set colour to green
   




   ; Tell PB to limit the refresh rate (The number of syncs per second) to 30 frames per second
   Setfps 60



Do

   Cls 0
   

   ; ------------------------------------------------------------
   ; Draw all of the objects in our array as cicles on the screen
   ; ------------------------------------------------------------

   Number_OF_Living_Objects=0
   

   for Obj=1 to 10

      ; check if this ball object exists ?? - We only created 2 objects, and our array
      ; has space for 10. So we only want to di8splay the one's that exist.
      if Ball(Obj)

            ; get this balls X# & Y# position  & and his objects Speed values to it
            x#=ball(obj).x+ball(obj).Speedx
            y#=ball(obj).y+ball(obj).Speedy

            ; check if the new position is inside the screens X & Y bounds, if it's not, we'll KILL this object
            if x#<0 or x#>800 or y#<0 or Y#>600
            
                  // THis object has left the screen, so lets kill it (remove it from the Ball() array
                  Ball(Obj) = NULL

                  ; since this object has been removed,  we don't do want PB to continue and try and access
                  ; this object anymore.
                  
                  Continue ;  This jumps us out of this loop and CONTINUES on with the next FOR/NEXT loop
            endif


            ; get its size, which we'll use the circles radius
            Radius=ball(obj).size

            ; get it's colour
            colour=ball(obj).colour   

            ; draw a circle to represent this character on screen at it's current position
            circlec x#,y#,radius,true,colour



            ; store the characters new position (the position it was drawn in)
            ball(obj).x=x#
            ball(obj).y=y#

            ; bump the counter for how many objects are still alive
            inc Number_OF_Living_Objects

      endif   


   next


   print "Number of living objects="+Str$(Number_OF_Living_Objects)


   Sync
loop
   


[/pbcode]



 
Example #5  (Character Life Cycles)



  This version extends example #4, this one adds a function to 'randomly' spawn a character.  


[pbcode]


   ; Declare a type that will describe al of the required properties that
   ; each of our game character will have

   Type tObject
         x#,y#       ; it's position on screen
         SpeedX#      ; The Speed (along the X axis) the character is moving
         SpeedY#      ; The Speed (along the y axis) the character is moving
         size         ; size of the object
         colour      ; colour of this object
   EndType
   
   ; create an array with space for 10 objects to stored within
   Dim Ball(10) as tObject


   ; When we dim an array it's contents are empty,  so next well manually create 2 objects

   ; --------------------
   ; Create Object #1
   ; --------------------

   ;  This ball with be position in the cventer of the default screen, has 40 pixel radius
   ; an be RED
   
   Ball(1) = New Tobject
   Ball(1).x# = 400
   Ball(1).y# = 300
   Ball(1).speedx# = -2
   Ball(1).speedy# = 0

   Ball(1).size = 40
   Ball(1).colour =rgb(255,0,0)  ; set colour to red
   
   
   


   ; --------------------
   ; Create Object #2
   ; --------------------

   ;  This ball with be positioned in the top left part of the screen,
   ; it'll be 20 pixel radius and be coloured green.
   
   Ball(2) = New Tobject
   Ball(2).x# = 100
   Ball(2).y# = 100
   Ball(2).speedx# = 2
   Ball(2).speedy# = 1
   Ball(2).size = 20
   Ball(2).colour =rgb(0,255,0)  ; set colour to green
   




   ; Tell PB to limit the refresh rate (The number of syncs per second) to 30 frames per second
   Setfps 60



Do

   Cls 0


   ; Check if the user presses the space bar
   
   if SpaceKey()=true
      ; create a ball
      RandomlyCreateBall()
   
   endif

   

   ; ------------------------------------------------------------
   ; Draw all of the objects in our array as cicles on the screen
   ; ------------------------------------------------------------

   Number_OF_Living_Objects=0
   
   
   for Obj=1 to GetArrayElements(Ball(),1)

      ; check if this ball object exists ?? - We only created 2 objects, and our array
      ; has space for 10. So we only want to di8splay the one's that exist.
      if Ball(Obj)

            ; get this balls X# & Y# position  & and his objects Speed values to it
            x#=ball(obj).x+ball(obj).Speedx
            y#=ball(obj).y+ball(obj).Speedy

            ; check if the new position is inside the screens X & Y bounds, if it's not, we'll KILL this object
            if x#<0 or x#>800 or y#<0 or Y#>600
            
                  // THis object has left the screen, so lets kill it (remove it from the Ball() array
                  Ball(Obj) = NULL

                  ; since this object has been removed,  we don't do want PB to continue and try and access
                  ; this object anymore.
                  
                  Continue ;  This jumps us out of this loop and CONTINUES on with the next FOR/NEXT loop
            endif


            ; get its size, which we'll use the circles radius
            Radius=ball(obj).size

            ; get it's colour
            colour=ball(obj).colour   

            ; draw a circle to represent this character on screen at it's current position
            circlec x#,y#,radius,true,colour



            ; store the characters new position (the position it was drawn in)
            ball(obj).x=x#
            ball(obj).y=y#

            ; bump the counter for how many objects are still alive
            inc Number_OF_Living_Objects

      endif   


   next


   print "Number of living objects="+Str$(Number_OF_Living_Objects)


   Sync
loop
   


Function RandomlyCreateBall()

   ; ask PB to locate a FREE (unused cell) in the ball array, if a spot can't be found it'll expand
   ; BALL() array for you
   Index =GetFreeCell(Ball())

   ; init this objects
   Ball(Index) = New Tobject
   Ball(Index).x# = rnd(800)      ; screen x position
   Ball(Index).y# = rnd(600)      ; screen y position

   Angle#=rnd(360)   ; pick and angle this object will move in
   Speed#=Rndrange#(1,5)  ; pick the speed of this object
   Ball(Index).speedx# = cos(angle#)*Speed#
   Ball(Index).speedy# = sin(angle#)*Speed#


   Ball(Index).size = rndrange(10,50)      ; random size between 10, and 50 pixel radius
   Ball(Index).colour =rndrgb()   ; random colour
   
EndFunction

[/pbcode]




 
Example #6  (Character Life Cycles)



    In this version we're created functions to simplify the creation process for us.    In this version we've added a function called CreateNewBall,  this function will create a new ball character in the ball() array and initialized it's properties with whatever we pass this function.    So any time we need to create a ball, we can just call our 'custom' function rather than manually initializing it like the previous examples do.  

[pbcode]

   ; Declare a type that will describe al of the required properties that
   ; each of our game character will have

   Type tObject
         x#,y#       ; it's position on screen
         SpeedX#      ; The Speed (along the X axis) the character is moving
         SpeedY#      ; The Speed (along the y axis) the character is moving
         size         ; size of the object
         colour      ; colour of this object
   EndType
   
   ; create an array with space for 10 objects to stored within
   Dim Ball(10) as tObject


   ; When we dim an array it's contents are empty,  so next well manually create 2 objects

   ; --------------------
   ; Create Object
   ; --------------------

   CreateNewBall(400,300,2,180,40,rgb (255,0,0))


   ; --------------------
   ; Create Object
   ; --------------------

   CreateNewBall(100,100,2,180+45,20,rgb(0,255,0))


   ; Tell PB to limit the refresh rate (The number of syncs per second) to 30 frames per second
   Setfps 60



Do

   Cls 0


   ; Check if the user presses the space bar
   
   if SpaceKey()=true
      ; create a ball
      RandomlyCreateBall()
   
   endif

   

   ; ------------------------------------------------------------
   ; Draw all of the objects in our array as cicles on the screen
   ; ------------------------------------------------------------

   Number_OF_Living_Objects=0
   
   
   for Obj=1 to GetArrayElements(Ball(),1)

      ; check if this ball object exists ?? - We only created 2 objects, and our array
      ; has space for 10. So we only want to di8splay the one's that exist.
      if Ball(Obj)

            ; get this balls X# & Y# position  & and his objects Speed values to it
            x#=ball(obj).x+ball(obj).Speedx
            y#=ball(obj).y+ball(obj).Speedy

            ; check if the new position is inside the screens X & Y bounds, if it's not, we'll KILL this object
            if x#<0 or x#>800 or y#<0 or Y#>600
            
                  // THis object has left the screen, so lets kill it (remove it from the Ball() array
                  Ball(Obj) = NULL

                  ; since this object has been removed,  we don't do want PB to continue and try and access
                  ; this object anymore.
                  
                  Continue ;  This jumps us out of this loop and CONTINUES on with the next FOR/NEXT loop
            endif


            ; get its size, which we'll use the circles radius
            Radius=ball(obj).size

            ; get it's colour
            colour=ball(obj).colour   

            ; draw a circle to represent this character on screen at it's current position
            circlec x#,y#,radius,true,colour



            ; store the characters new position (the position it was drawn in)
            ball(obj).x=x#
            ball(obj).y=y#

            ; bump the counter for how many objects are still alive
            inc Number_OF_Living_Objects

      endif   


   next


   print "Number of living objects="+Str$(Number_OF_Living_Objects)


   Sync
loop
   



Function CreateNewBall(x#,y#,speed#,angle#,radius,colour)

   ; ask PB to locate a FREE (unused cell) in the ball array, if a spot can't be found it'll expand
   ; BALL() array for you
   Index =GetFreeCell(Ball())

   ; init this objects
   Ball(Index) = New Tobject
   Ball(Index).x# = x#      ; screen x position
   Ball(Index).y# = y#      ; screen y position
   Ball(Index).speedx# = cos(angle#)*Speed#
   Ball(Index).speedy# = sin(angle#)*Speed#
   Ball(Index).size = radius   
   Ball(Index).colour =colour
   
EndFunction Index




Function RandomlyCreateBall()
   ThisBall=CreateNewBall(rnd(800),rnd(600),rndrange#(1,5),rnd(360),rndrange(10,50),rndrgb())
EndFunction ThisBall

[/pbcode]






  At this point, we've got a frame work that allows us to manage as many game characters as required.  Each character is born,  lives out it's life within the game, then dies...  

  The challenge for the reader is now example this example to handle, many different types of objects...      



Video





Related Articles

   * Introduction to Animation (http://www.underwaredesign.com/forums/index.php?topic=3201.0)

   * How To Handle More than One Object (Source Code ONly) (http://www.underwaredesign.com/forums/index.php?topic=978.0)

   * Moving an object between two points (http://www.underwaredesign.com/forums/index.php?topic=989.0)



Return To PlayBASIC Tutorial Index (http://www.underwaredesign.com/forums/index.php?topic=2552.0)