Chapter 3.2 - Paint Pot Tutorial
Time Estimate: 90 minutes
Paint Pot is a basic “finger painting” app. It simulates the process of dipping your finger in a pot of paint and then drawing on a canvas. The app uses buttons to simulate dipping your finger in the paint and uses Thunkable’s touch event handlers to draw circles and lines on the canvas.
Objectives: In this lesson, you will learn to:
follow an instructor-led walkthrough to create the PaintPot app on a mobile device.
continue navigating the Thunkable programming platform.
develop your understanding of what a Thunkable program is.
deepen your understanding of event-driven programming.

Getting Ready
Open Thunkable in a separate tab and follow along with the following tutorial. Create a new project called PaintPot.
The Paint Pot UI
The UI for our PaintPot app will consist of User Interface (UI) components -- four Buttons and a drawing Canvas.

As you can see, the Red, Blue, and Green buttons are arranged horizontally along the top of the screen. These are used to set the paint color.
You will add an image to be contained on the canvas component.
And the “Wipe” button is below the canvas.
Adding Red, Blue, and Green Buttons
Drag three Button components out and place them on the screen.
Select each Button in turn and change its Text and BackgroundColor properties, so that they match its function. So the red button should be red and should be labeled “Red” as shown in the screenshot.
Renaming Components with Descriptive Names
So far, we’ve been using Thunkable’s default names for our components. Our three buttons are named Button1, Button2, and Button3. But this will be confusing when we switch to the Blocks Editor, where you can no longer see that Button1 is red. You’ll want to give your buttons’ names that are more descriptive of their function in the app.
You can give them any names that are meaningful to you. But if you give them names that begin with “Button”, then they’ll all be right next to each other and easier to find in the Blocks Editor’s Toolbox, for example:
ButtonRed
ButtonBlue
ButtonGreen
To rename a component, just select the component by clicking on it in the Viewer or in the Components panel. Then, click the name in the properties panel and type in an appropriate name in the name textbox.
Adding the Canvas
In Thunkable, all animations, drawing, and painting take place on a Canvas component, which is also used as a background for interactive games.
Drag a Canvas UI component out and place it just below the row of color buttons.
Adjust the Canvas’ Height and Width property to take up more of the screen.
Delete the Sprite1 component from Stage1.
Select the Stage1 component that was added as part of the Canvas component. Set the Stage’s Touch Drawing property to true
Set the Stage’s Drawing Color property to red, overriding its default color, which is black.
Set the Stage’s Background Picture property to the kitty.png image (or another image).
Adding a Wipe Button
Add another button component to the Thunkable viewer. Change the color to black and text to “Wipe”. Rename the button as ButtonWipe.
Your Viewer should now look like this.
Event Driven Programming. If you recall from the I Have A Dream app, we had one button and we had one block for responding to its “click” events. How many different events will this app have to handle in the code editor view? What would you guess?

Coding the App’s Behavior
There are three buttons, each of which will have its own Button Click event. Plus, we want to be able to draw dots and lines on the Canvas. This means it will need to respond to a pointer-down event, in addition to the built-in touch drawing. Let’s see how this goes.
Setting A Property’s Value
For this app we’ll be using a new kind of block to set, or change, the value of the Stage’s Drawing Color property whenever one of the color buttons is clicked:

Note that this block has a to slot that looks like a jig-saw piece. This is where you would plug in an appropriate value for the property. In this case, we are plugging in the color red (which can be found in the Toolbox’s Colors drawer).
Set blocks are very important, and we will be using them in almost all of our apps. One of the features of Thunkable is that each type of component has a single set block, which is known as a mutator in Computer Science, that can be used to set any of that component’s properties. This is done using the drop-down menu on the block:

In this case, we are using the Set block to set the value of the Drawing Color property. But this same block can be changed (mutated) to set the value of the Width or Height and so on.
Handling the Button Clicks
We will need three When Button Click blocks, one for each button. For the color buttons, when one of them is clicked, we want to set the Stage’s drawing color to its color. For example, for ButtonRed:
Click on the ButtonRed component in the Toolbox. Drag When ButtonRed Click block into the Workspace.
Click on Stage in the Toolbox and drag its set Stage1’s Drawing Color block into the ButtonRed’s do slot. Make sure to select the Drawing Color property from its mutator (pull-down menu).
Click on the Colors in the Toolbox and drag out the color Red and plug it into the to-slot on the set block.
When you’re done, the finished block should look like this:

