INTERACTIVe Patterns

In the basic introduction you can learn the programming syntax. However, to make interesting things with code one need to think in terms of combining the different programming components into basic structures. These structures are called patterns. They are similar to having a basic sewing pattern for a shirt, but the end result can be very different depending on how you use it. Programming patterns differ depending on what kind of programming one is doing. When working with interaction design there is a set of commonly known strategies for making interactive elements. The secret trick to mastering interactive programming is to recognize these patterns that makes up structures for common solutions to interactive problems. In the following we have collected the most common patterns that everry interaction design programmer needs to know to create interactions.

Long example: Programming PONG (as a pattern)

Core_programming_session_one.mov


In this video I go through the core concepts of programming with P5.JS by programming a simple pong game.

The video is a bit fast paced, so do make sure to pause and scroll back and forth.

Basic Pong:

https://editor.p5js.org/hobyedk/sketches/4T-l65OWi

Correct bounce on all axis:

https://editor.p5js.org/hobyedk/sketches/GrcQM_w8L

Many games are based on this pattern in some form.

Interactive pattern cheat sheet

We have tried to make the examples as generic as possible. Although there are only examples from one platform, it should be relatively simple to convert it to the other. Be aware that the main method in Processing is called draw(), where in Arduino it is called loop(). Simply change the words depending on the platform used.

function draw() {

var btnPressed = mouseIsPressed;

if (btnPressed == true) {

print("Button is down");

} else {

print("Button is up");

}

}

Doing something while a button is pressed

To change something while a button is pressed. The code looks like this.

var posX = 200;

var posY = 200;

var radius = 100;


function setup()

{

createCanvas(400,400);

}


function draw() {

background(0);


if(dist(mouseX, mouseY,posX,posY) <radius/2 )

{

fill(255,0,0);

}

else

{

fill(255);

}

ellipse(posX,posY,radius,radius);

}

Calculating the distance to use for detecting the hover/collision of the mouse

By using the dist() function you can see whether a mouse is over a circle. This is the simplest way to make an interactive button or to detect a collision between the mouse (the player) and an object.

var btnPressedOld = false;


function draw() {

var btnPressed = mouseIsPressed;


if (btnPressed == false && btnPressedOld == true) {

print("Button has been clicked");


}

btnPressedOld = btnPressed;

}

Detecting a push button event

The above example only works for doing something WHILE the button is pressed, and it is not the same as an event. An event is when something changes from one state to another; e.g. you want something to happen when the button is released => going from a pressed state to a not pressed state. This requires us to "remember" the old state an compare it to detect the change.

var btnPressedOld = false;

var toggle = false;


function draw() {

var btnPressed = mouseIsPressed;

if (btnPressed == true && btnPressedOld == false) {

// button has been pressed.

toggle = !toggle;


}

btnPressedOld = btnPressed;


if (toggle == true) {

background(0, 255, 0);

// the butten has been toggled on.

} else {

background(0);

}

}

Make a toggle button

Toggling with a pushbutton is a common solution to turning things on an off. This is one way to do it.

var btnPressedOld = false;

var timer = 0;


function draw() {

// do something every two seconds

if (millis() - timer > 2000) {

timer = millis();

print("tick");

//do something here

}

}

Make an interval timer

To make something happen every x miliseconds. This pattern is a generic solution.

var timeWhenPressed = 0;

var oldMouseState = 0;

var timerActive = false;


function draw() {

if (mouseIsPressed == true) {

timeWhenPressed = millis();

timerActive = true;

}


if (millis() - timeWhenPressed > 2000 && timerActive == true) {

// do something two seconds later

timerActive = false;

print("Two seconds later");

}

}

Timing an event

To time an event; e.g. you want something to happen two seconds after the button is pressed. To do so you need to register the time the button was pressed and look for when the two seconds has passed from then.

var btnPressedOld = false;


function setup() {

createCanvas(400, 400);

}


function draw() {

background(100);

if (mouseX > 100 && mouseX < 200 && mouseY > 100 && mouseY < 200 && mouseIsPressed) {

if (btnPressedOld == false) {

/// Code in here will only run once, when the mouse has clicked within a 100x100 square positioned at 100,100.

print("pressed");

}

btnPressedOld = true;

fill(0, 255, 0);

} else {

btnPressedOld = false;

fill(0,255, 255);

}

rect(100,100,100,100);

}

