Programs become mazes.
In order to navigate these programming mazes, we need to visibly chunk out blocks of code so that our programs are easier to read and use. To achieve this we will create our own custom functions() and these new custom functions() will work as modular nuggets of code. Essentially, we will write blocks of code and store them at the bottom of our program ready to be called when we need them. These new custom functions() are described as “user defined” because we made them. They are not pre-existing in the Processing built-in function collection like, for example, ellipse, rect, mouseX and mouseY. These are custom, modular functions() that break-up larger programs into smaller parts and help us quickly see and manipulate our code sections.
Section 1. Defining and Calling Functions()
This example shows a user defined function() named Greencircles(). Greencircles() has been called by draw().
1. Make your own design that has 2-3 shapes created inside of draw().
(If you want to challenge yourself then write this design with a “while” or a “for” loop inside of draw.)
2. Name your design.
3. Looking at the above green circle model on how a function() is written, now program your design as a user defined function with the name you just gave it.
Section 2. How to Organize a Program into Useful Custom Functions()
Once you determine the most useful way to divide up your code into functions(), then you can simplify the way you organize your programs. When you take the lengthy code instructions out of the draw() function and relocate them as new custom functions(), your code becomes manageable.
Here’s the above code sorted into 3 user defined functions():
Take a look below to make sure you understand how things are organized.
Note the simplified code inside of the draw() function.
The difference between using custom functions() and not:
With the code of your program reduced to custom functions() inside of draw, you can quickly make adjustments to particular code blocks to troubleshoot or make changes. As you know, you can debug your code easily by reductive testing (commenting out lines and examining the changes). By sequentially deactivating your custom functions() inside of draw() and then running your code, you can narrow down which of your user defined functions() might have an issue.
1. Code the following program and save it.
2. Next, reprogram it into 3 practical custom functions(). Name them as you see fit.
3. Lastly, comment out each function() you wrote inside of draw and see what happens when you push play.
Section 3. Getting Functions To Do More
Staying organized with easy debugging is handy! But, we want our functions() to do more. For example, our functions() could save us time by helping us to quickly generate and manipulate repetitive designs.
Take the 1980’s video game Frogger.
Many repetitive forms. It would be quite painful to write the code for each instance of a frog, car or log.
Take a look at this code (without functions) for two simple cars.
You don’t have to type and run the following program but you should notice things that seem redundant or inefficient!
What if I needed 20 variable cars? To escape the tedious and time consuming task of repeatedly using the same code in succession, we will program custom functions(). We also want our functions() to efficiently shift the size, color and positions of several cars with just one block of code. In order to do this, we need to expand our understanding of functions() by adding arguments.
Section 4. Arguments
Our functions() need to be told what to do! We need to tell them what parameters we want to change such as size, color, and/or motion? The parameters of our custom functions() are specified by arguments.
We have used arguments with built-in functions() before:
With one custom function, in this case, “car()” and the use of arguments, we will be able to create multiple car designs with endless variations through draw(). To do this, we must pass on the parameters of our functions() to draw(). The next few steps will show us how to do this…
Exercise 3: Take a look at the following program carefully and answer the questions below.
(You don’t have to type and run the following program, you should be able to get answers from just looking!)
In the above function() where are the 5 variables?
What does each variable control on the car design?
If you were now going to program the drawCar() function inside of draw(),
guess where your arguments would go so that you can control the car’s parameters (size, color, etc)?
It is just a guess but try to think about it logically.
How could you create more than one car sketch inside of draw()?
This is also a guess but it is worth analyzing logically.
Exercise 3.1 Code the following program and answer the questions below.
Explain why 3 cars appeared when you ran the code?
Why did the 3 cars vary in shape and color with only one function, drawCar()?
Important Things To Remember About Passing Parameters:
1. You must pass the same number of parameters as are defined by the function() you created.
2. When a parameter is passed it must be the same type. This means integer to integer, float to float and so on.
3. The value you pass can be a literal value (3,50, etc), a variable (x,y,etc) or the result of an expression (8+3, 4*x/2, random (0,10), etc.)
4. Arguments act as local variables to a function and are only accessible within that function.
Make the above cars in color. To do this you will need to add two more parameters to the above drawcar() function and use draw() to pass the parameters so that the cars change from grayscale to RGB color.
Program the following and fill in the 3 missing lines of code to create a car that moves back and forth like the bouncing ball example. Try to guess and plug in a few lines before you peek at the answer.
Note: Global variables are now named globalX and globalY to avoid confusion with the local variables x and y in drawCar().
Analyze the code example explaining the variable data type called “color” from the Processing reference example. Can you explain every line of code and figure out why color events are happening?
Practice using the new variable/data type called, “color.” As you see in exercise 4.1 – the color variable makes things easier so that you don’t have to declare 3 different variables for R,G,B. For this exercise, write a quick and simple program with 2 ellipses() and 2 color variables – keep it simple and explain how this variable type works with in your comments
Here’s the hard code for one yellow star.
A. Rewrite the above code with a function() and draw 3 stars in different positions (any 3 positions).
B. Now, rewrite the code with a loop so a line of stars appear somewhere on your screen.
C. Now, annotate the code you just wrote for exercise B and explain how the 4 different variables work. You have:
Explain the relationship between the variables used inside of the function and those that are used globally.
D. Next, rewrite the program using mouseX and mouseY so that stars appear when you click your mouse.
And, annotate your program to explain why the position of your mouse is centered on the star.
Now, remix the above code into a really excellent design of your choice. Make something cool!
Section 5. Return Type
You may have noticed that we have repeatedly coded the word “void“ in our programs without explaining why. For example, “void setup()” and “void draw()” are common in our code. Void literally means “nothing” and when you use void to define a function() there is nothing returned. User defined functions() have to specify their return type and void means no return.
This rule is illustrated by two examples from Processing’s built-in function set (remember there are tons of handy built-in functions ready to use that you don’t have to define).
Example function() with no return, AKA void:
rect (x,y,w,z); —> there is no value calculated/returned – just a rectangle drawn.
Example function() with a return:
random(100); —> this function returns a value between 0 and 100.
So far, our user defined functions() have not needed to return a value. This is common for computer generated design. However, it is good to keep in mind that you may need to perform a calculation with a custom function() in the future. Functions() that return values are traditionally used to perform complex calculations that may need to be performed multiple times throughout the course of a program. So, if this mathematical need comes in your coding future then note that your return type will no longer be “void“, it will become “int“, “float” or another value identifier.
If the above concepts aren’t clicking for you or if you would like a fun review of these coding ideas, then try watching the very animated and informal free video tutorials by NYU professor and Processing champion, Daniel Shiffman.
The videos which reference this webpage:
Also, functions are explained here in another way by Jose Sanchez of the Plethora Project.