Stopwatch Part II: Advanced Stopwatch

Let’s continue with the ideas from my first post on creating a stopwatch.

If you have not yet created the basic stopwatch, then you’ll probably want to head back to the first post: Making a Stopwatch

Now, let’s extend this basic stopwatch with some added functionality.

Finished code

Here is a link to the finished version of the project. Feel free to run the project in the simulator. As before, if you’re planning on walking through this journey with me, then please don’t look at the code yet. You don’t want to spoil the story! :slight_smile:

Adding to the project plan

Updating basic information

In the advanced version of the stopwatch, we want to allow the player to pause and to restart the stopwatch by pressing A. We also want the player to reset the stopwatch by pressing B. Let’s update our project plan with this new information. Once you’ve updated the project name, project description, and events, take a look at my versions below.

Project name

MakeCode Arcade Advanced Stopwatch

Project description

This MakeCode Arcade project will display a stopwatch in a text sprite. The stopwatch will count up from zero. The player can start, pause, and restart the stopwatch by pressing A. The user can reset the stopwatch by pressing B.

Events

  • Player presses A
    • If the timer is running, then stop the timer.
    • If the timer is stopped, then start the timer.
  • Player presses B
    • If the timer is running, then stop the timer.
    • Reset timer variables.
    • Reset sprite text.
Basic stopwatch algorithms

Before we consider how to approach the advanced stopwatch, let’s take a step back and look at the algorithms for our basic timer. An algorithm is a series of steps that we can take to accomplish a goal. We use algorithms every day. For many of those algorithms, because we do them so frequently, we don’t even think about them!

Think about the steps that you take to start a new MakeCode Arcade project. It’s an example of an algorithm.

  1. Start a new browser tab or session.
  2. Open the MakeCode Arcade web site.
  3. Click on the New Project button on the MakeCode Arcade home page.

Each of those steps, in turn, could be expanded into their own list of steps. Each step, then, is its own algorithm.

We have three algorithms for our basic timer: One starts the timer, one stops the timer, and the last displays the timer in the text sprite. That last algorithm accepts a parameter: the time to display in the sprite. Pause here and try to write these algorithms yourself. Feel free to refer to your code. Once you’ve done so, compare your algorithms with mine below.

Algorithms

Start timer

  1. Save current game time in startTime variable.
  2. Set timerIsRunning to true.

Stop timer

  1. Set timerIsRunning to false.

Display timer

Parameter: Time to display

  1. Update the text sprite with the value of the parameter.
Advanced stopwatch algorithms

Now, we need to figure out how to start the timer after it has been stopped. Let’s consider an example.

When the player presses A, let’s say that we store 14 in our startTime variable. The sprite updates as it should. Later, the player presses A again, and the timer stops updating. Let’s say that, when the player presses A a second time, the timer stops and shows 27 seconds.

When the player presses A again to restart the timer, the timer resets to zero and starts counting again. That was fine for our basic timer, but that’s not the behavior that we want for our advanced timer. What if we could add that previous time–27 seconds–to the restarted timer?

That’s precisely what we need to do. We need to save the amount of time that elapsed when the player stops the timer. We sometimes call this type of variable an accumulator, because it collects (or accumulates) data as it is generated. More specifically, as a new piece of data is stored in an accumulator, it is added to the existing value.

When we are updating our text sprite, we can add this accumulated value to the current time.

Give this a try. See if you can alter the algorithms that you created previously to handle this new ability to pause and restart the timer. While you’re writing, see if you can write the algorithm for resetting the timer, too. We also have identified a new variable; let’s add that, too, to our project plan. After you’ve made your changes, compare your algorithms with mine below.

Variables

  • timerIsRunning
    • Data type: Boolean
    • Indicates whether the timer is currently running.
    • Value at start of the program: false
  • accumulatedTime
    • Data type: Number
    • Accumulates time when player pauses the timer.
    • Value at start of the program: 0

Algorithms

Start timer

  1. Save current game time in startTime variable.
  2. Set timerIsRunning to true.

Stop timer

  1. Add elapsed time to existing value of accumulatedTime.
  2. Set timerIsRunning to false.

Display timer

Parameter: Current time to display

  1. Update text sprite with value of the parameter plus value stored in accumulatedTime.

Reset timer

  1. Set timerIsRunning to false.
  2. Set accumulatedTime to 0.
  3. Reset text sprite.
Final project plan

Project name

MakeCode Arcade Advanced Stopwatch

Project description

This MakeCode Arcade project will display a stopwatch in a text sprite. The stopwatch will count up from zero. The player can start, pause, and restart the stopwatch by pressing A. The user can reset the stopwatch by pressing B.

Sprites

Stopwatch sprite

  • Text sprite
  • Located at top center of screen
  • Displays current timer in seconds

