UnderwareDESIGN

PlayBASIC => Resources => Tutorials => Topic started by: kevin on January 02, 2006, 06:55:41 AM

Title: How To Handle More than One Object
Post by: kevin on January 02, 2006, 06:55:41 AM
Sorry This tutorial is code only for now.




[pbcode]

; Make a ball image
 Size=100
 CreateImage 1,Size,Size
 RenderPhongImage 1,Size/2,Size/2,$ffff8f,size*0.9,2.0


; define a ball type
  Type tBall
        Status
        Xpos,Ypos
        SpeedX,SpeedY
    Image
    LifeTimer
    FlashToggle
  EndType

; create an array to house our list of balls
dim Balls(1) as tBall



; Main Loop

Do
   Cls rgb(20,30,40)
 Print "press space to create ball"
    

 UpdateBalls()
 
   ; Check for space key
 If SPacekey() and KeyPress=false

 ; Calc a random starting position for this ball
    Xpos=Rnd(GetScreenWIdth())
    Ypos=Rnd(GetScreenHeight())
   
 ; Create (init) a ball at this position and give it a random speed    
    CreateBall(Xpos,Ypos,NewSpeed(5),NewSpeed(5))

    KeyPress=True

 else
    If SPacekey()=false then KeyPress=false
 endif
   
   Sync   
loop



; this function finds a random speed for a ball axis.
Function NewSpeed(Max)
   Repeat
 Speed=RndRange(-max,max)   
   Until   Speed<>0
EndFunction Speed



Function UpdateBalls()
   ; run through all   
 ScreenWidth=GetSCreenWidth()
 ScreenHeight=GetSCreenHeight()
   
 CurrentTime=Timer()
   
 For lp=1 to GetArrayelements(Balls().tball,1)
    if Balls(lp).Status=True

   ThisImage=Balls(lp).Image
   ImageWidth   =GetImageWidth(ThisImage)/2
   ImageHeight   =GetImageHeight(ThisImage)/2
   
    ; Move the ball on the X axis
   NewXpos=Balls(lp).Xpos+Balls(lp).SpeedX

    ; Check for Left Edge redbound
   If NewXpos<=ImageWidth
      NewXpos=ImageWidth   
      Balls(lp).SpeedX=Balls(lp).SpeedX*-1
   endif
    
    ; check for right edge rebound
   If NewXpos=>(ScreenWidth-ImageWidth)
      NewXpos=ScreenWidth-ImageWidth   
      Balls(lp).SpeedX=Balls(lp).SpeedX*-1
   endif
   
    ; MOve the ball along the y axis
   NewYpos=Balls(lp).Ypos+Balls(lp).SpeedY
    ; Check for Left Edge redbound
   If NewYpos<ImageHeight
      NewYpos=ImageHeight
      Balls(lp).SpeedY=-Balls(lp).SpeedY
   endif
    
    ; check for right edge rebound
   If NewYpos>(ScreenHeight-ImageHeight)
      NewYpos=ScreenHeight-ImageHeight   
      Balls(lp).SpeedY=-Balls(lp).SpeedY
   endif

    ; Store this balls position
   Balls(lp).Xpos=NewXpos
   Balls(lp).Ypos=NewYpos


   LifeTimeLeft=Balls(lp).LifeTimer-CurrentTime
   if LifeTimeLeft<0
      DeleteBall(lp)   
   else
      
   ; Check if the ball has less than a second to live
      if LifeTimeLeft<500
        
     Balls(lp).FlashToggle=Mod(Balls(lp).FlashToggle+1,8)

     if Balls(lp).FlashToggle>3
        drawimage ThisIMage,NewXpos-imagewidth,NewYpos-imageheight,1  
     endif
    
     CenterText NewXpos,NewYpos,LifeTimeLeft
     
      else
     ; draw the image to represent this ball    
        drawimage ThisIMage,NewXpos-imagewidth,NewYpos-imageheight,1  
      endif

   endif    


    endif
 next
   
   
EndFunction


; Some Helper Functionsto deals with balls

Function CreateBall(Xpos,Ypos,SpeedX,Speedy)
   ; Get a free Ball Index    
  ThisBall=GetFreeBall()

   ; init it's settimgs
     Balls(ThisBall).status=True
     Balls(ThisBall).xpos  =xpos
     Balls(ThisBall).ypos  =ypos
     Balls(ThisBall).SpeedX  =SpeedX
     Balls(ThisBall).SpeedY  =SpeedY

     Balls(ThisBall).Image  =1

   ; Define this balls lifes span to end 5 seconds from now
 Balls(ThisBall).LifeTimer =Timer()+3000

 Balls(ThisBall).FlashToggle=0

EndFunction ThisBall



Function DeleteBall(ThisBall)
   If Balls(thisBall).status=true
 CleararrayCells  Balls().tball,ThisBal,0,1,0
   endif
EndFunction


