Countdown & Clock
-
Saturday, November 24, 2012 4:29 PM
Hi,
I wanted to write a little program that starts a countdown after someone clicks on a button. But when the button is clicked the program freezes until the countdown ran out. I tried these possibilities:
c = Clock.Minute While c = Clock.Minute 'wait for the first minute EndWhile While c <> Clock.Minute 'wait for an hour EndWhile
Program.Delay(3600000)
My second problem is a clock. I want the clock to update every second. I've allready made this, but i'm using a GraphicsWindow and so everytime it updates it writes over the time written before. I got allready something else written in this GraphicsWindow and so I dont want to use GraphicsWindow.Clear() to clean up.
I'm quite a green horn in Small Basic, so if these problems are nooby just toast me.
BlackSc0rp
All Replies
-
Saturday, November 24, 2012 4:47 PMModerator
Problem 1] The reason it freezes is that it enters the While loop and keeps repeating the loop until the time is ellapsed. While the loop is running the cpu is continuously working flat out doing the loop and appears to freeze. To stop the freezing, give the program time to refresh the window etc by adding a Program.Delay inside the loop, say Program.Delay(20) 1/50th sec (plenty of time to stop it freezing).
Problem 2] To just clear a region of the GraphicsWindow so you can overwrite with a new time, just use GraphicsWindow.FillRectangle to clear a small region with the bakground colour.
Example show some of this:
GraphicsWindow.BackgroundColor = "LightBlue" While "True" GraphicsWindow.BrushColor = GraphicsWindow.BackgroundColor GraphicsWindow.FillRectangle(10,10,100,40) GraphicsWindow.BrushColor = "Black" GraphicsWindow.DrawText(12,12,Clock.Hour+":"+Clock.Minute+":"+Clock.Second) Program.Delay(20) EndWhile
- Proposed As Answer by Ed Price - MSFTMicrosoft Employee, Owner Sunday, November 25, 2012 8:59 AM
- Marked As Answer by BlackSc0rp Sunday, November 25, 2012 9:27 AM
- Unmarked As Answer by BlackSc0rp Sunday, November 25, 2012 10:05 AM
- Marked As Answer by BlackSc0rp Sunday, November 25, 2012 10:22 AM
-
Saturday, November 24, 2012 5:23 PM
show GKV447 its runBest Regards Martin
- Marked As Answer by BlackSc0rp Sunday, November 25, 2012 9:29 AM
-
Saturday, November 24, 2012 6:51 PM
show SXV526 its a good alarmclock,
Best Regards Martin
- Proposed As Answer by Ed Price - MSFTMicrosoft Employee, Owner Sunday, November 25, 2012 8:59 AM
-
Sunday, November 25, 2012 10:32 AM
looks like i'm doing everything like you but, my clock is still flattering, maybe could you have a look on that? RHQ594
Thanks, BlackSc0rp
-
Sunday, November 25, 2012 2:45 PM
Thanks for the answer,
but the program freezes, even if I implement a delay of 20 milliseconds.
-
Sunday, November 25, 2012 2:58 PM
I imported RHQ594, and added Program.Delay(1000) just before the EndWhile.
The program worked flawless!
Jan [ WhTurner ] The Netherlands
-
Sunday, November 25, 2012 4:14 PM
Thanks, I've just put the Delay to low
BlackSc0rp
-
Sunday, November 25, 2012 5:00 PMAnswerer
Heyya BlackSc0rp!
Some tips for you:
Small Basic is always displaying what is being drawn to screen.
So, when you try to use any of the GraphicsWindow's drawing methods too fast, like -> GraphicsWindow.FillRectangle(10,10 100,40), flickering may happen!
Those types are only ideal for static drawings, that is, something that won't change once drawn and stays quiet at the background.
Your clock display's drawing changes every 1 second. Thus, it's not static, but dynamic!
For dynamic drawings, the ideal is to use the Shapes object category. And 1 of them is Shapes.AddText(), which you can change the text being displayed w/o having to clear previous one beforehand. And it happens smoothly, w/o any flickering!
Besides displaying any text, you can move it anywhere across the GraphicsWindow, w/o erasing any drawings below it. Also w/o flickering!
Another useful object category for your program is Timer. It keeps calling back a subroutine you choose after a period of time you set has passed. For example:
- Timer.Tick = Seconds -> Sets Sub Seconds as its callback event subroutine.
- Timer.Interval = 1000 -> Sets & activates the callback to happen each 1000 ms. ( 1 second = 1000 milliseconds = 1 FPS )
In short, you just put the code you want to be always called back inside the subroutine set by Timer.Tick in a period of Timer.Interval!
In your case, that code would be -> Shapes.SetText( display, Clock.Time ), which changes the displayed text to current clock time!
Here's a very simple example code, well commented; so you can study it to learn all the concepts above: RHQ594-0
' Countdown & Clock ' by BlackSc0rp (2012/Nov) ' remixed by GoToLoop ' RHQ594-0 ' http://social.msdn.microsoft.com/Forums/en-US/smallbasic/thread/f2768efb-8f3b-4ff4-b162-333cfdb780b7 gw = GraphicsWindow.Width ' stores GraphicsWindow's dimensions gh = GraphicsWindow.Height fs = 64 ' text font size for clock display GraphicsWindow.Title = "Countdown & Clock"
GraphicsWindow.BackgroundColor = "Yellow" GraphicsWindow.BrushColor = "Black" GraphicsWindow.FontBold = "True" GraphicsWindow.FontSize = fs display = Shapes.AddText( Clock.Time ) ' creates text shape object to display current clock time Shapes.Move( display gw/2 - fs*3, gh/2 - fs*2/3 ) ' places clock at about the center of GraphicsWindow Timer.Tick = Seconds ' triggered event subroutine to change the text displayed by shape object -> display Timer.Interval = 1000 ' it's called-back every 1 second ( 1 second = 1000 milliseconds ) Sub Seconds Shapes.SetText( display, Clock.Time ) ' changes displayed text to current clock time EndSub
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)
- Edited by GoToLoopEditor Sunday, November 25, 2012 5:27 PM
- Marked As Answer by BlackSc0rp Monday, November 26, 2012 2:14 PM
-
Sunday, November 25, 2012 5:37 PM
Hallo BlaSc0rp,
ich habe 2 Zeilen eingefügt. Mit der variablen PD kann man das flackern des Bildschirms verhindern. Am Ende der While-Schleife habe ich "Program.Delay(PD)" eingefügt damit eine Pause gemacht wird und das Flackern verhindert wird.
Importiere mal das Programm RHQ594-1 und setz für PD unterschiedliche Werte ein.
Viel Spass beim Programmieren
Martin
Best Regards Martin
-
Monday, November 26, 2012 3:06 PM
Thanks to GoToLoop and martmen for the answers.
Finally, I got it. Dont know why but using a variable to set the Delay helped to stop flickering. -->
While uhrCheck = 0 ... ... ... Program.Delay(1000) ' keeps flickering EndWhile delay = 1000 While uhrCheck = 0 ... ... ... Program.Delay(delay) ' stops flickering
@GoToLoop:
I've allready used the Timer method, but I thought, the clock was flickering cause of that. But I think i'm gonna use it again. Thanks for your good explanation. Actually I didnt even know that there's a possibility to use Shapes.AddText or stuff like that.
But I still cant get arround with the countdown without freezing... Someone got an idea?
BlackSc0rp
- Edited by BlackSc0rp Monday, November 26, 2012 3:23 PM
-
Monday, November 26, 2012 4:31 PMAnswerer
Hello again!
Expanded previous example to include a variable for countdown seconds -> cd = 60.
Since Sub Seconds is called back every 1 second (1000 milliseconds), it's an excellent opportunity to put code to decrease our countdown's variable!
For now, it just places its display at the running program's window title-bar.
Check it out: RHQ594-2
' Countdown & Clock (v2.0) ' by BlackSc0rp (2012/Nov) ' remixed by GoToLoop ' RHQ594-2 ' http://social.msdn.microsoft.com/Forums/en-US/smallbasic/thread/f2768efb-8f3b-4ff4-b162-333cfdb780b7 gw = GraphicsWindow.Width ' stores GraphicsWindow's dimensions gh = GraphicsWindow.Height fs = 64 ' text font size for clock display cd = 60 ' countdown seconds GraphicsWindow.BackgroundColor = "Yellow" GraphicsWindow.BrushColor = "Black" GraphicsWindow.FontBold = "True" GraphicsWindow.FontSize = fs display = Shapes.AddText( Clock.Time ) ' creates text shape object to display current clock time Shapes.Move( display gw/2 - fs*3, gh/2 - fs*2/3 ) ' places clock at about the center of GraphicsWindow Timer.Tick = Seconds ' triggered event subroutine to change the text displayed by shape object -> display Timer.Interval = 1000 ' it's called-back every 1 second ( 1 second = 1000 milliseconds ) Sub Seconds If cd > 0 Then cd = cd - 1 ' 1 second less for countdown EndIf Shapes.SetText( display, Clock.Time ) ' changes displayed text to current clock time GraphicsWindow.Title = "Countdown: " + cd + " seconds" ' displays countdown as title bar EndSub
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)
- Edited by GoToLoopEditor Monday, November 26, 2012 8:01 PM
-
Tuesday, November 27, 2012 4:53 PM
Hey GoToLoop,
Nice idea with putting the countdown into the subroutine, but I would like to start the countdown after a button is clicked, while the clock allready is displayed.
Is there a possibility to have 2 different Timer.Tick?
BlackSc0rp
-
Tuesday, November 27, 2012 6:03 PMAnswerer
Only 1 Timer.Tick can be active, although that can be changed to another subroutine at any time!
But a simpler solution would be to create a flag state variable, which would be turned on w/ isActive = "True", and turned off w/ isActive = "False".
So within Sub Seconds, besides testing if cd > 0 Then, just include the flag variable as well:
If isActive And cd > 0 Then
cd = cd - 1 ' 1 second less for countdown
Else
isActive = "False" ' turns off countdown
EndIfBut in a more compact way, you wouldn't even need a flag variable for it, since you can consider that countdown is active if cd > 0 by itself.
So, rather than create an extra variable (and an extra check) for it.
Inside the code where you check whether the user clicked on the start countdown button, just assign a number > 0 to variable cd.
To turn it off abruptly, just make cd = 0! ;-)
An extra flag variable would only be necessary if you had the need to pause/resume the countdown at any given moment!
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)
- Edited by GoToLoopEditor Tuesday, November 27, 2012 6:22 PM
- Marked As Answer by BlackSc0rp Wednesday, November 28, 2012 4:04 PM
-
Wednesday, November 28, 2012 4:16 PM
Finally made it :) Thaaaanks GoToLoop, you really helped me :)
KXC882 I've commented it in german
BlackSc0rp

