 Okay, today we're going to use Godot to create a very simple stopwatch application, the little button to stop and start. It actually keeps tracking the background. So even if you restart your phone, it's going to keep the timer going properly. We'll talk about that as we get going. So let's go ahead and jump right in here. I just want to go over something real quick. I've talked about this in previous videos. When doing timers, there's a right way and a wrong way, and I'm sure there's more than just two ways. I have two examples here written in bash, just as an example. And the top one is a way a beginner might try to do it, and it's not a very good way to do it. So what we have here is we're saying set x equals zero, and then we're going to loop forever. So loop y. Then we're going to echo what x equals, so zero. And then we're going to say add one to x, sleep for a second, and then do it all again. So basically every second it's going to add one to x. The biggest problem with this is when you're running all these commands, you're running a sleep command for one second, but there's going to be all the other commands running, so it's not going to be exactly a second for each loop. And if your computer runs slow, it could be even worse. And even if it's a hundredth of a second slow, that means in a hundred seconds, which is just over a minute and a half, you're going to be a second off. Now look at the second example down here. Instead of saying x equals zero, we're going to set x to our start time. We're looking at the start time in seconds. Then we're going to loop, and we're just going to take the current time in seconds and subtract the start time from that. Sleep for a second loop. That way even if it's, I could set the loop to loop every five seconds and it will still keep accurate time because it's not counting the time. It's just displaying how much time has passed. So I'm going to demonstrate that. I'm going to start the top one and bottom one so you can see they're both going a little off here. But if I hit control Z, I can throw the process into the background. So they're both in the background now. So a couple seconds have passed, probably five seconds, six seconds. Let me go ahead and bring them both forward. So if I bring this top one forward, you can see it starts off right where it left off, where if I bring the bottom one forward, it's actually still keeping accurate time from before we suspended the application. So we're going to use those techniques in our Godot project. So let me go ahead and kill those and we will go to our Godot project here. So I have a new Godot project. I called it stopwatch and we are going to now create a user interface. We're going to rename that. We'll just call it stopwatch. I am going to create a vertical box here to contain our two things. We're going to have a label to display the time. And we're going to have a button to stop and start the timer. Okay, that's it. Now let's go ahead and take our vertical box. We're going to say fill the whole screen. Then we're going to take our label here and we're going to go down to size. And we're going to say, horizontally expand and fill. And then our button, we're going to go to its size flag. And we're going to say vertically fill. So I think we're good on that. We don't want to expand it. I mean, you could have a really big button. So let's go ahead and get started. I have some assets here. I am going to bring them in. So I have just a load screen. So we don't just have the default load screen, a font and an icon. Those are the only assets we need for this. So really the font, we don't really need any of them. But they do make the program a little bit nicer. So let's go ahead now. And we will go to our label. And we are going to type in here, I'm just going to go 00, 00, 00, just as a starting label timer. Now we're going to say align center, vertical align center. So now it's centered up. Now we can come down here to where it says custom font. And with the label selected, we're going to go custom font dynamic. Click where you said dynamic. Now click font. And we're just going to drag and drop our font, whatever font you have over to here. And there we go. We have a nicer looking font. We can up the size. I'll say 128. I'll give it a black border, just a little black border on it to make it look a little bit nicer. Now we're going to go to our button. And we're going to go down to where it has custom fonts. Same thing. Where it says empty, choose dynamic. Click where it says dynamic under font. We're now going to drag our font over. I'm going to use the same font for this. And for this, we're going to start off with saying start. Now we're going to up the font a little bit. So come back down here to font. We'll set this to 64. That looks good. And then we'll also add some margins here. So we're going to go extra space. And on the top and bottom, we'll add, I don't know, 10, maybe 20. Just to make the button a little bit larger. OK. Our interface is designed. Let's start some programming. We're going to right click on our main node here and say attach a script. Stopwatch.gd is fine. OK. So now we're going to create two variables at the top. I should have not had to create these comments here. But we're going to say var running. This is a variable to check to see if it's running. By default, it's not going to be running. Next we're going to say start, sorry, var start time, which we're going to set to 0, but immediately reset. So we probably could just leave that blank, but I'm going to do that. Also we're going to create little variables for our label and our button just to make it easier to get. We're going to say on ready. So it's going to wait for everything to load. We're going to say var button equals get node. You can also do a little dollar sign thing. I'm not really sure if one is better than the other. This one looks a little more official to me. So that's why I've been going this route. Our label get node and we're going to go label. So we now have a button and a label variable. Next we're going to start creating some functions here. I'm just going to function process delta here. So we are going to, let's do pass on that, what do we want to do first? We want to probably get the time. So we're going to create a function called get time. And we're going to create some variables here. And I'm going to copy and paste from the code I've already written just to speed things up so you're not watching me type a hundred things here. So what are we doing? We're going to create a variable in here called time now. That's the current time. It's going to get the Unix time code stamp, which is in second since 1971 I think, January 1st, 1971 I think is the time, but it gives you the current time in seconds. Then we're going to take that current time and subtract the start time from it. So that will give us how many seconds since we started running this. And then we're going to get seconds out of that. So we're going to take that elapsed time. We're going to divide it by 60 and get the remainder. That's how many seconds we have. Then we want to get hours. We're going to take the time elapsed and divide that by 3600. And then we're going to get minutes by taking the time elapsed, subtracting the output of 3600 times hours, and then we're going to divide that by 60. And then we're going to take that and we're going to put it into a variable called elapsed time. And we're going to have hours, minutes, and seconds, but we're writing it like this. So each one of these percent zero two D is going to take a variable over here and just going to take that number and make sure it's a two digit number so that we always have a leading zero so that you don't have like in the minute spot it says one without a zero before it, same for seconds and hours. And then we're going to change the label to show that time. So that was super simple. So whenever we run that, it's going to get the current elapsed time for us. Okay, so next thing we need to do, let's go ahead and choose our button here and I'm going to go node and we're going to get a signal and we're going to say when it's pressed, we're going to link it to that script, a function called on button press. We're going to click that, okay. So now we want to check, is the stopwatch currently running? So we're going to say if running and we're going to then say stop, okay. So if it's running stop and then we're going to, and we haven't created that function yet, but we're going to, that's why it's turning right there. Then we're going to say else, we're going to start. So if it's not already running, we're going to start it. Let's go up and create those two functions. So func, stop, and for right now we'll just say pass. What that's going to do is it's, if we don't have something in the function, it's going to give us an error until we do. So you can just put pass there until you put something in there. Okay, so we have those functions, but we need to put something in there. When we start it, what do we want? We want to change this button so that it says stop. So you can press that button to stop and set our variable of running to true. So let's go ahead and do that. We're going to say our button.text equals stop. And we're going to set running equals true. When we stop it, what do we want to do? Well actually, the opposite of those two things. So we're going to take that and I'm just going to say button equals start. So when it's stopped, the button will say start so you can start it. And we're going to say that it's currently not running. Okay, next let's go ahead and create our process loop. So we're going to say if running, so if the timer is running, we're going to get time. Okay, we haven't saved anything yet. So let's go ahead and quickly save that. And I'll hit F5, it's going to ask for the default scene. We're going to choose that scene. And here we go, let's see, have we done everything we need to so far? That is not right. Okay, let's see. It's counting seconds. Let me stop it and start it again. Okay, here we go. We need some more stuff in our start function here. So let's go ahead and we are going to set the start time. That's something important to do because right now it's set to zero. So we're going to say start time equals, and we're going to say get, so OS, get Unix timestamp, or time, let's go ahead and click start. There we go. It's counting and it's going to keep accurate time for us. Every time it loops, it's checking how much time has passed since that start time. If we click stop, what happens? It starts all over again. So we stop it and we start it. Our program's pretty much done besides a few cosmetic things we're going to do at the end. But let's say you accidentally close the program or you restart your device. Can we keep the timer going? Yes, if we take that start time, save it to a file, and when we open up the application, check that file, we can shut down our device, turn it on a year from now, and it will calculate the right time. All the hours will be huge because we're not doing days or weeks in here. But let's go ahead. Again, I'm going to copy and paste code, but I'll explain it all just for time to save. So we have a save time function and a load function. So what this is saying, okay, we're going to create a new config file. We're going to create that file, and I was putting this into a error, but we don't ever check that error. So you're supposed to check the error, but I'm not doing that. And then, I'm sorry, I'm just thinking about my code here. It can be cleaned up a little bit. Anyway, we're going to open up a file. We're going to load this file. We don't need this right here. We're going to remove it from here too. Technically, you should check for errors when you're opening and saving the files, but we don't need to. So I'm going to load this config file, or open this config file, and then I'm going to say, okay, we're going to create a category called timer. We're going to have a variable in there called time, and we're going to set it to whatever time we pass it. And then we're going to save that. So we're going to open it, right to it, save it. Down here, when we are loading it, we are going to create a new config file variable. We're going to load that file. We're going to check inside the timer section, is there a variable called time? If there is, grab it. If not, we're going to set the default to zero. Okay? And then we're going to check, okay, if the time does not equal zero, meaning that the timer had been started previously, we're going to change the button to say stop, or we're going to say running is true. Now, all we have to do is add to our load, or our ready, we're going to add in that function load time. One other thing we need to do, so when we load, it's going to check that, but we need to set it to save that. So when we start, we click the start button, we're going to say save time. That's the function we just created, and we're going to pass this start time variable. And I believe that should be it. So if I hit F5 now, it starts up. We don't have a previously saved time. I can go ahead and click start. It starts counting. If I hit stop, it's going to restart it when I click start, okay? But if I was to close this, so I'll just close that window, and I'll start the program again. If we've done everything right, you can see it continued counting. So we're at 10 seconds, go 11, 12, 13, 14. The program is completely closed right now. It's not running anywhere in memory. I'm going to hit F5, it's going to load up, it's going to check that config file and continue where it left off by calculating the time that it's passed. So again, I can shut down this machine. As long as I don't delete that config file, we are good to go. A few more things we want to do real quick. Let's go ahead and go into project settings. I'm going to go to this boot splash screen, I'm going to choose this little boot screen. I am also going to come up here and say clear and I'm going to look for where it says environment. I'm going to change the background to be a darker color, probably a darker blue I think would look good. And then we also want to go down here and for mobile devices, we don't want it always in landscape or portrait. We're going to allow it to rotate. So we're looking for display, display window. We're going to go down here and we're going to say sensor. So it'll rotate when you rotate your phone. Go ahead and hit F5 again. You saw our little load screen and here we go, it's still counting. Now if we were to stop it and close out of it, it's going to still count. That's something we might want to change, but for right now we can always stop and start. So even if you stop it, if you restart it, it's going to start off, continue going from the original time. Again, this is a very basic example, but if you're already in a real app, you probably want it to when you hit stop, clear out that save file. You know what, I didn't do that originally. Let's go ahead and do that now. I'm going to just, I think if we just take our save time and pass it the number zero, that should work. So now if we stop, okay, we can start, starts over again. We can stop, if I close it and reopen it, let's see, I'm sorry, back up at zero. But if I don't click stop and I close it and restart it, it continued where it left off. Perfect. And now that I have my phone plugged in, before I export it, I push it to my phone. I have to go to export, say create Android. I'm going to change this to be my website, come that, films by Chris. Go ahead and close that. And we will push it to the phone. Now it all goes well. It will push it, it will package it up as an APK, pushing my phone and directly start it, although sometimes you have to manually start it. It all just ends. There we go. And there we go, it's starting up. There we go, there's our timer. You got it going, click stop. It says five seconds there, click start again. And it's going again. And again, so it's counting right now at five seconds, six seconds, seven seconds. I'm going to show you, I can now restart the device. You can see it shutting down. And if we did everything right, that timer's still going to be going when it starts back up. But I'll take this moment to say thank you for watching. Please visit my website, filmsbychris.com, that's Chris the K, there's a link in the description. If you enjoy my videos, you can support me over at patreon.com, forward slash metalx1000, there's a link to that in the description. I really appreciate it. If you can't support me monthly, but want to give a one-time donation, go to my website filmsbychris.com. There's a donation section with a link to that Patreon page, but also a link to PayPal. I know it's not the best. I should probably get some other ways for you guys to support me. But if you can't support financially, that's fine. Like, share, subscribe. You know, more people will watch my videos, the better. You know, when I upload a video, it does great for the first day or two. I'll get a couple hundred views, but then after that they kind of peeter off for the most part. More people will watch them, the better. I appreciate it. I'm trying to think if there's anything else. Oh, it just finished booting. Let's go ahead and unlock it. And I will now open up that application. So it's opening up. There we go. And there we go. One minute, 27 seconds. They kept counting. Perfect. That's exactly what we need. As always, the code for this project, as well as all the assets, the font and icon, and load screen will be up on GitLab. But you can go there and get this code played with it. But I also recommend, you know, not just loading it up and trying it. Play around with it. Make it how you like. Throw your picture in the background or something like that. Again, this is a very basic example. You can do a lot more with this. But I hope that you learned something and I hope that you have a great day.