; Scan the array looking for a free Ball (any ball that has
; it's status set to FALSE we'll considered free for use)
Function GetFreeBall()

   ; run through the array (no matter how big it is)
 For lp=1 to GetArrayelements(Balls().tball,1)
    if Balls(lp).Status=false
   Ballindex=lp
   exit
    endif  
 next

   ; If it couldn't find a free Array Cell, then expand the array
 if BallIndex=0
    BallIndex=lp+1
    Redim Balls(GetArrayelements(Balls().tball,1)*2) as Tball     
 endif


EndFunction BallIndex
[/pbcode]




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


Title: Re: How To Handle More than One Object
Post by: kevin on July 02, 2007, 11:11:08 PM
 Here's an alternative version of the above example.    This one uses  GetArrayCells() for to find free indexs within the Balls() array, then it uses the NULL writing to delete a type within the array.


[pbcode]
; Make a ball image
 Size=100
 CreateImage 1,Size,Size
 RenderPhongImage 1,Size/2,Size/2,$ffff8f,size*0.9,2.0


; define a ball type
  Type tBall
        Status
        Xpos,Ypos
        SpeedX,SpeedY
           Image
           LifeTimer
           FlashToggle
  EndType

; create an array to house our list of balls
 dim Balls(1) as tBall


; -----------------------------------------
; Main Loop
; -----------------------------------------

Do
  ; Clear the Screen
   Cls rgb(20,30,40)
  ; Display Controls
 Print "press space to create ball"
    

  ; Call the UpdateBalls() function
 UpdateBalls()
 
   ; Check for space key
 If SPacekey()=true and KeyPress=false

     ; Calc a random starting position for this ball
        Xpos=Rnd(GetScreenWIdth())
        Ypos=Rnd(GetScreenHeight())
   
     ; Create (init) a ball at this position and give it a random speed    
        CreateBall(Xpos,Ypos,NewSpeed(5),NewSpeed(5))

        KeyPress=True

 else
        If SPacekey()=false then KeyPress=false
 endif
   
   Sync   
loop



; this function finds a random speed for a ball axis.
Function NewSpeed(Max)
   Repeat
        Speed=RndRange(-max,max)   
   Until   Speed<>0
EndFunction Speed



Function UpdateBalls()
   ; run through all   
 ScreenWidth=GetSCreenWidth()
 ScreenHeight=GetSCreenHeight()
   
 CurrentTime=Timer()
   
 For lp=1 to GetArrayelements(Balls().tball,1)
    if Balls(lp).Status=True

   ThisImage=Balls(lp).Image
   ImageWidth      =GetImageWidth(ThisImage)/2
   ImageHeight   =GetImageHeight(ThisImage)/2
   
    ; Move the ball on the X axis
   NewXpos=Balls(lp).Xpos+Balls(lp).SpeedX

    ; Check for Left Edge redbound
   If NewXpos<=ImageWidth
      NewXpos=ImageWidth   
      Balls(lp).SpeedX=Balls(lp).SpeedX*-1
   endif
    
    ; check for right edge rebound
   If NewXpos=>(ScreenWidth-ImageWidth)
      NewXpos=ScreenWidth-ImageWidth   
      Balls(lp).SpeedX=Balls(lp).SpeedX*-1
   endif
   
    ; MOve the ball along the y axis
   NewYpos=Balls(lp).Ypos+Balls(lp).SpeedY
    ; Check for Left Edge redbound
   If NewYpos<ImageHeight
      NewYpos=ImageHeight
      Balls(lp).SpeedY=-Balls(lp).SpeedY
   endif
    
    ; check for right edge rebound
   If NewYpos>(ScreenHeight-ImageHeight)
      NewYpos=ScreenHeight-ImageHeight   
      Balls(lp).SpeedY=-Balls(lp).SpeedY
   endif

    ; Store this balls position
   Balls(lp).Xpos=NewXpos
   Balls(lp).Ypos=NewYpos


   LifeTimeLeft=Balls(lp).LifeTimer-CurrentTime
   if LifeTimeLeft<0
          DeleteBall(lp)   
         Continue
    Endif
      
   ; Check if the ball has less than a second to live
      if LifeTimeLeft<500
        
     Balls(lp).FlashToggle=Mod(Balls(lp).FlashToggle+1,8)

     if Balls(lp).FlashToggle>3
        drawimage ThisIMage,NewXpos-imagewidth,NewYpos-imageheight,1  
     endif
    
     CenterText NewXpos,NewYpos,LifeTimeLeft
     
      else
     ; draw the image to represent this ball    
        drawimage ThisIMage,NewXpos-imagewidth,NewYpos-imageheight,1  
      endif



    endif
 next
   
   
EndFunction


; Some Helper Functionsto deals with balls

