Hey again...
For the game we are currently developing I created a function library (at lest the 20th..^^) managing ingame-time. I searched the forum and it doesn't seem as if there was a thread with such a system, at least not with as much functionality, so it might be usefull for someone.
So, what are the functions good for?
They can handle an more or less independent time, with a variable speed. Also there's a function to pause the time, so it needn't go on running while the player is in a menu for example.
Very easy to use, there's also a possibility of getting a possible sun-angle or height to simulate day-night-circles.
Functions:
Prefix is always "gte_" [Game Time-Engine], for all functions, variables, constants etc.
-gte_init() //Must always be called before all other functions!!!
-gte_update() //This one in your mainloop to update the time-value
-gte_pause() //This function should be called in or after a menu-routine when the time is not supposed to run
-gte_UpdateTime() //Updates the next 3 functions
-gte_GetHour$()
-gte_GetMinute$()
-gte_GetSecond$()
-gte_GetNewDay() //Returns a 1 if a new day has started
-gte_SetFactor(Factor#) //Defines the speed in which the time is running
-gte_SetTime(Hours,Minutes,Seconds) //Specifies the time of day
-gte_SaveSetTime(Hours,Minutes,Seconds) //Same like above, just with mod to avoid to high times
Intern:
-gte_FillNumber(Num,Decimalplaces) //Adds 0s to the beginning of numbers (6 -> "06")
-gte_SetCounter(CounterValue) //Sets the counter-value and updates variables
Variables:
-gte_SunHeight (float) //Height always between 2 (12:00, high) and 0 (00:00, low)
-gte_SunAngle (float) //Angle 0: Sun on top->midday(12:00), Angle 180: Night
I think that are the most important things..
If you have any questions, issues or whatever just ask.
Here the code with example:
set display mode 800,600,32
set window on
sync on
sync rate 0
gte_init()
gte_SetFactor(1000.0)
gte_SetCounter(83500000)
KeyPressed = 0
InMenu = 0
ActDay = 1
do
rem Clear screen
cls
rem Update timer
if InMenu=0 then t = gte_update() else gte_Pause()
gte_updateTime()
rem Draw info
if InMenu=0 then ink rgb(255,255,255),0 else ink rgb(128,128,128),0
print "FPS: ", screen fps()
print "Mouse: ", mousex(),"|",mousey()
print "Time: ", gte_GetHour$(),":",gte_GetMinute$(),":",gte_GetSecond$()
print "Sunheight: ", str$(gte_SunHeight,3)
print "Sun-Angle: ", str$(gte_SunAngle,3)
circle 400,400 - gte_SunHeight*100, 25
circle 400+100*sin(gte_SunAngle),300-100*cos(gte_SunAngle),25
print "Day: ", ActDay
print
print "Return -> menu"
print "Control -> time-change"
rem Menu-Selection
if returnkey()
if KeyPressed=0
KeyPressed=1
InMenu = 1-InMenu
else
KeyPressed=1
endif
else
if KeyPressed=1
KeyPressed=-1
else
KeyPressed = 0
endif
endif
rem Print Menu info
if inMenu=1
CenterText("This is the gte-Demo",100)
CenterText("Press escapekey to quit",120)
CenterText("Or Returnkey to return",140)
CenterText("Timer: "+str$(timer()),170)
CenterText("Thanks for watching :P",200)
CenterText("~made by Mr Kohlenstoff~",250)
endif
rem New day
if gte_GetNewDay()=1
ActDay = (ActDay+1)
if ActDay = 8 then ActDay = 1
endif
rem Set time
if controlkey()
gte_SetTime(23,45,39)
endif
rem Update screen
sync
loop
function CenterText(s$,yp)
w = text width(s$)
xp = screen width()/2 - w/2
if mousex()>xp and mousex()<xp+w and mousey()>yp and mousey()<yp+20
ink rgb(128,0,0),0
else
ink rgb(32,32,32),0
endif
box xp,yp,xp+w,yp+20
ink rgb(200,200,200),0
text xp,yp+1,s$
endfunction
rem Game Time-Engine [gte]
rem One day has 86,400 seconds, so 86,400,000 ms
#constant gte_MsPerDay = 86400000
rem This function must be called one time in the beginning to set up
rem the variables needed in the rest of gte-Functions
function gte_init()
global gte_Counter as integer = 0 `Absolute time-value in ms
global gte_TimerOffset as integer = 0 `If the time is manually changed
global gte_Timer as integer : gte_Timer = timer() `Represents the dbp-timer()
global gte_StartTimer as integer : gte_LastTimerValue = gte_Timer `timer() when it was initialized
global gte_TimeFactor as float = 1.0
global gte_ActHour as integer
global gte_ActMinute as integer
global gte_ActSecond as integer
global gte_NewDay as boolean = 0
global gte_Paused as boolean = 0
global gte_PauseTimer as integer = 0
global gte_SunHeight as float
global gte_SunAngle as float
endfunction
rem This function updates the timer's etc. and should be called
rem each loop, when the time should continue running
function gte_update()
if gte_Paused=1
`inc gte_TimerOffset, gte_PauseTimer-gte_Timer
oldcounter = gte_Counter
endif
gte_Timer = timer()
gte_Counter = gte_TimeFactor*(gte_Timer - gte_StartTimer) - gte_TimerOffset
c = gte_Counter
if gte_Paused=1
gte_Paused=0
inc gte_TimerOffset, gte_Counter-oldcounter
gte_Counter = oldcounter
endif
rem Sun Angle
sunf# = (gte_Counter mod gte_MsPerDay) / (1.0*gte_MsPerDay)
gte_SunHeight = (sin(sunf#*360+270)+1)
gte_SunAngle = 360*(((gte_Counter + 1.5*gte_MsPerDay) mod gte_MsPerDay) / gte_MsPerDay)
endfunction c
rem The time is _not_ added to the timer (if a menu etc is opened this
rem one should be called afterwards, so the time isn't added)
function gte_pause()
gte_Paused = 1
gte_PauseTimer = timer()
endfunction
rem This function updates the Hour, Minute and Second-String, so is just
rem important, when you need the time-strings. Call this function one
rem time before you read the time from the next 3 functions.
function gte_UpdateTime()
sec = gte_Counter/1000
min = sec/60
hour = min/60
gte_ActSecond = sec mod 60
gte_ActMinute = min mod 60
lasth = gte_ActHour
gte_ActHour = hour mod 24
if lasth = 23
if gte_ActHour = 0
gte_NewDay = 1
endif
endif
endfunction
rem Returns the actual time-hours in a string (from 0 to 23)
function gte_GetHour$()
h$ = gte_FillNumber(gte_ActHour,2)
endfunction h$
rem Returns the actual time-minutes in a string (from 0 to 59)
function gte_GetMinute$()
m$ = gte_FillNumber(gte_ActMinute,2)
endfunction m$
rem Returns the actual time-seconds in a string (from 0 to 59)
function gte_GetSecond$()
s$ = gte_FillNumber(gte_ActSecond,2)
endfunction s$
rem This intern function adds 0s to e.g. single digits (so '8' becomes '08')
function gte_FillNumber(num,_dec)
s$ = str$(num)
l = len(s$)+1
for z = l to _dec
s$ = "0"+s$
next z
endfunction s$
rem This function tells you if a new day began recently
function gte_GetNewDay()
if gte_NewDay = 0 then exitfunction 0
gte_NewDay = 0
endfunction 1
rem With this function you can define how fast the time runs: 1.0 -> 1 second equals 1 second. 60.0 -> 1 seconds is 1 minute in the engine
function gte_SetFactor(f#)
t = gte_Counter
gte_TimeFactor = f#
gte_SetCounter(t)
endfunction
rem Don't look at this function.. not needed ;)
function gte_SetCounter(v)
gte_Timer = timer()
gte_StartTimer = gte_Timer
gte_TimerOffset = -v
endfunction
rem Sets the actual time to H:M:S (Hours:Minutes:Seconds)
function gte_SetTime(H,M,S)
t = s*1000 + m*60000 + h*3600000
inc gte_TimerOffset, gte_Counter-t
endfunction
rem This function does the same like "gte_SetTime" but uses mod to prevent to high values, but might need a bit longer
function gte_SaveSetTime(H,M,S)
H = H mod 24
M = M mod 60
S = S mod 60
gte_SetTime(H,M,S)
endfunction
And here just the functions:
rem Game Time-Engine [gte]
rem One day has 86,400 seconds, so 86,400,000 ms
#constant gte_MsPerDay = 86400000
rem This function must be called one time in the beginning to set up
rem the variables needed in the rest of gte-Functions
function gte_init()
global gte_Counter as integer = 0 `Absolute time-value in ms
global gte_TimerOffset as integer = 0 `If the time is manually changed
global gte_Timer as integer : gte_Timer = timer() `Represents the dbp-timer()
global gte_StartTimer as integer : gte_LastTimerValue = gte_Timer `timer() when it was initialized
global gte_TimeFactor as float = 1.0
global gte_ActHour as integer
global gte_ActMinute as integer
global gte_ActSecond as integer
global gte_NewDay as boolean = 0
global gte_Paused as boolean = 0
global gte_PauseTimer as integer = 0
global gte_SunHeight as float
global gte_SunAngle as float
endfunction
rem This function updates the timer's etc. and should be called
rem each loop, when the time should continue running
function gte_update()
if gte_Paused=1
`inc gte_TimerOffset, gte_PauseTimer-gte_Timer
oldcounter = gte_Counter
endif
gte_Timer = timer()
gte_Counter = gte_TimeFactor*(gte_Timer - gte_StartTimer) - gte_TimerOffset
c = gte_Counter
if gte_Paused=1
gte_Paused=0
inc gte_TimerOffset, gte_Counter-oldcounter
gte_Counter = oldcounter
endif
rem Sun Angle
sunf# = (gte_Counter mod gte_MsPerDay) / (1.0*gte_MsPerDay)
gte_SunHeight = (sin(sunf#*360+270)+1)
gte_SunAngle = 360*(((gte_Counter + 1.5*gte_MsPerDay) mod gte_MsPerDay) / gte_MsPerDay)
endfunction c
rem The time is _not_ added to the timer (if a menu etc is opened this
rem one should be called afterwards, so the time isn't added)
function gte_pause()
gte_Paused = 1
gte_PauseTimer = timer()
endfunction
rem This function updates the Hour, Minute and Second-String, so is just
rem important, when you need the time-strings. Call this function one
rem time before you read the time from the next 3 functions.
function gte_UpdateTime()
sec = gte_Counter/1000
min = sec/60
hour = min/60
gte_ActSecond = sec mod 60
gte_ActMinute = min mod 60
lasth = gte_ActHour
gte_ActHour = hour mod 24
if lasth = 23
if gte_ActHour = 0
gte_NewDay = 1
endif
endif
endfunction
rem Returns the actual time-hours in a string (from 0 to 23)
function gte_GetHour$()
h$ = gte_FillNumber(gte_ActHour,2)
endfunction h$
rem Returns the actual time-minutes in a string (from 0 to 59)
function gte_GetMinute$()
m$ = gte_FillNumber(gte_ActMinute,2)
endfunction m$
rem Returns the actual time-seconds in a string (from 0 to 59)
function gte_GetSecond$()
s$ = gte_FillNumber(gte_ActSecond,2)
endfunction s$
rem This intern function adds 0s to e.g. single digits (so '8' becomes '08')
function gte_FillNumber(num,_dec)
s$ = str$(num)
l = len(s$)+1
for z = l to _dec
s$ = "0"+s$
next z
endfunction s$
rem This function tells you if a new day began recently
function gte_GetNewDay()
if gte_NewDay = 0 then exitfunction 0
gte_NewDay = 0
endfunction 1
rem With this function you can define how fast the time runs: 1.0 -> 1 second equals 1 second. 60.0 -> 1 seconds is 1 minute in the engine
function gte_SetFactor(f#)
t = gte_Counter
gte_TimeFactor = f#
gte_SetCounter(t)
endfunction
rem Don't look at this function.. not needed ;)
function gte_SetCounter(v)
gte_Timer = timer()
gte_StartTimer = gte_Timer
gte_TimerOffset = -v
endfunction
rem Sets the actual time to H:M:S (Hours:Minutes:Seconds)
function gte_SetTime(H,M,S)
t = s*1000 + m*60000 + h*3600000
inc gte_TimerOffset, gte_Counter-t
endfunction
rem This function does the same like "gte_SetTime" but uses mod to prevent to high values, but might need a bit longer
function gte_SaveSetTime(H,M,S)
H = H mod 24
M = M mod 60
S = S mod 60
gte_SetTime(H,M,S)
endfunction