Detect a mouse click within a square

In Processing you sometimes need to design your own button interaction. To do this, we need to define the active area of the mouse pointer. Here is a simple pattern to solve this problem:

var value = 0;

var speed = 2;

var direction = 1;


function draw() {

value = value + direction * speed;

if (value > 255 || value < 0) {

direction = direction * -1;

}

background(value);

}

Fade in and fade out

To make something fade in and fade out you need to create a counter and add/subtract from it over time.

var positionX = 0;

var speed = 2;

var direction = 1;


function draw() {

positionX = positionX + direction * speed;

if (positionX > width || positionX < 0) {

direction = direction * -1;

}

background(0);

ellipse(positionX, height/2, 20,20);

}

Make an object move

To make something move you need to created a counter and add/subtract from it over time.

var currentState = 0;

var btnPressedOld = 0;


function draw() {



if (mouseIsPressed == false && btnPressedOld == true) {

currentState = currentState + 1;

if (currentState > 2) {

currentState = 0;

}

}

btnPressedOld = mouseIsPressed;


if (currentState == 0) {

background(0);


} else if (currentState == 1) {

background(0, 255, 0);



} else if (currentState == 2) {


background(0, 255, 255);


}

}

Creating a state machine

As the complexity of your code grows you will need to have multiple states where different parts of code should happpen in certain situations. Using a this pattern allows you to compartamentalise which part of the program should in any given moment. Each state represent at certain situation in your porgram. It could be the intro screen in a game, the actual game, the highscore etc.

var buttonPushedTime = 0;

var lastButtonState = false;


function draw() {

background(120);

if (mouseIsPressed && !lastButtonState) {

buttonPushedTime = millis();

}


if (mouseIsPressed && millis() - buttonPushedTime > 3000) {

print("button has been pressed for 3 seconds");

}


lastButtonState = mouseIsPressed;

}

Detecting a long press

Check if a button has been pressed for a particular minimum time (in this example 3 seconds). This can provide safety (e.g. for a reset button, check that someone actually means it, not just touched the button by accident) and provides implicit debouncing of a glitchy signal.

var turnRed = true;


function setup() {

createCanvas(400, 400);

}


var lastShot = 0;

var delay = 1000;

function draw() {

background(220);

if (millis() - lastShot > delay ) {

lastShot = millis();

//shouldBGRed =!shouldBGRed;

if(turnRed == false)

{

turnRed = true;

delay = 1000;

}

else

{

turnRed = false;

delay = 10000;

}

}


if (turnRed == true) {

background(255, 0, 0);

} else {

background(255);

}

}

Toggling with two different delays

Sometimes you want something to be turned on for one second and turned off for 10 seconds. This code does that.

Note: This code can be compressed - this example will toggle the background every one second (but hard to read):

background(255*Math.floor((millis()/1000)%2), 0,0);

var inputBuffer = "";

var inputResult = "";

var newInput = false;


function setup() {

createCanvas(400, 400);

}


function draw() {

background(220);

if(newInput==true)

{

print( inputResult);

background(255);

newInput=false;

}

}


function keyPressed()

{

//print(key);

if(key != "Enter" && key!= "Control" && key != "Shift")

{

inputBuffer = inputBuffer + key;

}

else if(key == "Enter")

{

inputResult = inputBuffer;

inputBuffer = "";

newInput = true;

}

}

Reading a line from the keyboard

This collects all the keypress characters until return has been pressed.

var balls = [];

function setup() {

createCanvas(400, 400);

// generat many objects at random positions

for(let i = 0; i < 20;i++)

{

// create a random vector postions

var randomPos = createVector(random(width), random(height));

// add it to the list

balls.push(randomPos);

}

}


function draw() {

background(220);


// loop through the ball vector array and

// draw an ellipse at their positions

for(var i = 0; i < balls.length; i++){

ellipse(balls[i].x, balls[i].y, 20,20);

}

}

Generating multiple objects

This little example generates multiple objects. It uses an array of vectors. Vectors contain both and x and y coordinate.