You should repeat these same steps for each of the other When Button Click blocks. As a shortcut, you could use the Copy (Ctrl-C) and Paste (Ctrl-V) keys to copy this block and change the names of the components involved. But be careful to name things correctly.
Responding to a Touch Event
While the various button events are important for the behavior of the app, it is the pointer down events that give the app its ability to draw on the screen. Here is what the pointer down block looks like:

Notice that this block has a pointer parameter that refers to each mouse or finger that touches the canvas. The pointer has an x and y property that represents the x- and y-coordinates of the pointer down event’s location -- i.e., on what pixel, given by its (x,y) coordinates, did the user touch the Canvas.
These properties are given values when the event occurs -- that is, in this case, when the Canvas is touched. To access their values, we will use Getter Blocks, which are located in the Toolbox’s Canvas Blocks Motion drawer:

For example, here’s how we use these the pointer down event’s (x,y) pointer values to draw a circle of radius 5 at that same location:

In this case, we are using the Canvas Blocks Look’s draw filled circle procedure to draw the circle. Note that the draw filled circle procedure has 5 slots, labeled x, y, radius, fill color, and on. These represent the circle’s (x,y) location, its radius, its fill color, and the canvas that it will draw on. When we plug the Canvas’s pointer x block into the x-slot and the Canvas’s pointer y block into the y-slot, we are setting the circle’s location. Similarly, by plugging the value 5 into the with radius slot, we are setting its radius. We are also setting the fill color of the circle by plugging in a from Stage1 get Drawing Color block from the Canvas Blocks Stage blocks.
Canvas Drawing Methods
In addition to draw filled circle, the Canvas component has several other drawing procedures that you can experiment with in your app. Here are some of the others:


Clearing the Canvas with Wipe Button
Add an event for When ButtonWipe Click. Use the clear drawings method from the Canvas Blocks Looks toolbox. It should look like this:

Testing and Increasing the Dot Size
Nice work! Now try out your app and test that it works. Do you notice any limitations? To start, did you notice that all of the paint dots have the same radius -- 5 pixels. Let’s take another look at the draw filled circle method that we used to draw a dot whenever the canvas was touched. As you see here, the radius is always set to 5. Every dot will have a radius set to 5. The radius will never change!

Programmers refer to the number 5 here as a constant or a literal value because its value never changes -- it is literally 5. How can we make this more flexible? How can we enable the app to draw dots of different sizes?
Abstraction to the Rescue
Let’s think about what would happen if we replaced the number 5 in the above block with a symbol, such as dotsize, that can represent any value:

Now, when a dot is painted, its radius will be whatever value that dotsize represents. If we set dotsize’s value to 5, then it would draw a dot of radius 5. If we set it to 8, it will draw a dot of radius 8. And so on. So, rather than just being a constant, such as 5, dotsize is an abstract variable that can stand for any value. This is a simple example of the abstraction principle. We will see many other examples in this course. But we can’t implement this just yet. First, we will need to create an app variable.
Creating and Using App Variables
In Thunkable, dotsize is an example of an app variable. You can think of a variable as a storage container that can store any value, and it can be used globally throughout the app. App variables have to be created and given an initial value using a special block that is found in the Variables drawer of the Toolbox. When creating an app variable, you should give it a unique, but valid, name. Variables in Thunkable, as in many other computer languages, must be strings of letters and digits (no quotes) and cannot start with a digit. An example of an invalid name would be 10seconds.
Here’s how we define and initialize our app dotsize variable:

We have given dotsize an initial value of 5. So if we added these two blocks to our app and did nothing else, it would behave just as before -- all dots would have a radius of 5 because that’s the current value of dotsize.
Of course, Thunkable also has blocks in the Variables drawer to set and get the value of an app variable:


