Main Menu

Timer Based Life Spans

Started by kevin, June 26, 2009, 02:35:17 AM

Previous topic - Next topic

kevin

 Timer Based Life Spans

  In this example we're using the time periods to dictate the life / death of a moving objects (in this case some circles).  Each object is given a spawn time (start), duration of it's life span (in milliseconds), as well as it's starting screen position and end screen position.        The code processes the array of objects and plots their position at any given time.   What this does is detaches the codes execution speed from the systems rendering speed.   So the objects will move at the same speed regardless of the computer speed,  the only differences the computer speed makes is the smoothness of motion.



 Controls:
            Space = Change FPS()
            ESC to exit.


Related To

  Time Based Movement


PlayBASIC Code: [Select]
   Type tPos
x#
y#
EndType

Type tEvent

StartTime
Duration
EndTime

Origin as Tpos
Target as Tpos
EndType

max=500

Dim Events(Max) as tEVent

for lp=1 to max

Events(lp).StartTime = Ticks ; When this event starts
Events(lp).Duration = rndrange(500,5000) ; Event can last from 1/2 a second to 5 seconds
Events(lp).EndTime = Ticks +Events(lp).Duration ; when it ends

; Starting position of object
Events(lp).Origin.x#=rnd(800)
Events(lp).Origin.y#=rnd(600)

; target/end position of object
Events(lp).Target.x#=rnd(800)
Events(lp).Target.y#=rnd(600)

; bump the ticks counter randomly, so the objects have
Ticks=Ticks+Rnd(100)
next




ProgramStartTime=timer()

; ------------------------------------------------------------------
; ------------------------------------------------------------------
Do

Cls rgb(0,0,0)

// Get the time since this loop started (in milliseconds)
CurrentTime=timer()- ProgramStartTime

ActivateEventCount=0
DeadEventCount=0

Count=GetArrayElements(Events().tEvent,1)
lockbuffer
For lp=1 to Count
if Events(lp)

// Check if the currentime is before the end of this event
if CurrentTime<Events(lp).EndTime

// Check if the currentime is beyond the startof this event. If so it must be active
if CurrentTime=>Events(lp).StartTime

// Get the time since this object came to life
TimePast#=CurrentTime-Events(lp).StartTime

// Divide the this objects life span duration (the time it's alive in milliseconds)
// into the time past since it was alive. This will give a scaler of 0.0-1.0
Scaler#=TimePast#/Events(lp).Duration

// Linearly interpolate the objects current coordinates from 'starting' position/end position
x#,y#=LerpPosition(Events(lp).Origin.x#,Events(lp).Origin.Y#,Events(lp).Target.x#,Events(lp).Target.y#, Scaler#)

// Draw the object at it's position at this point of it's life
Circle x#,y#,10,true

// Bump the Active event counter
inc ActivateEventCount

endif
else
//
Events(lp)=null
endif
else
inc DeadEventCount
endif
next
unlockbuffer
print "Number of Active Events ="+str$(ActivateEventCount)
print "Total Events ="+str$(Count)+" Events Left="+str$(Count-DeadEventCount)
print "Peek FPS="+Str$(GetfPS())
print "FPS ="+str$(Fps())


// press the space bar to force PB to restict the FPS to multiples of 5
if spacekey()
Rate=wrapvalue(Rate-5,0,60)
Setfps rate
flushkeys
endif



Sync
loop