Events

  • Player presses A
    • If the timer is running, then stop the timer.
    • If the timer is stopped, then start the timer.
  • Player presses B
    • If the timer is running, then stop the timer.
    • Reset timer variables.
    • Reset sprite text.

Variables

  • timerIsRunning
    • Data type: Boolean
    • Indicates whether the timer is currently running.
    • Value at start of the program: false
  • accumulatedTime
    • Data type: Number
    • Accumulates time when player pauses the timer.
    • Value at start of the program: 0

Algorithms

Start timer

  1. Save current game time in startTime variable.
  2. Set timerIsRunning to true.

Stop timer

  1. Add elapsed time to existing value of accumulatedTime.
  2. Set timerIsRunning to false.

Display timer

Parameter: Current time to display

  1. Update text sprite with value of the parameter plus value stored in accumulatedTime.

Reset timer

  1. Set timerIsRunning to false.
  2. Set accumulatedTime to 0.
  3. Reset text sprite.

Incorporate changes into code

We have quite a few changes to make to our code! Let’s approach this in two phases. First, we will make our existing code a bit more flexible and reusable by adding some functions. Then, we will add the new functionality to the project.

Create function to reset stopwatch

Let’s move some of our existing code into functions to make the code a bit more flexible. First, let’s create a resetStopwatch function. We will call this function in our on start block. Later, we’ll also call it from our event handler for the B button.

Move the appropriate blocks out of the on start container and into a new function called resetStopwatch. Feel free to take a look at my version, below. I’ll hide it behind a spoiler in case you want to try it yourself first.

Create functions to start and stop timer

Let’s move more of our code into functions. Specifically, let’s move the code out of our event handler for the A button into functions. We don’t have much of a reason to do this for our application, but I will explain later why this might be a good idea.

Create two more functions, startTimer and stopTimer, and move the code out of the if block in your A button handler and into these new functions. Again, feel free to take a look at my code below.

Add new event handler

Now, we can add the event handler for the B button. Because we moved that code out of our on start block earler, this event handler should be really easy to write!

Give it a try. After you’ve finished, compare your code with mine below.

arcade-screenshot (2)

Add accumulator variable

Now, let’s tackle the tough part: Adding the accumulator variable to our code. You have the information in our project plan that you need, so give it a try. If you get stuck, open the first spoiler, which will give you a plan of attack. If you’re still stuck, or if you get a working project and want to compare your code to mine, then open the second spoiler.

Suggested plan of attack

  1. Create the new variable in the resetStopwatch function.
  2. Update the stopTimer function to add the elapsed time to the accumulator.
  3. Update the updateStopwatch function to add the accumulator to the current time displayed.

Next steps

When we created the startTimer and stopTimer functions earlier, I mentioned that it wasn’t really necessary. All of that code could have stayed in that if block for our A button. The reason that we moved it out of that event handler might be more apparent now. What if we want to use this code in a game? What if, instead of the player controlling the stopwatch, we wanted to control the stopwatch within our game? Because we moved that code into functions, we now can call them from anywhere within our code … and not just in the event handler for the A button.

Now that we have a stopwatch that can be paused, restarted, and reset, what are some additional features that we could add in the future? Here are some ideas that I came up with. What ideas do you have?

  • Format the time within the updateStopwatch function. Perhaps round the displayed value to one or two digits, or have it print in different formats (e.g. include minutes when the timer runs over 60 seconds).
  • Change the colors of the text outline based on the amount of time that has elapsed.

As far as this tutorial is concerned, I plan on writing Parts III and IV down the road.

  • Part III: Write our advanced stopwatch in TypeScript (and, as an alternative, in Python).
  • Part IV: Convert the TypeScript code into an extension.

Have fun, friends!

6 Likes

This whole thing is a lot of fun right now. I can’t wait for a stopwatch extension as well!! :smiley:

1 Like

I’m not very good with typescript but I’m trying to learn it. But I think I have a good idea for the minutes part. You can make a variable that is the exact same thing of what the text sprite says. Then if the variable equals to 60, then we can stick it in a join with text block or something into the text sprite and make another variable for minutes and change minute by one. Then we go into hours if we wanted to

No Blocks needed. I tried duplicating the blocks in your javascript game. Took me a couple hours to try to copy this. One step closer into learning a little bit of javascript

1 Like

Nice! You’ve learned about adding multiple files to your project!

When I write Part III, we’ll look at different ways of structuring this code. Specifically, we’ll look at something called object-oriented design.

1 Like

This will be a long journey. A lot of fun as well!

1 Like

I don’t know how to make blocks with these specific javascript pieces in the block.
I have a pretty good idea on how you should make the block look. All I’m good at is designing these things.


This is only one of my block idea. I didn’t have enough time