|
Post by Mark Dunham on Feb 15, 2022 10:55:22 GMT -5
I am working on a timer idea and I am not sure I am going in the right direction. I would like to have things that take different amounts of time and show the timers counting down. This code sample seems to run too fast am I heading in the right direction or is what I am trying to do not going to work? I wanted to get the timer portion figured out before I built the game framework.
NewTimer = time$("seconds") Time = NewTimer + 10
while Time <> NewTimer Time = Time - 1 print "Timer: "; Time
wend
|
|
|
Post by tsh73 on Feb 15, 2022 12:45:06 GMT -5
So to have "real" time you should ask system. Like, time$("ms")
Your code does not check if actual time is passed, that's why it goes so fast
Now, if you will insert a loop what will do nothing but check time, it will use all available to LB CPU (single core) preventing LB from doing anything of use. You will not be able to break that loop unless you add SCAN
But you can call Windows API Sleep function - while your program sleeps, Windows could do other things (likely redraw your GUI too)
So something like this
t0=time$("ms") dt = 10*1000 'milliseconds
k = 4 FullLine$=REPLSTR$( space$(k*10), " ", "#" )+REPLSTR$( space$(k*10), " ", "." )
while time$("ms")<t0+dt a=(time$("ms")-t0)/dt locate 1,1 print mid$(FullLine$, int((1-a)*k*10), int(k*10)) locate k*10/2-2,1 print using("###",a*100);"% " call sleep (50) scan wend
sub sleep ms calldll #kernel32, "Sleep",_ ms as ulong,_ ret as void end sub
AND LB has native TIMER statement TIMER N [label] (TIMER 0 to turn it off) actually it makes program jump to given [label] every N ms It could be problematic if code at [label] takes more then N ms - events will build up and LB will eventually crash But you can turn timer off just as you jump to label, and turn it back on then finishing.
t0=time$("ms") dt = 10*1000 'milliseconds
k = 4 FullLine$=REPLSTR$( space$(k*10), " ", "#" )+REPLSTR$( space$(k*10), " ", "." )
timer 50, [update] wait
[update] if time$("ms")>t0+dt then timer 0 'turn off
a=(time$("ms")-t0)/dt locate 1,1 print mid$(FullLine$, int((1-a)*k*10), int(k*10)) locate k*10/2-2,1 print using("###",a*100);"% " wait
Have a look, and then try to describe what you want to do - again.
|
|
|
Timer Test
Feb 15, 2022 12:56:18 GMT -5
via mobile
Post by Rod on Feb 15, 2022 12:56:18 GMT -5
Also how fast does the timer need to run? Every second? 100 times a second?
I would set a timer to tick every half second then branch to the timer reduction code where you take a half second off each time and display the resulting time remaining. That will take no time at all and you can have ten or more counters counting down.
The difficulty will come when a time reaches zero and you want to do something. Whatever you do must be completed within the remaining timer tick time. Say 500ms
As tsh73 says tell us a bit more about what your code will do.
|
|
|
Post by Mark Dunham on Feb 15, 2022 12:56:57 GMT -5
So to have "real" time you should ask system. Like, time$("ms") Your code does not check if actual time is passed, that's why it goes so fast Now, if you will insert a loop what will do nothing but check time, it will use all available to LB CPU (single core) preventing LB from doing anything of use. You will not be able to break that loop unless you add SCAN But you can call Windows API Sleep function - while your program sleeps, Windows could do other things (likely redraw your GUI too) So something like this t0=time$("ms") dt = 10*1000 'milliseconds
k = 4 FullLine$=REPLSTR$( space$(k*10), " ", "#" )+REPLSTR$( space$(k*10), " ", "." )
while time$("ms")<t0+dt a=(time$("ms")-t0)/dt locate 1,1 print mid$(FullLine$, int((1-a)*k*10), int(k*10)) locate k*10/2-2,1 print using("###",a*100);"% " call sleep (50) scan wend
sub sleep ms calldll #kernel32, "Sleep",_ ms as ulong,_ ret as void end sub
AND LB has native TIMER statement TIMER N [label] (TIMER 0 to turn it off) actually it makes program jump to given [label] every N ms It could be problematic if code at [label] takes more then N ms - events will build up and LB will eventually crash But you can turn timer off just as you jump to label, and turn it back on then finishing. t0=time$("ms") dt = 10*1000 'milliseconds
k = 4 FullLine$=REPLSTR$( space$(k*10), " ", "#" )+REPLSTR$( space$(k*10), " ", "." )
timer 50, [update] wait
[update] if time$("ms")>t0+dt then timer 0 'turn off
a=(time$("ms")-t0)/dt locate 1,1 print mid$(FullLine$, int((1-a)*k*10), int(k*10)) locate k*10/2-2,1 print using("###",a*100);"% " wait
Have a look, and then try to describe what you want to do - again. Thank you for the info I will have to think about this more. I was thinking something like Forge of Empires where you can have building do work for a certain amount of time. But it looks there is not a good way to do precise time with LB without possibly using a DLL or by using API functions. Also I think another issue will be that I would probably need to do multi-threading.
|
|
|
Post by Mark Dunham on Feb 15, 2022 13:19:48 GMT -5
I was thinking something like Forge of Empires where you can have building do work for a certain amount of time. You would select a building select a task and depending on upgrades or what you have researched it may take longer or shorter. The time remaining would be displayed above each building.
|
|
|
Post by tsh73 on Feb 15, 2022 13:23:45 GMT -5
Huh! People used to do this kind of stuff on NES or same kind of computers ("Construction complete", anyone? ) so multi-threading is completely unnecessary Really, you hardly need it "precise" Unless you make music application that is Typical timer events is 16 ms apart, that makes about 60 times per second.
|
|
|
Post by Mark Dunham on Feb 15, 2022 13:38:01 GMT -5
Huh! People used to do this kind of stuff on NES or same kind of computers ("Construction complete", anyone? ) so multi-threading is completely unnecessary Really, you hardly need it "precise" Unless you make music application that is Typical timer events is 16 ms apart, that makes about 60 times per second. I guess I meant more like running two timers at one time (multi-threading probably wrong terminology) but LB only lets you run the one. Seems like game creation or type of game is niche to the game and a lot of the topics when googled are always out of scope of what I am looking for. I will keep digging through the web and I will try to get a working/Non-Working example of code. Thank you appreciate the feedback.
|
|
|
Post by tsh73 on Feb 15, 2022 13:57:14 GMT -5
10 objects with different time spans above them, counting down
N=10
dim x(N), y(N), state(N), timeLeft(N) states$=".. -- '' `` oo OO" '6 w=64 h=24
for i = 1 to N x(i)=randInt(w-2)+1 y(i)=randInt(h-2)+1 state(i)=randInt(6)+1 timeLeft(i)=randInt(100)+1 next
cls timer 200, [update] wait
[update] scan for i = 1 to N if timeLeft(i)<1 then [skip] 'clear old locate x(i),y(i): print space$(4) locate x(i),y(i)+1: print space$(4) dx=int(randInt(6)-3)/2 dy=int(randInt(3)-1) x=x(i)+dx y=y(i)+dy if (x>2) and (x<w-2) and (y>2) and (y<h-2) then 'if coords are good x(i)=x y(i)=y end if if timeLeft(i)>0 then timeLeft(i)=timeLeft(i)-1 locate x(i),y(i): print using("###", timeLeft(i));" " locate x(i),y(i)+1: print " ";word$(states$,state(i));" " if timeLeft(i)=0 then locate x(i),y(i)+1: print " xx " end if [skip] next
wait
function randInt(n) randInt=int(n*rnd(0)) end function
|
|
|
Post by Mark Dunham on Feb 15, 2022 14:35:01 GMT -5
10 objects with different time spans above them, counting down N=10
dim x(N), y(N), state(N), timeLeft(N) states$=".. -- '' `` oo OO" '6 w=64 h=24
for i = 1 to N x(i)=randInt(w-2)+1 y(i)=randInt(h-2)+1 state(i)=randInt(6)+1 timeLeft(i)=randInt(100)+1 next
cls timer 200, [update] wait
[update] scan for i = 1 to N if timeLeft(i)<1 then [skip] 'clear old locate x(i),y(i): print space$(4) locate x(i),y(i)+1: print space$(4) dx=int(randInt(6)-3)/2 dy=int(randInt(3)-1) x=x(i)+dx y=y(i)+dy if (x>2) and (x<w-2) and (y>2) and (y<h-2) then 'if coords are good x(i)=x y(i)=y end if if timeLeft(i)>0 then timeLeft(i)=timeLeft(i)-1 locate x(i),y(i): print using("###", timeLeft(i));" " locate x(i),y(i)+1: print " ";word$(states$,state(i));" " if timeLeft(i)=0 then locate x(i),y(i)+1: print " xx " end if [skip] next
wait
function randInt(n) randInt=int(n*rnd(0)) end function
Thank you for the example this might kick me in the direction I need to go.
|
|
|
Post by Brandon Parker on Feb 16, 2022 0:46:22 GMT -5
Mark, Here is a quick example showing how one might set up some timers in standard Liberty BASIC code without using API's for the timers themselves. You could even wrap up the For...Next loop inside a Sub/Function if you wanted to and pass in the range of timers to check as parameters.
Global False : False = 0 Global True : True = 1
'Use a Two-dimensional array to hold timer data Dim myTimers(1, 1)
'Row 1 is the first timer '(0, 0) holds the timer start time '(0, 1) holds the timer interval myTimers(0, 0) = Time$("ms") myTimers(0, 1) = 1000
'Row 2 is the second timer myTimers(1, 0) = Time$("ms") myTimers(1, 1) = 5000
'You need to have a continuous loop as your main ' "waiting" point in Liberty BASIC for this to work [Loop] 'Obviously, we need a Scan Scan 'Loop through each timer and call the checkTimer() function For i = 0 To 1 'We need to set the previous timer value to a variable 'to enable the ByRef to work correctly myTime = myTimers(i, 0) 'Call the function result = checkTimer(myTime, myTimers(i, 1)) 'Set the timer value to the returned value of the myTime variable from the function myTimers(i, 0) = myTime 'If the timer has fired, result will be set to True If result Then Print "Timer ";i;" has fired." Next i 'Just set the Sleep() value to 1; doing so will sleep the minimum amount of 'time allowed by your processor. This is normally about 16ms 'This value has to be lower than your smallest timer interval result = Sleep(1) GoTo [Loop]
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function checkTimer(ByRef myTime, resolution) currentTime = Time$("ms") If ((myTime + resolution) > 86400000) And (currentTime < resolution) Then If currentTime >= (resolution - (86400000 - myTime)) Then checkTimer = True : myTime = currentTime End If Else If (currentTime >= (myTime + resolution)) Or (myTime > currentTime) Then checkTimer = True : myTime = currentTime End If End If End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Sleep(milliseconds) CallDLL #kernel32, "Sleep", milliseconds As ulong, _ ret As void End Function
If you want you could check out the Timer abilities over on my forum using the Import Architect and associated Timer library.
{:0)
Brandon Parker
|
|
|
Post by Mark Dunham on Feb 16, 2022 8:39:04 GMT -5
Mark, Here is a quick example showing how one might set up some timers in standard Liberty BASIC code without using API's for the timers themselves. You could even wrap up the For...Next loop inside a Sub/Function if you wanted to and pass in the range of timers to check as parameters. Global False : False = 0 Global True : True = 1
'Use a Two-dimensional array to hold timer data Dim myTimers(1, 1)
'Row 1 is the first timer '(0, 0) holds the timer start time '(0, 1) holds the timer interval myTimers(0, 0) = Time$("ms") myTimers(0, 1) = 1000
'Row 2 is the second timer myTimers(1, 0) = Time$("ms") myTimers(1, 1) = 5000
'You need to have a continuous loop as your main ' "waiting" point in Liberty BASIC for this to work [Loop] 'Obviously, we need a Scan Scan 'Loop through each timer and call the checkTimer() function For i = 0 To 1 'We need to set the previous timer value to a variable 'to enable the ByRef to work correctly myTime = myTimers(i, 0) 'Call the function result = checkTimer(myTime, myTimers(i, 1)) 'Set the timer value to the returned value of the myTime variable from the function myTimers(i, 0) = myTime 'If the timer has fired, result will be set to True If result Then Print "Timer ";i;" has fired." Next i 'Just set the Sleep() value to 1; doing so will sleep the minimum amount of 'time allowed by your processor. This is normally about 16ms 'This value has to be lower than your smallest timer interval result = Sleep(1) GoTo [Loop]
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function checkTimer(ByRef myTime, resolution) currentTime = Time$("ms") If ((myTime + resolution) > 86400000) And (currentTime < resolution) Then If currentTime >= (resolution - (86400000 - myTime)) Then checkTimer = True : myTime = currentTime End If Else If (currentTime >= (myTime + resolution)) Or (myTime > currentTime) Then checkTimer = True : myTime = currentTime End If End If End Function
'_________________________________________________________________________________________________________________________________________________________ '_________________________________________________________________________________________________________________________________________________________
Function Sleep(milliseconds) CallDLL #kernel32, "Sleep", milliseconds As ulong, _ ret As void End Function If you want you could check out the Timer abilities over on my forum using the Import Architect and associated Timer library. {:0) Brandon Parker Brandon, thank you that helps as well. Do you have a link to you're forum. I got a new machine and some of my Bookmarks are lost forever. Thank you again.
|
|
|
Post by Brandon Parker on Feb 16, 2022 20:50:12 GMT -5
Brandon, thank you that helps as well. Do you have a link to you're forum. I got a new machine and some of my Bookmarks are lost forever. Thank you again. Here you go Mark... LB Import Architect{:0) Brandon Parker
|
|