Psub LerpPosition(OriginX#,OriginY#,DestX#,DestY#, Scaler#)
Scaler#=ClipRange#(Scaler#,0,1)
x#=OriginX#+((DestX#-OriginX#)*Scaler#)
y#=OriginY#+((DestY#-OriginY#)*Scaler#)
Endpsub x#,y#






kevin

#1
  Here's version of previous demo that can run forward and backwards. To do so, all we need is the time span that all objects will be created and die within, which is calculated during the object creation.  Once we have that, we can then ping pong through the time range forward/backward at will.


PlayBASIC Code: [Select]
   Type tPos
x#
y#
EndType

Type tEvent

StartTime
Duration
EndTime

Origin as Tpos
Target as Tpos
EndType

max=100

Dim Events(Max) as tEVent

// Variable to hold how long this demo will take in milliseconds
TotalExecutionTime=0

for lp=1 to max

Events(lp).StartTime = Ticks ; When this event starts
Events(lp).Duration = rndrange(500,5000) ; Event can last from 1/2 a second to 5 seconds
Events(lp).EndTime = Ticks +Events(lp).Duration ; when it ends

; Starting position of object
Events(lp).Origin.x#=rnd(800)
Events(lp).Origin.y#=rnd(600)

; target/end position of object
Events(lp).Target.x#=rnd(800)
Events(lp).Target.y#=rnd(600)


if Events(lp).EndTime>TotalExecutionTime
TotalExecutionTime=Events(lp).EndTime
endif

; bump the ticks counter randomly, so the objects have
Ticks=Ticks+Rnd(100)
next




ProgramStartTime=timer()

; ------------------------------------------------------------------
; ------------------------------------------------------------------
Do

// Clear the Screen.
Cls rgb(0,0,0)

If TimeDirection=0

// Get the time since this loop started (in milliseconds)
CurrentTime=timer()- ProgramStartTime
if CurrentTime>TotalExecutionTime
// Swap to time moving backward
Inc TimeDirection
CurrentTime=TotalExecutionTime
ProgramStartTime=Timer()
endif

else

// Get the time since this loop started (in milliseconds)
CurrentTime=TotalExecutionTime-(timer()- ProgramStartTime)
if CurrentTime<0
// Swap to time moving backward
Dec TimeDirection
CurrentTime=0
ProgramStartTime=Timer()
endif
endif

// Draw the scene at this time
Draw_Scene(CurrentTime)


// Time Direction.
If TimeDirection=0
Print "Time Moving Forward. "
else
Print "Time Moving Backward."
endif
print CurrentTime

Sync
loop





Function Draw_Scene(CurrentTime)

ActivateEventCount=0
DeadEventCount=0

Count=GetArrayElements(Events().tEvent,1)
lockbuffer
For lp=1 to Count

// Check if the currentime is before the end of this event
if CurrentTime<Events(lp).EndTime

// Check if the currentime is beyond the startof this event. If so it must be active
if CurrentTime=>Events(lp).StartTime

// Get the time since this object came to life
TimePast#=CurrentTime-Events(lp).StartTime

// Divide the this objects life span duration (the time it's alive in milliseconds)
// into the time past since it was alive. This will give a scaler of 0.0-1.0
Scaler#=TimePast#/Events(lp).Duration

// Linearly interpolate the objects current coordinates from 'starting' position/end position
x#,y#=LerpPosition(Events(lp).Origin.x#,Events(lp).Origin.Y#,Events(lp).Target.x#,Events(lp).Target.y#, Scaler#)

// Draw the object at it's position at this point of it's life
Circle x#,y#,10,true

// Bump the Active event counter
inc ActivateEventCount

endif

endif

next
unlockbuffer

EndFunction



Psub LerpPosition(OriginX#,OriginY#,DestX#,DestY#, Scaler#)
Scaler#=ClipRange#(Scaler#,0,1)
x#=OriginX#+((DestX#-OriginX#)*Scaler#)
y#=OriginY#+((DestY#-OriginY#)*Scaler#)
Endpsub x#,y#




ATLUS


kevin

#3
 Timer Based Life Spans / Two PlayFields

  This is a variation of the first demo.  The only real difference is that it renders the objects (in this case some circles) to a depreciating foreground playfield, this playfield is then masked over the screen.  So the foreground trials blend with the backdrop.


 Controls:
            Space = Change FPS()
            ESC to exit.


Related To

  Time Based Movement
  Blur-O-Vision


Requires PB V1.64J

PlayBASIC Code: [Select]
   Type tPos
x#
y#
EndType

Type tEvent

StartTime
Duration
EndTime

Origin as Tpos
Target as Tpos

Colour
Size

EndType

max=1000

Dim Events(Max) as tEVent

for lp=1 to max

Events(lp).StartTime = Ticks ; When this event starts
Events(lp).Duration = rndrange(500,2500) ; Event can last from 1/2 a second to 5 seconds
Events(lp).EndTime = Ticks +Events(lp).Duration ; when it ends

; Starting position of object
Events(lp).Origin.x#=rnd(800)
Events(lp).Origin.y#=rnd(600)

; target/end position of object
Events(lp).Target.x#=rnd(800)
Events(lp).Target.y#=rnd(600)

Events(lp).Colour =RndRGB() | $ff000000

Events(lp).Size =RndRange(16,50)

; bump the ticks counter randomly, so the objects have
Ticks=Ticks+Rnd(50)
next




ProgramStartTime=timer()




Screen=NewFxImage(GetSCreenWidth(),GetSCreenHeight())

PlayField=NewFxImage(GetSCreenWidth(),GetSCreenHeight())
PrepareAfxImage PlayField

; ------------------------------------------------------------------
; ------------------------------------------------------------------

BacKDropColour1=rndrgb() | $ff000000
BacKDropColour2=rndrgb() | $ff000000
BacKDropColour3=rndrgb() | $ff000000
BacKDropColour4=rndrgb() | $ff000000


Do

rendertoimage Screen

shadebox 0,0,getscreenwidth(),getscreenheight(),BacKDropColour1,BacKDropColour2,BacKDropColour3,BacKDropColour4


rendertoimage PlayField
inkmode 1+2048
boxc 0,0,GetScreenWidth(),GetSCreenHeight(),true,$f0f0f0f0


// Get the time since this loop started (in milliseconds)
CurrentTime=timer()- ProgramStartTime

ActivateEventCount=0
DeadEventCount=0

ink $ffffffff

Count=GetArrayElements(Events().tEvent,1)
lockbuffer
For lp=1 to Count
if Events(lp)

// Check if the currentime is before the end of this event
if CurrentTime<Events(lp).EndTime

// Check if the currentime is beyond the startof this event. If so it must be active
if CurrentTime=>Events(lp).StartTime

// Get the time since this object came to life
TimePast#=CurrentTime-Events(lp).StartTime

// Divide the this objects life span duration (the time it's alive in milliseconds)
// into the time past since it was alive. This will give a scaler of 0.0 -> 1.0
Scaler#=TimePast#/Events(lp).Duration

// Linearly interpolate the objects current coordinates from 'starting' position/end position
x#,y#=LerpPosition(Events(lp).Origin.x#,Events(lp).Origin.Y#,Events(lp).Target.x#,Events(lp).Target.y#, Scaler#)

// Draw the object at it's position at this point of it's life

Size#=Events(lp).Size
Size# = SinRadius(180*Scaler#,Size#)
inkmode 1
Circlec x#,y#,Size#,true,Events(lp).Colour

// Bump the Active event counter
inc ActivateEventCount

endif
else
//
Events(lp)=null
endif
else
inc DeadEventCount
endif
next
unlockbuffer

inkmode 1

rendertoimage Screen

drawimage PlayField,0,0,true
rendertoscreen
drawimage screen,0,0,false

setcursor 0,0
print "Number of Active Events ="+str$(ActivateEventCount)
print "Total Events ="+str$(Count)+" Events Left="+str$(Count-DeadEventCount)
print "Peek FPS="+Str$(GetfPS())
print "FPS ="+str$(Fps())


// press the space bar to force PB to restict the FPS to multiples of 5
if spacekey()
Rate=wrapvalue(Rate-5,0,60)
Login required to view complete source code




kevin

#4
 Flares

   This is a variation of the previous demo above, the main difference is that this one renders sprites rather than circles.   The movement is tracked against the timer, so the effect executes in consistence time frame.



  Controls:
            Space = Change FPS()
            ESC to exit.


Related To

   Time Based Movement
   Blur-O-Vision


Requires PB V1.64J

Code Attached