Object Management (Character Life Cycles)

Started by kevin, November 27, 2009, 11:59:22 AM

Previous topic - Next topic

kevin




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

PlayBASIC Code: [Select]
   ; 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








 
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.



PlayBASIC Code: [Select]
   ; 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




 
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)


PlayBASIC Code: [Select]
   ; 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








 
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.


PlayBASIC Code: [Select]
   ; 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








 
Example #5  (Character Life Cycles)



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


PlayBASIC Code: [Select]
   ; 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
Login required to view complete source code





 
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.  

PlayBASIC Code: [Select]
   ; 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









  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

   * How To Handle More than One Object (Source Code ONly)

   * Moving an object between two points