For the set block we can set the value of dotsize to whatever number we put in its to-slot. By using a get block we can get dotsize’s value and plug it into any slot where it will fit -- just like putting together a jigsaw puzzle.
Now that we’ve created the app variable dotsize, we can replace the constant 5 with the getter block, for app dotsize, as we discussed in the previous section.
Example: Adding 1 to a Variable
Variables that store numbers, such as dotsize, can be used in arithmetic. To see this, let’s pull an addition block and a number block out of the Math drawer:
Notice that the open slots the addition block has the correct shape for plugging in either a value (such as 0) or a variable (such as dotsize):

Thus, we have created an expression whose value is (dotsize + 1). Since we have initialized the dotsize to 5, then the resulting expression would have the value 6, (dotsize + 1) or (5 +1).
Now, this expression block can itself be plugged into any slot where a value can be plugged. For example, we can plug it into dotsize’s set block:
This is a Thunkable example of an assignment statement. The value of dotsize is set to the result of the expression, which is its current value + 1. dotsize will now have the value 6.
Drawing Different-Sized Dots
How might we use this newfound ability to enable our app to draw different-sized dots? One way would be to add two Buttons to the app, one labeled ‘+’, which adds 1 to dotsize whenever it is clicked, and the other labeled ‘-’, which subtracts 1 from dotsize whenever it is clicked. It might also be nice to add a Label Component that will display the current value of dotsize and to update its value whenever one of the buttons is clicked.
In other words, we want to change our UI so that it has the following additional components:
(NOTE: You could use two Labels for this task, one for the prompt, “Dotsize = “, which never changes, and one for the current value of dotsize (e.g., 5), which will vary when the user changes the dotsize. In this example, we will show how to use a single label that concatenates or joins together two or more separate pieces of text called ‘strings’. In this case, concatenate the prompt and the value.)
Coding the Plus Button
Whenever the plus (‘+’) button is clicked, it should perform the following operations:
Add 1 to the app dotsize.
Concatenate the prompt (“Dotsize = “) and the app dotsize using a join block from the Text drawer:

Display dotsize’s value in the LabelDotsize. To do this, we set the label’s Text property.
Here’s what the block should look like:

It has two statements. First it adds 1 to dotsize -- we saw how to do that above. Then it sets the label’s Text property to the string “Dotsize = dotsize “ where the variable dotsize is replaced by its current value. The coding for the (-) button is left as a mini-project.
Issues displaying the Buttons and Background Picture
You may encounter issues with displaying your Buttons and Background Picture when testing with either the in-window Preview or with the Thunkable Live App. Here are some suggestions to fix the display issues:
Go to the Screen1 properties and click the toggle for Scrollable to change it to true.
This fixes the buttons but somehow causes the image to not display correctly when getting the image from the URL.
To fix the image not displaying correctly:
Delete the URL from the Stage1 Background Picture.
Save the image from the URL on your computer.
Upload the image as the Stage1 Background Picture.
Change the Stage1 Height to 270 and Stage1 Width to 294. These are the original dimensions of the kitty image.
Change the Canvas1 Height to Absolute Size 270 and Canvas1 Width to Absolute Size 294.
(I have found other dimensions to work, e.g. 400x400, but I think they may depend on the device screen size.)
3.2.2. Learning Activities
Q-1: By default, when you add components to the MIT App Inventor Viewer they are laid out ___________.
A. Randomly
B. Vertically
C. Horizontally
D. Diagonally
Q-2: Which value would you set the Width property to if you want your component, e.g., a Button, to fill its container?
A. Max pixels
B. Fill container
C. Automatic
D. Fill parent
Q-3: Which of the following would be a good name for a button whose purpose was to allow the view to refresh the screen? (Choose all that apply)
A. Button1
B. ButtonRefresh
C. RefreshButton
D. B1
E. ButtonOne
Tutorial Part 2: Varying the Size of the Dots
Watch the video tutorial below or click here for the text version of the tutorial. (TeacherTube version)
AP CSP Pseudocode: Variables and Assignment Statements
A variable provides a way to name a memory location in your program to hold different values. It is a data abstraction that exists in all programming languages. In MIT App Inventor, we set up a variable using the initialize global variable block. The get block is used to get the variable's current value whenever needed in the program. The set block is used to assign or change the value of the variable.
![]()
The AP CS Principles Exam does not have a designated programming language. It uses pseudocode, which is a cross between computer code and everyday English. Pseudocode is less precise than actual computer code, such as Java or Python or MIT App Inventor, but more precise and less wordy than everyday English. The AP CSP Reference Sheet is provided during the exam to help you understand the AP pseudocode format used in the exam. It includes two pseudocode styles: text-based and block-based.
In the College Board AP CSP exam, MIT App Inventor set blocks are called assignment statements and are represented as the left-pointing arrow (←). The following text and block style pseudocode is used to assign values to variables:
Function
AP Text
AP Block
MIT App Inventor
Assignment:
a ← expression
a ← expression
![]()
The DISPLAY statement is used to display variable values or the value resulting from mathematical expressions like (a+b)/2. Expressions are made up of values, variables, math operators, and sometimes mathematical procedures like getting a random number or squaring a number. In mathematical expressions, the operators * for multiplication, / for division, and the mod operator (remainder after division) are done before + and - like in math, unless there are parentheses that for example tell the computer to do (a+b) first before dividing by 2. Notice that * is used for multiplication instead of x, because x would get confused with a variable name. Expressions are evaluated to produce a single value.
Function
AP Text
AP Block
Display:
DISPLAY(expression)
DISPLAY expression
Expressions:
a + b, a - b, a * b, a/b
a + b
For example, here is AP style pseudocode to set the dotsize variable to 5 and then increment it (add one to it). The variable dotsize will have the value 6 after these two lines of code are executed. The value stored in a variable will be the most recent value assigned.
Function
AP Text
AP Block
MIT App Inventor
Set dotsize to 5
dotsize ← 5
dotsize ← 5
![]()
Increment dotsize
dotsize ← dotsize + 1
dotsize ← dotsize + 1

