Published: January 24, 2017, Edited by: Mads Hobye

# Learn to program games in processing

This is a video guide we use to teach students to program in processing. Each video goes through step by step the different elements of programming. We use traditional arcade games as our platform to experiment with.

We further advise you to read through the guides on the processing site:

https://processing.org/tutorials/

Also, the processing reference is your friend:

https://processing.org/reference/

If you want to see examples of games students have made you can find them here:

http://fablab.ruc.dk/noob-to-master-programmer-in-10-days/

### Basic understanding of grid and interactivity

The following tutorials give you an overview of the basics understanding the grid and how to make interactivity:

https://processing.org/tutorials/drawing/

https://processing.org/tutorials/interactivity/

### General syntax

This is general syntax that we will go through in this tutorial:

``````   // ********************************************************
// ***    Basic syntac for Processing - cheat sheet     ***
// ***    By: FabLab RUC - Mads Hobye - V1              ***
// ********************************************************

// Global variables defined by the user

float aDecimal = 0.5f; // float creates a decimal (kommatal)
int anInteger = 100; // int creates an integer (heltal)
boolean aLogical = true; // boolean creates an a logical operater (only true or false)
ArrayList<Integer> anArrayOfInt = new ArrayList<Integer>();

myClass myObject;

// setup() runs once when you start the program.
// the curly braces defines the boundary of the setup() funciton
void setup()
{
println("This message is only presented once"); // "println" prints a line in the debug prompt

}

// draw() repeats endlessly.
void draw()
{
myObject = new myClass(); // Creates and object from the class below
int myLocalInt = 3; // This is a local variable only accessible within draw

println("This is the beginning of draw");

// An if statement - only runs if the variable "anInteger" is equal to 100
if (anInteger == 100)
{
println("The anInteger is 100");
}
else // only runs if "anInteger" is not equal to 100 then
{
println("Change anInteger to something else than 100 to run me");
}

//Everything within the curly braces are run 3 times
for (int i=0; i < 3; i = i +1)
{
println("This has been run " + (i+1) + " times");
}

// calls my function below
myFunction(anInteger);

// calls classFunction in myObject
myObject.classFunction();

println("This is the first item in the array: " + anArrayOfInt.get(0));

println("This is the end of draw - I will now start over");
} // when draw reaches the end it start over.

//This is a custom function called myFunction()
void myFunction(int _input)
{
println("This is my custom function");
println("You gave me the number:" + _input);
}

class myClass
{
int classVariable = 0; // local variable for myClass
void classFunction()
{
println("You called the subfunction for my class");
}
}
``````

### How to program pong

This video is a run-through of the basics of programming a simple pong game. It gives you a basic understanding of the principles behind programming and game design.

Pong example code

``````      float posX = 150;
float posY = 100;
float dirX = 1;
float dirY = 1;
float opponentY = 0;
int score = 0;

void setup()
{
size(300, 200);
}

void draw()
{
background(0);

// Y axis - ball
posY = posY +dirY;

if (posY > height)
{
dirY = -1;
}

if (posY < 0)
{
dirY = 1;
}

// X axis - ball
posX = posX +dirX;

if (posX > width)
{
dirX = -1;
}
if (posX < 0)
{

if (posY > mouseY && posY < mouseY + 60) // within the bat
{
println("bat hit");
dirX = 1;
score = score +1;
} else // above or below the bat
{
println("bat missed");
posX = width/2;
posY = height/2;
score = score -1;
}
}
//opponent

opponentY = opponentY * 0.99 + (posY-30)*0.01;

rect(width-10, opponentY, 10, 60);

// Bat

rect(0, mouseY, 10, 60);

fill(255);
ellipse(posX, posY, 20, 20);
text(score, 10, 20);
}
``````

### Scope, logical structures and state machines

When you have done your first little game it is relevant to dwell a little on some key concepts. By now you probably want to add a start screen. Further, you are probably struggling with getting the curly brackets right. This video runs through these concepts:

Bouncer example code

``````      // properties of the person who wants to enter the club
int age = 20;
boolean wellDressed = false;
boolean wearsJacket = true;

// day properties
boolean saturday = true;

void setup()
{
println("Welcome to the club");
if (age >= 18 && saturday == false || saturday == true && age >= 21)
{
if(wearsJacket == true)
{

}
if (wellDressed == true)
{
println("Great that you are so well dressed - you will get a drink");
}
} else
{
println("You are not old enough - please go away!");
}
}