Function CreateBall(Xpos,Ypos,SpeedX,Speedy)
   ; Get a free Array Index within the Balls() array  
  ThisBall=GetFreeCell(Balls())
 
   ; init it's settimgs
     Balls(ThisBall).status=True
     Balls(ThisBall).xpos  =xpos
     Balls(ThisBall).ypos  =ypos
     Balls(ThisBall).SpeedX  =SpeedX
     Balls(ThisBall).SpeedY  =SpeedY

     Balls(ThisBall).Image  =1

   ; Define this balls lifes span to end 5 seconds from now
     Balls(ThisBall).LifeTimer =Timer()+3000

     Balls(ThisBall).FlashToggle=0

EndFunction ThisBall



Function DeleteBall(ThisBall)
   If Balls(thisBall)
        Balls(thisBall)=Null
   endif
EndFunction
[/pbcode]

Title: Re: How To Handle More than One Object
Post by: kevin on July 02, 2007, 11:18:48 PM
 Here's a linked list version.

[pbcode]

; Make a ball image
 Size=100
 CreateImage 1,Size,Size
 RenderPhongImage 1,Size/2,Size/2,$ffff8f,size*0.9,2.0


; define a ball type
  Type tBall
        Xpos,Ypos
        SpeedX,SpeedY
           Image
           LifeTimer
           FlashToggle
  EndType

; create a linked list of called BALL of TBALL
 dim Ball as tBall list


; -----------------------------------------
; Main Loop
; -----------------------------------------

Do
  ; Clear the Screen
   Cls rgb(20,30,40)
  ; Display Controls
     Print "press space to create ball"
    

  ; Call the UpdateBalls() function
 UpdateBalls()
 
   ; Check for space key
 If SPacekey()=true and KeyPress=false

     ; Calc a random starting position for this ball
        Xpos=Rnd(GetScreenWIdth())
        Ypos=Rnd(GetScreenHeight())
   
     ; Create (init) a ball at this position and give it a random speed    
        CreateBall(Xpos,Ypos,NewSpeed(5),NewSpeed(5))

        KeyPress=True

 else
        If SPacekey()=false then KeyPress=false
 endif
   
   Sync   
loop



; this function finds a random speed for a ball axis.
Function NewSpeed(Max)
   Repeat
        Speed=RndRange(-max,max)   
   Until   Speed<>0
EndFunction Speed



Function UpdateBalls()
   ; run through all   
 ScreenWidth=GetSCreenWidth()
 ScreenHeight=GetSCreenHeight()
   
 CurrentTime=Timer()
   
 For Each Ball()
    
   ThisImage=Ball.Image
   ImageWidth      =GetImageWidth(ThisImage)/2
   ImageHeight   =GetImageHeight(ThisImage)/2
   
    ; Move the ball on the X axis
   NewXpos=Ball.Xpos+Ball.SpeedX

    ; Check for Left Edge redbound
   If NewXpos<=ImageWidth
      NewXpos=ImageWidth   
      Ball.SpeedX=Ball.SpeedX*-1
   endif
    
    ; check for right edge rebound
   If NewXpos=>(ScreenWidth-ImageWidth)
      NewXpos=ScreenWidth-ImageWidth   
      Ball.SpeedX=Ball.SpeedX*-1
   endif
   
    ; MOve the ball along the y axis
   NewYpos=Ball.Ypos+Ball.SpeedY
    ; Check for Left Edge redbound
   If NewYpos<ImageHeight
      NewYpos=ImageHeight
      Ball.SpeedY=-Ball.SpeedY
   endif
    
    ; check for right edge rebound
   If NewYpos>(ScreenHeight-ImageHeight)
      NewYpos=ScreenHeight-ImageHeight   
      Ball.SpeedY=-Ball.SpeedY
   endif

    ; Store this balls position
   Ball.Xpos=NewXpos
   Ball.Ypos=NewYpos


   LifeTimeLeft=Ball.LifeTimer-CurrentTime
   if LifeTimeLeft<0
         ; Kill This object in the list
         Ball = NULL
         Continue
    Endif
      
   ; Check if the ball has less than a second to live
      if LifeTimeLeft<500
        
         Ball.FlashToggle=Mod(Ball.FlashToggle+1,8)

         if Ball.FlashToggle>3
           drawimage ThisIMage,NewXpos-imagewidth,NewYpos-imageheight,true
        endif
       
        CenterText NewXpos,NewYpos,LifeTimeLeft
     
      else
        ; draw the image to represent this ball    
           drawimage ThisIMage,NewXpos-imagewidth,NewYpos-imageheight,true
      endif


 next
   
   
EndFunction



Function CreateBall(Xpos,Ypos,SpeedX,Speedy)
   ; Get a free Array Index within the Balls() array  
 
     Ball= New tBall
   ; init it's settimgs
     Ball.xpos  =xpos
     Ball.ypos  =ypos
     Ball.SpeedX  =SpeedX
     Ball.SpeedY  =SpeedY

     Ball.Image  =1

   ; Define this balls lifes span to end 5 seconds from now
     Ball.LifeTimer =Timer()+3000

     Ball.FlashToggle=0

EndFunction ThisBall


[/pbcode]