DOM-E5152 - Introduction to Creative Coding, Lecture, 14.9.2021-1.10.2021
This course space end date is set to 01.10.2021 Search Courses: DOM-E5152
Topic outline
-
This course is an introduction to the basic concepts of programming – no previous skills are required. Part lectures, part exercises and then a larger individual assignment. We'll meet 9:15–12:00 four mornings every week. The classroom is M102 in Väre.
- Week 1
- Sep 14: Kickoff, arrangements, basics of programming, setting up
- Sep 15: Making graphics in Processing, variables
- Sep 16: Simple math, interaction with mouse, comments
- Sep 17: Flow control part 1, recap
- Week 2
- Sep 21: Flow control part 2
- Sep 22: Arrays, using arrays with loops
- Sep 23: Functions, parameters and return values
- Sep 24: Recap, using images, exercises
- Week 3
- Sep 28: More types, dealing with text
- Sep 29: Basics of object-oriented programming
- Sep 30: Lists, using callbacks for input
- Oct 1: Recap of the course, assignment instructions & tutoring
-
Links to useful places
- Processing.org
- Khan Academy's interactive programming lessons
- The Coding Train: Learning Processing, video tutorials
- Lev Manovich: Software Takes Command
- Nick Montfort: Experimental Programming for the Arts and Humanities
- Patricio Gonzalez Vivo & Jen Lowe: The Book of Shaders (for your interest, we won't get into this)
-
To pass the course, you need to be present at 80 % of the lectures, do the homework assignments, and complete the larger...
Final Programming Assignment
You are allowed to choose your own topic if you so please, but there will also be a ready-made option available below. A small project will earn you the minimum 3 ECTS, but if you do something considerably larger, you may earn up to 6. Discuss your idea with the teacher. Tutoring will be available before the deadline in case you need it – keep following your email for a Doodle link where you can book a meeting time.
The deadline for the assignment is October 18 at 23:59. Zip the sketch folder with all the required files and send it by email to the lecturer. If you're doing a larger project the deadline can be extended by a week or two. In any case, you'll have to put into some meaningful use at least:
- variables
- arrays or lists
- loops and if statements
- own function(s)
- comments
- interaction with either the mouse or keyboard
Default Option: Aliens!
Oh no! Aliens from outer space are trying to invade Earth, and we can't let that happen. You and your trusty laser gun are our last hope. Requirements:
- Aliens keep appearing from the top and moving down
- If an alien gets to the bottom of the screen the game ends
- Show the gun at the bottom of the screen
- You can shoot a laser by clicking with the mouse
- If you hit an alien it'll disappear
- Zapping aliens awards you points which are shown on the screen
Once you get it working you can experiment with things like more interesting motion, explosions for the aliens, title and end screens, different kinds of enemies and so on. If you extend the basic functionality far enough, it will earn you an extra credit point too.
Some tips
- You can consider the aliens rectangles or circles when detecting if you hit them
- Event handlers work well for games
- A list makes more sense here than an array here (both can be made to work though)
- Pay attention what happens to the list size and indices when removing items
- Start building the solution progressively: this first, then that and so on
- See previous days' examples for useful pieces of code
- cursor() will let you change the shape of the mouse pointer
-
Let's get started! Outline of the course, requirements, expected learning outcomes. Introduction to programming (see slides below).
Exercise in pairs: writing instructions. What makes for good instructions?
Finding your way around in the Processing editor. Making sure everyone has a working environment for real use.
Special characters
… and how to type them on your keyboard. We’ll need many of these when typing in our programs, since they have special meanings. Finnish translations for the non-obvious ones included (the tips work for a Finnish Mac keyboard):
- parentheses ( )
- square brackets (hakasulut) [ ] – alt-8, alt-9
- braces/curly brackets (aaltosulut) { } – alt-shift-8, alt-shift-9
- asterisk *
- slash (kauttaviiva) /
- pipe (putki) | – alt-7
- ampersand &
- equal sign, “is” =
- colon :
- semicolon ;
- comma ,
- hash (“risuaita”) #
- tilde (“mato”) ~ – alt-^-space
- single quote (heittomerkki) ‘ – note that this is not the same as accent ´
- double quote (lainausmerkki) “
- less/greater than < >
Program flow
Statements are executed (“run”) sequentially line by line. The order of the statements is crucial: changing it will result in completely different end results. Comparable to a cake recipe: there’s ingredients (data) and instructions what to do (program code, statements).
-
Basic graphics with Processing
See the Processing reference for a complete list of graphical primitives supported by the language – there’s a lot at your disposal. Get to know at least:
- size
- ellipse
- rect
- line
- background
- fill and noFill
- stroke and noStroke
One thing to note is that the graphics are not any objects you could move, scale and so on later, but pixels in the window: there's no way to edit them afterwards except drawing them again.
Variables (muuttujat)
We could consider variables “boxes”, where you can store things. During the following lectures they will be used for several purposes such as counters, for holding status information such as mouse coordinates and for making the code more readable. In Processing every variable has a type, a name, a value and a scope. Before we can use a variable we need to declare (esitellä) it, which looks like this:
int whatever;
The type in this case is int, an integer number (kokonaisluku). The name we can choose freely, except that it can’t overlap with reserved words of the language. The value is set through assignment (sijoitus):
whatever=100;
Finally, the scope is the area where a variable is visible. It can be global (yleinen) or local (paikallinen). More about that later.
Homework
Create the famous smiley face using Processing graphics. Make it so that you can place it anywhere on the screen by changing the values of variables x and y.
Example solution: smiley.pde
-
Simple mathematics in Processing
We can use variables for many kinds of calculations, such as addition (+), division (/), subtraction (-), multiplication (*) and modulo (%). Wherever we could put a plain number, we can put a variable or mathematical statements as well:
a=1+2; a=b*2; a=a+1; a=b/3+a*3-40+c*b;
Optionally you can insert spaces to make it a bit more readable:
a = b/3 + a*3 -40 + c*b;
To see the number (will appear in the black box of the processing window) use print or println: println(a);
I’d rather not talk about these for now, but in a lot of tutorials and examples you will find things like this:
a++;
b––;They’re only shorthand for a=a+1; and b=b-1; Use them only when you need to increment or decrement a variable by one, not in mathematic statements.
Interactive software
So far we’ve only made small sketches that are run once. For most uses we need to have the sketch running continuously. For this we need two things: setup (run once when the sketch starts) and draw (runs all the time about 60 times a second). Each screen refresh is known as a frame in the Processing terminology. Things that you need once, like opening the window go under setup, things that are done continuously go under draw. This is a bit different to many other environments.
With draw and setup we start running into scope issues. Variables declared inside draw are not visible in setup and vice versa. If you declare them outside of both, they're available everywhere – this is what was called local and global scope. A good rule of thumb is to declare variables only where absolutely needed instead of populating the global scope, which will often lead to trouble.
Comments (kommentit)
For the sake of clarity it’s essential to use comments. They serve both you and others reading your code. Comments are free-form and start with two slashes: // The rest of the line is ignored. Edit – Comment/Uncomment will do it automatically for you. Another use for comments is disabling a piece of code for testing purposes or testing two alternatives before deciding which one is the final one.
Using the mouse
There are global variables named mouseX, mouseY, mousePressed and mouseButton, which you can use for simple interaction. Their values are updated automatically and they don’t need to be declared (they’re declared somewhere else). Their values can be used as usual:
ellipse(mouseX, mouseY, 100,100);
Homework
Create a sketch that draws circles like in the example screenshot below. For each frame, draw a slightly larger circle so that they eventually fill the whole window.
Example solution: grow.pde
-
Flow control
In numerous cases we need to do things conditionally, a number of times, or until something happens. For those sort of purposes we have different flow control statements:
- if – do something if a condition is true
- if-else – do something if a condition is true, otherwise do something else
- for – repeat something a certain number of times. Consists of the initial counter value, condition and increment
- while – repeat something as long as a condition is true. Quite rare in Processing because of the way interactive sketches work, but common in other languages and environments.
Today we'll start with if and if-else. These statements usually start a compound statement, which is a block of code enclosed in braces. Anything you put in there will be run or repeated, according to the statements above. You can also nest the compound statements, placing them inside each other.
if(a>1000000)
{
println("It is a big number");
}
else
{
println("It is only a modest number"); }Comparison operators (vertailuoperaattorit)
All of the above need conditions. Comparison operators are used for comparing two things, such as numbers or variables. Some of the most common ones we’ll use in the future are:
- Equal: == (very easy to mix up with assignment, beware!)
- Not equal: !=
- Greater than: >
- Greater than or equal: >=
- Less than: <
- Less than or equal: <=
Homework
Create a sketch that draws yellow bubbles on the left side of the screen and green on the right. On the upper half of the screen the bubbles should be small and on the lower large. Like here:
Looks like a case for some if or if-else magic.
Example solution: yellowandgreen.pde -
Flow control, part 2
Today we'll learn how to repeat things with for loops and also experiment a little with while loops, which in this family of languages – but not some others – are easily interchangeable.
As we know by now, we can nest flow control statements ie. inside a for can be another for or if or many when needed. Nested loop example: nestedloops.pde
At times it can be confusing that we can (slowly) repeat things by simply placing them inside draw but also using actual loops. The difference is that when we do a loop with for/while things will be repeated for each frame separately.
Grouping conditions
Conditionals can be grouped, if you want to do more comparisons at once:
- And: &&
- Or: ||
For example: if(mouseX>100 && mouseX<200)
Indentation (sisennys)
It’s a good common practice to indent the contents of compound statements a few characters to the right, so that they are visually aligned. This way you can instantly spot the statements that are on the same level. Processing will do most of it for you automatically, but if your code has gotten ugly, you can clean it up by selecting it and then clicking Edit – Auto Format.
Homework
Using nested for loops draw a grid of white squares as seen below. In addition, implement a "mouseover" where a square turns red if the mouse is over it. Use if and suitable conditions for that.
Example solution: grid.pde -
Arrays (taulukot)
So far we’ve used variables, which let you store single values and work with them. Often we need to process large amounts of data, and single variables aren’t enough for that. Arrays let you store multiple values of similar type. Like variables, arrays too have: a name, a type, value(s), and a scope. In addition to that they have size, which is the amount of members in the array. So, if a variable is a box, an array would be a pile of those boxes.
An array can be declared the following way:
int ourstuff[] = {2,4,6,7,8};
After this line ourstuff is at our disposal and contains five numbers. It’s possible to create arrays also without assigning any values, only specifying their size. An array with 100 members:
int ourstuff[] = new int[100];
Array members (also known as items) can be used exactly like variables, through referencing (viittaus):
ourstuff[1]=2; ellipse(ourstuff[1],ourstuff[2], 10,10);
The number inside the brackets is known as index. The first index in C-like languages such as Java and Processing is zero. So, for ourstuff the indices are in the range 0..4
Arrays and loops
In general, arrays go together with loops, especially for loops. With a loop you can walk through all the members of the array when needed. The loop counter is used as the index. See here for an example: arrayloop.pde
Often we don’t know the size of the array beforehand, or its size might change. A safe way to go through all the items is to use the length property that all arrays have:
for(i=0; i<ourstuff.length; i++)
Homework
Make an array that holds the following data set consisting of consecutive x and y coordinates and colors:
100,100,#ff0000, 500,200,#00ff00, 300,500,#0000ff, 200,400,#808080
Plot it from the array using a loop. The outcome should look like this:
Example solutio: dataplot.pde
-
Functions (Funktiot)
Also known as procedures or subroutines (aliohjelma) in many languages. They are a way to structure your programs to meaningful wholes for the sake of readability, and to avoid unnecessary copypasting of the same code over and over (you can also break your sketch to multiple files and have functions there separately). Like variables, functions too have a name, type and a scope. In addition to that they may have a return value and parameters. We’ve already defined two functions, setup and draw. We can create other functions exactly the same way:
void myfunc() { println("Here we go!"); }
The function can be called by giving its name and parenthesis: myfunc(); This is exactly what we’ve been doing when we write things like size(640,480); or smooth(); How to make a simple function: simplefunction.pde
Parameters
Parameters are a way to pass information to functions. When defining a function the parameters go inside the parentheses: type and name. Inside the function they are visible as any variables.
void printsum(int a,int b) { print(a+b); }
A complete example with parameters: parameters.pde
Return value
When the type of a function is void, it doesn’t return anything back to the caller. In many cases we need to get something back, such as information about whether there was a problem. If we define a function with a type (e.g. int), we can return things from it with return. Return will also stop the function and jump back to the caller. See returnvalue.pde
Homework
Modify your previous smiley face sketch so that the face is drawn by a function which takes the x/y location as parameters. When the mouse button is pressed, call the function from draw with mouseX and mouseY, which lets you paint with the face as follows:
Example solution: smileypaint.pde
-
Recap
First, let's go through the topics we've covered so far and think of when we would need them.
PImage
PImages let us load and display bitmap images (jpg/png/gif/tga). You can add images to your sketch through Sketch – Add File. You can also download them directly from URLs, but then they obviously won’t work, if you don’t have an Internet connection. Example images for today: player.jpg and football.png. How to load images and display them on screen: images.pde.
Debugging exercise
Download the following sketch: mousefollowbuggy.pde and fix it! There are ten errors altogether: some of them just minor typos and some more conceptual problems. Here’s the fixed one: mousefollowfixed.pde
Paint program(!)
Putting everything we've learned so far into use: let's make a simple paint program that lets us draw with different colors and exit by clicking a button.
Homework
Make something funny, experimental or creative using PImage and everything we've learned so far :)
Here's what I did: fall.pde and the pic: raindrop-transparent-7.png
-
Decimal numbers (desimaaliluvut)
So far we’ve used only int type for our calculations. Often the precision is not enough: for example if you divide one by two you get zero instead of 0.5. For more precision we can employ floating point numbers (liukuluvut), which can store decimal numbers. Instead of int, declare your variable float:
float mynumber;
An example illustrating the difference between the two: intvsfloat.pde
Type conversion (tyyppimuunnos)
Processing is very strict about mixing variables and functions of different types. You can’t directly assign a variable of type float into an int. For example random numbers in Processing are floats, and that’s why you can’t assign them to int variables without conversion. Fortunately, type conversion is easy to do:
int a;
float b=random(100);
a=int(b);A few more conversions here: typeconversion.pde
Boolean: true or false
Often it’s handy to have variables that contain yes/no values. For them we have type boolean, which can only have values true or false. You can’t do any mathematical calculations with booleans.
boolean truth=true;
truth=false;One example of booleans that we've already used is mousePressed. Since booleans are either true or false they can be used as conditions: if(mousePressed)
Strings (merkkijonot)
A new type coming up. Ints and floats let us use numbers, but there’s many situations when other types are needed. Textual information can be stored in a String. Two common use cases for strings are user-entered data and reading a text file. You declare a string as any other variable.
String mytext;
Assignment is the same. A string is enclosed in double quotes:
mytext="Never gonna give you up"; println(mytext);
You can "add" a string after another with the plus sign (+). To convert a number into a string, use the function str() like in the examples above.
Displaying text
We’ve output text with println already, but to display text inside the sketch window we need to use PFont together with loadFont, textFont and text. Processing has its own bitmap font format. Save your sketch first and then click Tools – Create Font. How to do all of it: graphicaltext.pde.
Homework
Make a crosshair that follows the mouse. In addition, display the current coordinates in the sketch window like this:
Soxample elution: crosshair.pde
-
Basics of Object-Oriented Programming (OOP)
First some definitions:
- Objects are collections of functions (often called methods) and variables (often called attributes or fields). In other words, things that belong together are encapsulated into an object.
- Classes are object descriptions, which you then turn into individual objects (often called instances).
- Constructor is a required method that gets called when the object is created with the keyword new. Much like setup in Processing, it is meant for setting initial values for the attributes and doing other initial tasks.
We have actually been using objects before. PImage and PFont are two such examples. Both of them are logical wholes of things that belong together, much more complex than just simple variables.Let's see an example: simpleoop.pde
The constructor has the same name as the class. It often takes parameters that are used when setting up a new object in a particular way. At times there's collision between the parameter names and the internal attributes of the class, which can be solved using the keyword this:
class MyClass
{
int a;
MyClass(int a) // This is the constructor
{
this.a=a; // "this" refers to the object itself
}
}Just like with simple variables, there can be arrays of objects, and they can be passed as parameters to functions when necessary. There are many other things that go with objects, such as inheritance and protecting attributes from external access, but we'll look more into those on the From Data to Pixels course.
Homework
Create a class called Cat, which contains the following functionality:
- A constructor that lets us set the initial place of the cat at (x,y)
- A paint method (function) that draws the cat at its current location
- An update method that makes the cat move toward the mouse if it's not there already
Make two cats with the names duchess and thomas with different starting locations and make them follow the mouse pointer by calling their update() and paint() each frame. This might be a good opportunity to use PImage for a little prettier graphics than mine:
Example solución: cats.pde
-
Lists
So far we've used arrays when we've had to store multiple values – even an array of objects is perfectly feasible. The issue with arrays is that they're static by nature: changing their size is cumbersome and slow, and may involve useless copying of data back and forth. Inserting values into an array is likewise tricky. There are common situations where we would like to have more flexibility, for example in a game where enemies keep appearing and
dyidisappearing. For this purpose we have lists. Processing has the following kinds available for you:- IntList
- FloatList
- StringList
- And ArrayList which lets you store objects – we'll discuss this in From Data to Pixels
The most common operations you'll need are get() – get an item from the list, append() – add one more at the end, size() – the number of items, useful for looping, and remove() – take out one item from the list. See here for a complete list of available functionality and an example.
Why wouldn't we use lists always then? Traditionally they've been slower than plain arrays, in addition to which they may consume more memory. Furthermore, it's a bit trickier to access the individual elements of a list as opposed to an array.
Using Event Handlers (Callbacks) for Input
Like with the mouse, the simplest way to read the keyboard is to check the global variable keyPressed. If it’s true, key will contain the pressed key. It can be either a character in single quotes or a special value such as ENTER or BACKSPACE.
However, when you get serious about it, both the mouse and keyboard are better supported using event handlers, such as mouseClicked. A simple keyboard example: keyboard.pde. An advanced example of the use of event handlers: eventhandlers.pde
By using event handlers you can be sure that you'll never miss mouse clicks or button presses, unlike with the simpler method. Another plus is that you have more advanced control over the mouse movement, for instance mouseDragged, which would be hard to implement otherwise.
Homework
This time let's combine lists and event handlers. Let the user place green dots around the window by clicking the mouse. Store the mouse coordinates in a list so that you can redraw all the dots each frame – clear the window at the beginning of draw(). mousePressed() is a good event handler for this purpose.
Example solution: dotlist.pde
-
Today's bigger example: spacegame.pde
What's Next?
Now that you know the basics, you can continue to one of our several other programming courses. Many more are available at the Department of Computer Science, of course.
- From Data to Pixels – pretty much continues where we left off here
- Generative Media Coding – C++/openFrameworks
- Embodied Interaction
- Electronics for Artists – Arduino
- Interactive Art
- Contemporary Web Development – JavaScript
- Composing with Data Flow Programming – Pure Data
- Physical Interaction Design – more Pure Data
- Procedural Audio
- Software Studies for Game Designers – the Unity course
- Intelligent Computational Media
- Coding Virtual Worlds
Note that for the next academic year the courses will change and some might disappear -- act now if you want to take a particular one.
Assignment instructions on the left under "Assignments".