void draw()
{
}
``````

State machine example code

``````int state = 0;

void setup() {
}

void draw() {

//println(state);

if (state == 0) {

state = 1;
} else if (state == 1) {

state = 2;
} else if (state == 2) {

state = 3;
}
}
``````

### For loops

When programming one has a tendency to write lots of redundant code. One way to solve this is to use for loops to repeat the same kind of code over and over again. In this example, we use the for loop to make a "fence" between the two players in the pong game.

For loop example

``````      for (int counter = 0; counter < height/30; counter = counter +1)
{
rect(width/2-5, 30*counter, 10, 20);
}
``````

### Classes and objects

Object-oriented programming is all about creating classes and make objects from them. This video converts the original pong game into an object oriented structure. This is especially relevant when you want to work with multiple game objects e.g. multiple balls, bullets, spaceships meteors etc.

``````int state = 0;

Ball theBall = new Ball();
Bat playerBat = new Bat();

float opponentY = 0;
int score = 0;

void setup()
{

size(400, 300);
textSize(30);
}

void draw()
{

if (state == 0) // welcome state
{
welcomeScreen();
} else if (state==1) // play the game state
{
gameScreen();
} else if (state == 2) // gameover state -win
{
winScreen();
} else if (state == 3) // gameover state -loose
{
looseScreen();
}
}

void welcomeScreen()
{
background(0, 255, 200);
text("Welcome to the amazing pong", width/2-100, height/2);
if (mousePressed)
{
state = 1;
}
}

void gameScreen()
{
background(0);

// draw the net
for (int counter = 0; counter < height/30; counter = counter +1)
{
rect(width/2-5, 30*counter, 10, 20);
}

// tjeck for collision between player one and the bat
if (theBall.y > playerBat.y && theBall.y < playerBat.y + 60 && theBall.x < playerBat.x) // within the bat
{
println("bat hit");
theBall.dirX = 1;
score = score +1;
if (score > 2)
{
state=2;
}
}

// the bat has been missed and the ball is outside on the left
if (theBall.x < 0)// above or below the bat
{
println("bat missed");
theBall.x = width/2;
theBall.y = height/2;
score = score -1;
if (score < -2)
{
state = 3;
}
}

// bat

playerBat.updateMe();
playerBat.drawMe();

// ball

theBall.updateMe();
theBall.drawMe();

//opponent
opponentY = opponentY * 0.99 + (theBall.y-30)*0.01;

rect(width-10, opponentY, 10, 60);
fill(255);

text(score, 10, 20);
}

void looseScreen()
{
background(255, 0, 0);
if (mousePressed)
{
state = 1;
score = 0;
}
}