Some exercises involving AP pseudocode for assignment are below. More complex AP pseudocode will be shown in Unit 4.
3.2.3. Summary
In this lesson, you learned how to:
Learning Objective AAP-1.A: Represent a value with a variable.
Learning Objective AAP-1.B: Determine the value of a variable as a result of an assignment.
Learning Objective AAP-2.B: Represent a step-by-step algorithmic process using sequential code statements.
Learning Objective AAP-2.C: Evaluate expressions that use arithmetic operators.
3.2.4. Self-Check
Vocabulary
Here is a table of some of the technical terms we've introduced in this lesson. Hover over the terms to review the definitions.
variable
assignment
expression
operator
pseudocode
Check Your Understanding
Complete the following self-check exercises.
Q-4: Which of the following would be a valid MIT App Inventor variable name?
A. 5
B. -5
C. "user name"
D. userName
Q-5: A variable is an abstract symbol that refers to some particular value. Which of the following symbols is a variable? (Choose all that apply)
A. "hello"
B. paintBrush
C. 10
D. x
E. true
Q-6: Suppose you initialize dotsize with the block
.
Which of the following blocks would you use to change the value of dotsize?
A.
B.
C.
D. None of the above.
Q-7: What value will the variable dotsize have after the following sequence of blocks is executed?
|blank|
Q-8: Using a variable is an example of abstraction because (Choose all that apply)
A. Using a variable instead of a specific value makes an app more generally useful.
B. A variable is an abstract symbol that can represent lots of different values.
C. A variable is more general and more abstract than a specific value, such as 5.
D. Using a variable instead of a specific value makes an app more vague.
Q-9: What does the following AP CSP pseudocode display? Remember to trace through the code keeping track of the values in a and b after each line of code.
a ← 1 (Set a to 1)
b ← a (Set b to the current value of a)
b ← b + 1 (Add 1 to b)
a ← a + b (Set a to be the current value of a + b)
DISPLAY(a)
DISPLAY(b)
A. 2 3
B. 2 2
C. 1 1
D. 3 2
Choose one
3.2.5. Reflection: For Your Portfolio
Answer the following portfolio reflection questions as directed by your instructor. Questions are also available in this Google Doc, where you may use File > Make a Copy to make your own editable copy.
Last updated