void winScreen()
{
background(#FFCA08);
if (mousePressed)
{
state =1;
score = 0;
}
}

void keyPressed()
{
if (key=='s')
{
playerBat.dirY = 1;
}

if (key=='w')
{

playerBat.dirY = -1;
}

if (key=='a')
{
playerBat.dirX = -1;
}

if (key=='d')
{

playerBat.dirX = 1;
}
}

void keyReleased()
{
if (key=='s' || key == 'w')
{
playerBat.dirY = 0;
}

if (key=='a' || key == 'd')
{
playerBat.dirX= 0;
}
}

class Ball
{
float x = 150;
float y = 100;
float dirX = 1;
float dirY = 1;

void updateMe()
{

// Y axis - ball
theBall.y = theBall.y +theBall.dirY;

if (theBall.y > height)
{
theBall.dirY = -1;
}

if (theBall.y < 0)
{
theBall.dirY = 1;
}

// X axis - ball
theBall.x = theBall.x +theBall.dirX;

if (theBall.x > width)
{
theBall.dirX = -1;
}
}

void drawMe()
{

ellipse(theBall.x, theBall.y, 20, 20);
}
}

class Bat
{
float x = 0;
float y = 0;
float dirX = 0;
float dirY = 0;

void updateMe()
{
// Bat
playerBat.y = playerBat.y + playerBat.dirY;
playerBat.x = playerBat.x + playerBat.dirX;
}

void drawMe()
{
rect(playerBat.x, playerBat.y, 10, 60);
}
}
``````

### Asteroids game

Simple example of making a meteor:

`````` class Meteor
{
float x = 0;
float y = 0;
float size = 0;
float dirX = 0;
float dirY = 0;

void init()
{
x = random(0, 200);
y = random(0, 200);
dirX = random(-1,1);
dirY = random(0,2);
size = random(3,10);
}

void show()
{
x = x + dirX;
y = y + dirY;
if(x > width)
{
x = 0;
}
if(x < 0)
{
x = width;
}
if(y  > height)
{
y = 0;
}
if(y < 0)
{
y = height;
}

ellipse(x, y, size, size);
}
} // slut på meteor definition

ArrayList<Meteor> meteorList = new ArrayList<Meteor>();
float numMeteors = 100;

void setup()
{

noStroke();
size(200, 200);

for (int i = 0; i < numMeteors; i= i +1)
{

Meteor tmpMeteor = new Meteor();
tmpMeteor.init();
}

}

void draw()
{

background(0);
for (int i = 0; i < numMeteors; i = i +1)
{
meteorList.get(i).show();
}

}
``````

### Basic gravity

It is often needed to have some element with gravity. E.g. at ball falling to the ground. This video shows you have to make the ball fall and also bounce on the ground. Further, keyPressed is used to enable jumping and moving around.

Gravity code examples

``````        float posX = 0;
float posY = 0;
float speedX = 0;
float speedY = 0;

void setup()
{
rectMode(CENTER);
size(200,200);
}

void draw()
{
background(0);
rect(posX, posY, 20, 20);
posX = posX +speedX;
posY = posY +speedY;

// gravity - crude version
speedY = speedY +0.01;

//platform
rect(width/2,height/2,20,20);
if(posY > height/2-20 && posX > width/2-10 && posX < width/2+10)
{
speedY = 0;
}

}

void keyPressed()
{
if (key== 'd')
{
speedX = 1;
} else if (key== 'a')
{
speedX = -1;
}

if (key== 'w')
{
speedY = -1;
} else if (key== 's')
{
speedY = 1;
}
}

void keyReleased()
{
if (key=='d')
{
speedX = 0;
} else if (key=='a')
{
speedX = 0;
}

if (key=='w')
{
speedY = 0;
} else if (key=='s')
{
speedY = 0;
}
}
``````

### Complex collision detection, gravity and level creation

This video is a run-through of making the basic of e.g. a Super Mario level.

``````class Block
{
float x =0;
float y = 0;
float w = 0;
float h = 0;

void show()
{
rect(x, y, w, h);
}
}

Player thePlayer = new Player();

ArrayList<Block> blocks = new ArrayList<Block>();

int numBlocks = 20;

void setup()
{
size(500, 500);

for (int counter = 0; counter < numBlocks; counter = counter +1)
{
Block tmpBlock = new Block();
tmpBlock.x = counter * 50+random(30);
tmpBlock.w = 50;
tmpBlock.y = height - random(0, 100);
tmpBlock.h = 100;

}
}

void draw()
{
background(0);
translate(thePlayer.x*-1+100, thePlayer.y *-1+100);
thePlayer.move();
thePlayer.show();

for (int counter = 0; counter < numBlocks; counter = counter +1)
{
Block selectedBlock = blocks.get(counter);
selectedBlock.show();
//ellipse(selectedBlock.x,selectedBlock.y,20,20);
thePlayer.collision(selectedBlock.x,selectedBlock.y,selectedBlock.w);
}
}

void keyPressed()
{
if (key == 'w')
{
thePlayer.jump();
}

if ( key=='a')
{
thePlayer.speedX = -1;
}

if (key == 'd')
{
thePlayer.speedX = 1;
}
}

void keyReleased()
{
if (key=='d' || key=='a')
{
thePlayer.speedX = 0;
}
}

class Player
{
float x =100;
float y = 100;
float speedY = 0;
float speedX = 0;
float size = 20;
boolean jumpOk = false;

void jump()
{
if (jumpOk == true)
{
speedY = -10;
jumpOk = false;
}
}

void move()
{
x = x + speedX;
y = y + speedY;
speedY = speedY + 0.3f;
}

void collision(float xCol, float yCol, float wCol)
{

if (y > yCol  && x >= xCol && x <= xCol + wCol )
{
println("we have collision");
y = constrain(y, 0, yCol);
speedY = speedY * -0.3 ;
jumpOk = true;
}
}

void show()
{
ellipse(x, y, size, size);
}
}
``````

### Programming patterns

If you want a more general understanding of programming patterns and some of the common challenges I suggest that you look here:

http://fablab.ruc.dk/basic-programming-patterns/

### Other code examples

#### Rotation

``````float speedX = 1;
float speedY = 1;

void setup()
{
size(500, 500);
background(0);
}

void draw()
{

float angle = (float)Math.toDegrees(Math.atan2(speedY, speedX));
pushMatrix();
translate(200, 200);
rect(0, 0, 100, 20);
popMatrix();
}
``````

#### KeyPressed

``````float batY = 0;
float batDirY = 0;
float batX = 0;
float batDirX = 0;

void setup()
{
size(400, 300);
background(0);
}

void draw()
{

rect(batX, batY, 10, 30);
batY = batY + batDirY;
batX = batX + batDirX;
}

void keyPressed()
{
if (key=='s')
{
batDirY = 1;
}

if (key=='w')
{

batDirY = -1;
}

if (key=='a')
{
batDirX = -1;
}

if (key=='d')
{

batDirX = 1;
}
}

void keyReleased()
{
if (key=='s' || key == 'w')
{
batDirY = 0;
}

if (key=='a' || key == 'd')
{
batDirX= 0;
}
}
``````

#### Chasing an object

``````float posX = 0;
float svampeX = 0;
float speedX = 0;

void setup()
{
size(500,500);
}

void draw()
{
background(0);
svampeX = mouseX;
ellipse(posX,200,20,20);
if(svampeX > posX)
{
speedX = 1;
}
else
{
speedX = -1;
}
posX = posX + speedX;
rect(svampeX,200,20,20);
}
``````

#### Explosion

``````float fireX = 0;
float fireY = 0;
float fireSize = -1;
float fireSpeed = 0;

void setup()
{

size(500, 500);
}

void draw()
{
background(0);
if (mousePressed)
{
fireX = mouseX;
fireY = mouseY;
fireSize = 0;
fireSpeed = 1;
}
if (fireSize >= 0)
{
colorMode(HSB);
fill(random(70), 100, 100);
ellipse(fireX, fireY, fireSize, fireSize);
colorMode(RGB);

fireSize = fireSize +fireSpeed;
}

if (fireSize > 100 && fireSize > -1)
{
fireSpeed = -1;
}

if(fireSize >= 0 && dist(mouseX,mouseY,fireX,fireY)< fireSize)
{
fill(255,0,0);
}
else
{
fill(255);
}
ellipse(mouseX,mouseY,20,20);

}
``````

### Chasing the mouse

`````` float botX = 100;
float botY = 100;

void setup()
{
size(200, 200);
}

void draw()
{
background(0);

if(botX > mouseX)
{
botX = botX -1;
}

if(botX < mouseX)
{
botX = botX +1;
}

if(botY > mouseY)
{
botY = botY -1;
}

if(botY < mouseY)
{
botY = botY +1;
}
//  botY = mouseY;
ellipse(botX, botY, 20, 20);
}
``````

### Fluid chase

More fluid chase.

`````` float x =0;
float y = 0;
float dirX = 0;
float dirY=0;
float speed = 3;

void setup()
{

size(600, 600);
}

void draw()
{
background(0);
ellipse(mouseX, mouseY, 20, 20);
ellipse(x, y, 10, 10);
// x = x * 0.90 + mouseX*0.1;
// y = y * 0.90 + mouseY*0.1;
x = x + dirX;
y = y + dirY;

float angle = (float)Math.toDegrees(Math.atan2(y-mouseY, x-mouseX));
}
``````

### Play audio file

`````` import ddf.minim.*;

Minim minim;
AudioSample kick;

void setup()
{

minim = new Minim(this);

kick = minim.loadSample( "BD.mp3", // filename
512      // buffer size
);
if ( kick == null ) println("Didn't get kick!");
kick.setGain(-40); // from -13 to -80
}

void draw()
{
}

void keyPressed()
{

if ( key == 'k' ) kick.trigger();
}
``````

### Use images

`````` PImage img;
void setup() {
size(640, 360);
// The image file must be in the data folder of the current sketch
}

void draw() {
// background image
image(img, 0, 0,width,height);

// follow the mouse with a 50 width and height
image(img, mouseX, mouseY,50,50);

}
``````

### Timing an event

`````` long timer = 0;
void setup()
{

}

void draw()
{
if(millis()-timer > 2000) // do something every two seconds)
{
timer = millis();
//do something here
}
}
``````