Category: Tutorials

Centering and zooming the canvas

P5 sketches run inside an html element called canvas which is created with create canvas. Centering within a page requires some css magic.

In the index.html style tag, replace the existing canvas item with

    canvas {
      vertical-align: middle;
      margin: auto;

      /* remove these if you DON'T want sharp pixel edges*/
      image-rendering: -moz-crisp-edges;
      image-rendering: -webkit-crisp-edges;
      image-rendering: pixelated;

      padding: 0;
      display: block;
      position: absolute;
      margin:auto;
      left: 0;
      right: 0;
      /* remove these two if you don't want vertical alignment */
      top:0;
      bottom: 0;

    }

The canvas can also be accessed and manipulated within the sketch.
This is how you can scale it by multiples of the native size.
Don’t forget to add the image-rendering settings below to the css if you want non antialiased (crisp) pixel for a pixelart project.

 function setup() {
      var canvas = createCanvas(64, 64);
      var pixelScale = 4;

      noSmooth();
      canvas.style("width", width*pixelScale+"px");
      canvas.style("height", height*pixelScale+"px");

    }
Comments Off on Centering and zooming the canvas Posted in

P5.play animations and animated sprites

First, download and copy this empty project which includes all the images.

Animations

Animations are like images, you preload images and you display them in a certain place. The library takes care of storing and advancing the frames.

Creating animations from single images:

//animations like p5 images should be stored in variables
//in order to be displayed during the draw cycle
var ghost, asterisk;

//it's advisable (but not necessary) to load the images in the preload function
//of your sketch otherwise they may appear with a little delay
function preload() {

//create an animation from a sequence of numbered images
//pass the first and the last file name and it will try to find the ones in between
ghost = loadAnimation("assets/ghost_standing0001.png", "assets/ghost_standing0007.png");

//create an animation listing all the images files
asterisk = loadAnimation("assets/asterisk.png", "assets/triangle.png", "assets/square.png", "assets/cloud.png", "assets/star.png", "assets/mess.png", "assets/monster.png");
}

function setup() {
  createCanvas(800,300);
}

function draw() {
  background(255,255,255);  

  //specify the animation instance and its x,y position
  //animation() will update the animation frame as well
  animation(ghost, 300, 150);
  animation(asterisk, 500, 150);
}

Creating animations from a sprite sheet requires two steps:

1. loading and processing the sprite sheet
sprite_sheet = loadSpriteSheet(filename, frame width, frame height, number of frames);

2. loading the animation

explode_animation = loadAnimation(sprite_sheet);

Try to load an animation you made in piskel, you just have to change the parameters in loadSpriteSheet.

var sprite_sheet_image;
var sprite_sheet;
var explode_animation;

function preload() {
  // specify width and height of each frame and number of frames
  sprite_sheet = loadSpriteSheet('assets/explode_sprite_sheet.png', 171, 158, 11);
  explode_animation = loadAnimation(sprite_sheet);

  // load the full sprite sheet for example reference only
  sprite_sheet_image = loadImage('assets/explode_sprite_sheet.png');
}

function setup() {
  createCanvas(800, 225);
}

function draw() {
  background(255);

  // animate the sprite sheet
  animation(explode_animation, 100, 130);

  // show full sheet for example reference
  image(sprite_sheet_image, 250, 40, 500, 154);
}

Sprites

p5 play facilitates the creation of objects called sprites. Sprites are visual entities existing in a 2d space. They have coordinates, they can be assigned an appearance (images and animations) and specific functions for physics, collision or interaction.

A sprite is created once and it doesn’t need to be drawn every time.
The function drawSprites(); usually called at the end of the draw cycle will take care of all the visualization.

var boxSprite;

function setup() {
  createCanvas(800,600);
  //create a sprite with a placeholder rectangle as visual component
  boxSprite = createSprite(100, 150, 50, 100);
}

function draw() {
  background(240);

  //draw all the sprites
  drawSprites();
}

Here is how to create an animated sprite and some functions to control the animation
Don’t forget to check the examples and the reference

//Changing the sprites' animations
var character;
var spriteSheet;

//preload the spritesheets
function preload() {

  //load from spritesheet
  spriteSheet = loadSpriteSheet('assets/explode_sprite_sheet.png', 171, 158, 11);

}

function setup() {
  createCanvas(800,300);

  //create a sprite and add the 3 animations
  character = createSprite(400, 150, 50, 100);

  //label, first frame, last frame
  //the addAnimation method returns the added animation
  //that can be store in a temporary variable to change parameters
  character.addAnimation("floating", "assets/ghost_standing0001.png", "assets/ghost_standing0007.png");

  character.addAnimation("moving", "assets/ghost_walk0001.png", "assets/ghost_walk0004.png");

  character.addAnimation("spinning", "assets/ghost_spin0001.png", "assets/ghost_spin0003.png");

  var explodeAnimation = loadAnimation(spriteSheet);

  character.addAnimation('explode', explodeAnimation);

}

function draw() {
  background(255,255,255);  

  //keyDown returns true for a cycle if the key was just pressed
  //during this cycle. Useful to capture instant events in the draw cycle
  //without moving game logic to the mousePressed() function
  //mouseWentDown works the same way with mouse input
  if(keyWentDown("a") )
    {
    character.changeAnimation("moving");
    }

  if(keyWentDown("s") )
    {
    character.changeAnimation("spinning");
    }

  if(keyWentUp("s") )
    {
    character.changeAnimation("floating");
    }

  if(keyWentDown("d") )
    {
    character.animation.stop();
    }

  if(keyWentUp("d") )
    {
    character.animation.play();
    }

  if(keyWentDown(LEFT_ARROW))
    {
    character.animation.previousFrame();
    }

  if(keyWentDown(RIGHT_ARROW))
    {
    character.animation.nextFrame();
    }

  if(keyWentUp("f") )
  {
  character.changeAnimation("explode");
  character.animation.rewind();
  }

  //changing an animation when another one is done
  if(character.getAnimationLabel () == "explode" && character.animation.getFrame()==character.animation.getLastFrame())
    {
    character.changeAnimation("floating");
    }

  //draw the sprite
  drawSprites();
}

Comments Off on P5.play animations and animated sprites Posted in

Using p5 add-ons / p5.play

p5play

P5.js has many add-on libraries for specific functions.
We are going to use one I made called p5.play that helps with graphical, playful, applications and games.

p5.play provides a Sprite class to manage visual objects in 2D space and features such as animation support, basic collision detection and resolution, sprite grouping, helpers for mouse and keyboard interactions, and a virtual camera.

How to install p5.play

1. Create a new p5 project and save it. Open the project folder (menu view > show sketch folder).

2. Download the library p5.play.js. File save as…

3. Save or copy p5.play.js in the library folder of your project

screen-shot-2016-11-07-at-10-26-53-am

4. Open the index.html of your project from the p5 editor and add this line before the sketch.js inclusion

<script src="libraries/p5.play.js" type="text/javascript"></script>

screen-shot-2016-11-07-at-10-27-43-am

5. Run this sketch to test if it works.

var boxSprite;

function setup() {
  createCanvas(800,600);

  //create a sprite with a placeholder rectangle as visual component
  boxSprite = createSprite(100, 150, 50, 100);
}

function draw() {
  background(240);
  //draw all the sprites
  drawSprites();
}

If you get an error related to “print” it’s a temporary version disalignment issue, download and replace p5.js in your project.

Alternatively just download this empty project and use it whenever you start a new project, it includes the assets in the examples.

Comments Off on Using p5 add-ons / p5.play Posted in

Pixel art & Character design

For the virtual pet assignment we’ll start from the design and animation of a character in 32×32 pixels.
Pixel art is not just drawing in low resolution or in the style of 80s videogames, it has his own processes and techniques. Let’s see some non-retro examples:

simpsonpixelart

Applications

160625_piskel
http://www.piskelapp.com

screen-shot-2016-11-02-at-9-55-10-am
http://www.pixelfor.me/crc/F0000032

Resources/inspirations

Curated graphics

PixelJoing sharing community

Pinterest curated list

Way of the pixel message board for in-depth feedback

Character design

Abstraction

Realistic, Iconic or Abstract?

Cuteness

Cute characterization seems to appeal to people across generations and cultures

Kawaii

The expectations that come along with cuteness can be subverted
People like to look at cute things, but your expressive goals may be different.
The original characters in Unmanned were a bit cuter

Distinctive features

Some of the best character design in contemporary games is iconic. Originally Mario’s distinctive big nose and mustache was a low-res necessity.

This is crucial for all characters in animation and games, if your character can be effectively rendered in a few pixel, that's a good design.
This is crucial for all characters in animation and games, if your character can be effectively recognized in a few pixel, that’s a good design.

In short animations, characters may have specific built-in affordances. They are designed to perform certain actions:

This happens more frequently in videogames, where characters are defined by what they can do and the actions they perform are limited.

Stereotypes
When designing cartoonish, memorable characters it’s easy to recur to stereotypes and cultural markers.
Game designers often need to communicate threats, goals and roles without going through narrative character establishments. To do so they often recur to problematic strategies such as stereotypes and stock characters: zombies, princesses in distress etc..
Let’s be thoughtful about that.

Modern day Native American wearing feathers… Magic-Yoga-practicing, skull-wearing Indian… traditional-but-sexyfied chinese dress… evil Russian brute…
Princess Peach fights enemies by using her mood swings

Ms. Male Character

Pixel Art

pixel_art_tutorial___basics_by_kiwinuptuo-d38pbk5

pixel_art_colors

Animation

These principles can be applied to pixel art as well

chun-slight-speed-down-copy

Animation Smears
smears

Don’t reinvent the wheel
walking-loop
See how successful animations are made and literally copy them.
Walking loop tutorial

Don’t animate in full detail frame by frame!
animation

Comments Off on Pixel art & Character design Posted in

Strings, text and font

When we want to print messages with println we use text in “quotes”.
Technically we are passing a string as parameter. You can handle text as variable as long as you declare the proper type.

Declaration and assignment:

var name = "paolo";

Also strings:

var text1 = "666";
var text2 = "two words";
var text3 = "text on \nTwo lines";
var text4 = " "; //space
var text1 = "6$%#@# AaBb()";

Concatenation:

var name = "paolo";
var lastName = "pedercini";
var nickName = "pizza";
var fullName = name + " \"" + nickName + "\" " + lastName;

function setup() {
  createCanvas(300, 300);
  background(0);
  fill(255);

  text(name + " " + lastName, 15, 30);

  text(fullName, 15, 60);
}

function draw() {

}

Formatting Text

You can change text color, it’s the same as the fill, and alignment.

function setup() {
  createCanvas(300, 300);
  background(0);

  fill(255,255,255);

  //alignment
  textAlign(CENTER);
  text("This text is centered.", width / 2, 60);
  textAlign(LEFT);
  text("This text is left aligned.", width / 2, 100);

  //change fill + alpha
  fill(255,255,255, 100);

  textAlign(RIGHT);
  text("This text is right aligned.", width / 2, 140);
}

function draw() {

}

Fonts

Download a font an try to load it. Make a simple clock.
For free fonts check dafont and google fonts.

var myFont;
function preload() {
  myFont = loadFont('assets/custom-font.ttf');
}

function setup() {
  fill('#ED225D');
  textFont(myFont);
  textSize(36);
  text('p5*js', 10, 50);
}

Comments Off on Strings, text and font Posted in

Timed events

This is how to use time functions (you also have day(), month(), year()).
They read your operating system’s clock.
This sketch prints 3 bars proportional to seconds minutes and hours.

function setup() {
  createCanvas(250, 250);
}

function draw() {
  background(0);

  //update variables with time and date
  s = second();
  m = minute();
  h = hour();

  //change fill
  fill(255, 0, 0);
  //map the lenght of my bar according to my seconds
  var sWidth = map(s, 0, 60, 0, 200);
  //draw a rectangle
  rect(0, 0, sWidth, 50);

  //do the same for minutes and hours
  fill(0, 255, 0);
  var mWidth = map(m, 0, 60, 0, 200);
  rect(0,100, mWidth, 50);

  fill(0, 0, 255);
  var hWidth = map(h, 0, 23, 0, 200);
  rect(0,200, hWidth, 50);

}

How to make something happen every second

var s;
var lastSecond;

function setup()
{
  createCanvas(200, 200);
}

//this function is called 60 times per second
function draw()
{
  s = second();

  //if the second was updated then do something once
  if (s != lastSecond)
  {
    println("A second elapsed");
    background(random(255), random(255), random(255));
    //update the last second
    lastSecond = s;
    //this variables will be the same until
    //the next second change in the clock
  }
}

millis: how to make something happen between seconds

Common problem: second() is related to the system clock but millis() count starts as you run the applet. Sometimes you need them to be in sync, for example if you want an analog clock with a second arm moving smoothly:

//the function millis() returns the time elapsed since
//the launch of the sketch in milliseconds

//millisRolloverTime is the time elapsed since
//the last time a second changed in milliseconds
var millisRolloverTime;
var prevSec;

function setup()
{
  createCanvas(600, 600);
  millisRolloverTime = 0;
}

function draw()
{
  background(0);
  fill(255);

  //second just changed
  if (prevSec != second () ) {
    //save the current time
    millisRolloverTime = millis();
  }

  //update the value of seconds
  prevSec = second();

  //the current second milliseconds is the current time (in ms)
  //MINUS the last time (in ms) a second changed.
  //I round it because I don't need tiny fractions of milliseconds
  var milliseconds = round(millis() - millisRolloverTime);

  //write it
  text(second() + " " + milliseconds, 10, 20);

  //draw a bar based on it
  var bar = map(milliseconds, 0, 999, 0, width);
  rect(0, 50, bar, 30);
}
Comments Off on Timed events Posted in

Using sound files: play, loop, spectrum analysis

Keyboard example, with different ways to play sound samples: download

Real time spectrum analysis via Fast Fourier transform download

Adding cues to the sound that trigger a function at a certain points in the reproduction download

Sounds work almost like images. To make this example work download an mp3 file and put it in an assets folder inside your project. You can go to freesound or download mp3 from youtube.

var mySound;

function preload() {
  mySound = loadSound('assets/mySound.mp3');
}

function setup() {
  mySound.setVolume(0.1);
  mySound.play();
//also try looping
//mySound.loop();
}

function draw() {
if(mySound.isPlaying())
println("PLAYING");
}

//sound mode
function mouseClicked() {
  mySound.playMode('sustain');
  mySound.play();
}

function keyPressed() {
  mySound.playMode('restart');
  mySound.play();
}

Comments Off on Using sound files: play, loop, spectrum analysis Posted in

Using image files in p5

You can load image and audio files in p5.

The files are loaded by the sketch so don’t forget to copy them wherever you want to use your filed.

Find an image and put it in the a folder called “assets” inside your project folder

Loading an image can take some times so it’s good practice to load the image inside a function called preload:

//1- Declare variable for your image
var img; 

//2- Preload the image (replace the name and path with your own)
// preload() runs once before setup
function preload() {
  img = loadImage("assets/imageName.png");
}

function setup() {
  createCanvas(720, 400);
}

function draw() {
  //3- Displays the image at its actual size at point (0,0)
  image(img, 0, 0);

  //You can also resize the image
  // Displays the image at point (0, height/2) at half size
  //image(img, 0, height/2, img.width/2, img.height/2);
}

It works with alpha too!
(How to add an alpha channel in photoshop)

Create a scene with a background and an object following the mouse.

Filters
Try to call the function tint before displaying the image:

image(img, 0, 0);
tint(0, 153, 204);  // Tint blue r,g,b,a (add one parameter for alpha)
image(img, 50, 0);

You can also use tint to change only the transparency

image(img, 0, 0);
tint(255, 126);
image(img, 50, 0);

Try some other effects using the filter and blend functions

Transformations
Transformations can be applied to images as well:

//change to center to facilitate rotation
imageMode(CENTER);

  push();
    translate(150, 150);
    rotate(radians(45));
    image(img, 0, 0, 200, 200);
  pop();

Comments Off on Using image files in p5 Posted in

Rotational symmetry – sin cos

Here’s how to use basic trigonometry to position things in a circle:

var numObjects = 10;
var centerX;
var centerY;
var angle = 0;
var distance = 100;

function setup() {
createCanvas(600, 600);
centerX = width/2;
centerY = height/2;

noStroke();
ellipseMode(CENTER);
}

function draw() {
background(0);

//divide the circle 360 degrees according to the number of objects
var angleObject = 360/numObjects;

for (var i=0;i<numObjects ;i++)
{
//you can have a circular motion if you sum the same angle to all objects
//angle = frameCount;
//and the speed can be also linked to the object number
//angle = frameCount*i / 2;

//fun with trigonometry and oscillations
//distance = sin(radians(frameCount))*150;

//the sin(angle) cos(angle) has to be
//multiplied by the distance from the center
//because trigonometric functions assume a circle with radius=1
//centerX and centerY is the offset from the top left corner
//remember to convert in radians
var posX = centerX + distance *cos( radians(angleObject*i + angle) );
var posY = centerY + distance *sin( radians(angleObject*i + angle) );

fill(255);
ellipse(posX, posY, 10, 10);
}
}

Doing more or less the same without trigonometry and with push/pop transformations


var numObjects = 10;
var centerX;
var centerY;
var angle = 0;
var distance = 100;

function setup() {
createCanvas(600, 600);
centerX = width / 2;
centerY = height / 2;

noStroke();
ellipseMode(CENTER);
}

function draw() {
background(0);
angle++;

var angleObject = 360 / numObjects;
for (var i = 0; i < numObjects; i++) {

push();
translate(centerX, centerY);
rotate(radians(i * angleObject + angle));
//or you can draw at 0,0 and translate again
//translate(distance,0);
ellipse(distance, 0, 10, 10);
pop();
}
}

Make an animated mandala/hypno-disc composition using the rotational symmetry algorithms below.

*You have to use at least two .png images with transparency loaded from an external file.
*You can mix bitmap and processing-generated images.
Bonus: use nested for-loops to give the illusion of a 3D tunnel.

Comments Off on Rotational symmetry – sin cos Posted in

Transformation Matrix (rotate, translate, scale)

Try this

translate(30, 20);
rect(0, 0, 55, 55);
translate(14, 14);
rect(0, 0, 55, 55);

What happened?

And this:

translate(width/2, height/2);
rotate(radians(45));
rect(-25, -25, 50, 50);

Example of transformation + scale + rotation.
More info here.

function setup()
{
createCanvas(200, 200);
background(255);
noStroke();
rectMode(CENTER);

// draw the original position in gray
fill(192);
rect(0, 0, 40, 40);

// draw a translucent blue rectangle in the new position
fill(0, 0, 255, 128);

push();
translate(100, 100);
rotate(radians(45));
scale(0.5);
rect(0, 0, 40, 40);
pop();
}

For loop + rotation.
1. push
2. translate first to the pivot, the center of rotation
3. rotate (don’t forget to convert in radians)
4. draw as if the origin (the center of your composition) was 0, 0
5. pop

var rows = 10;
var cols = 12;
var distanceX = 30;
var distanceY = 30;

function setup() {
createCanvas(400, 400);
background(0);
//stroke(18, 255, 233);
noStroke();
for (var r = 1; r <= rows; r++) { for (var c = 1; c <= cols; c++) { push(); translate(c * distanceX, r * distanceY); rotate( radians(45) ); fill(r*25, c*25, 0); rect(0, 0, 20, 20); pop(); } } }

Now try to reproduce the plotter drawing below (or your take on it). (Georg Nees Schotter, 1968)

Comments Off on Transformation Matrix (rotate, translate, scale) Posted in

If statements

Starting from this simple sketch:


var rows = 9;
var cols = 9;
var circleDiameter = 40;
var distanceX = 60;
var distanceY = 60;

function setup()
{
createCanvas(600,600);
noStroke();
}

function draw()
{
background(0);

for (var r = 1; r<= rows; r++) {
for (var c = 1; c <= cols; c++) {

if( r>5 )
{
fill(200, 0, 0);
}
else
{
fill(0, 200, 0);
}

ellipse(c*distanceX, r*distanceY, circleDiameter, circleDiameter);
}
}

}

 
Reproduce the following outputs by changing only the if condition:

Screen Shot 2015-10-21 at 6.10.55 PM

Screen Shot 2015-10-21 at 6.11.44 PM

Screen Shot 2015-10-21 at 6.13.13 PM

Screen Shot 2015-10-21 at 6.13.41 PM

Screen Shot 2015-10-21 at 6.14.02 PM

Screen Shot 2015-10-21 at 6.15.41 PM

Comments Off on If statements Posted in

Iteration (for loops)


Draw a vertical line. Now draw two parallel, now three…

Introducing for loops:

for (var i=1; i<=10; i++)
{
println(i);
}

This draws 10 horizontal lines:

for (var i=1; i<=10; i++)
{
line (10, i*10, width, i*10);
}

Change the color gradually using the counter i!
Generalize the formula using variables for the distance and the number of lines!

There can be multiple instructions in the same loop:

for (var i=0; i<50; i++)
{
line (0, i*10, width, i*10);
ellipse(10*i, i*10, 10, 10);
}

Make a more complex pattern using at least 3 for loops or multiple instructions in the same loop!

You can add randomness to the order:

for (var i=0;  i<50; i++)
{
line (0, i*10, width, i*10);
float posX = random(0, width);
ellipse(posX, i*10, 10, 10);
}

Create a composition with 12 randomly generated shapes, using iteration!

Embedded iteration

What if you have to iterate on two dimensions?
This is an example using indexes as number of rows and columns.

In this way you have better control over the number of shapes that are being drawn.

var rows = 8;
var cols = 12;
var circleDiameter = 40;
var distanceX = 30;
var distanceY = 30;

function setup()
{
createCanvas(400,300);
background(0);
stroke(18, 255, 233);

for (var r = 1; r<= rows; r++) {
for (var c = 1; c <= cols; c++) {
ellipse(c*distanceX, r*distanceY, circleDiameter, circleDiameter);
}
}
}

You can control other parameters too:

var box_size = 11;
var box_space = 12;
var margin = 7;

function setup()
{
createCanvas(200, 200);
background(0);
noStroke();

// Draw gray boxes

for (var i = margin; i<height-margin; i += box_space){
if(box_size &gt; 0){
for(var j = margin; j<width-margin; j+= box_space){
fill(255-box_size*10);
rect(j, i, box_size, box_size);
}
box_size = box_size - 0.6;
}
}

<h1>While loop</h1>
Sometimes you don’t know in advance how many times you want to iterate and/or you don’t need an loop counter (variable i). In these cases while loops can be handy. Make sure you exit condition is met at some point:

function setup()
{
createCanvas(200,200);
background(255);
noStroke();

var w = width;

while (w > 0) {
fill(w);
ellipse(width/2,height/2,w,w);
w = w - 20;
}
Comments Off on Iteration (for loops) Posted in

Variables

A variable is a memory location with an associated symbolic name, which contains some kind of value.

A third feature of variables is their type which defines the kind of data they contain: integer number, floating point number, string, object etc.

Javascript is a weakly typed language, meaning it doesn’t require you to specify a type and it won’t generally give you an error if you use a variable of the wrong type (although the results may be incorrect).

Let’s have some fun with variables:

//declaration
var myDiameter = 10;

function setup()
{
  createCanvas(500, 500);
  noStroke();
}

function draw()
{
  background( 0, 0, 0);
  ellipse(250, 250, myDiameter, myDiameter);
}

I use a var for the radius so I don’t have to type the number every time i want to adjust it.

Since it’s a variable it can be changed:

myDiameter = myDiameter+1;

or

myDiameter++;

What if I want the resizing to be slower?

What if I wanted to stop at a 100?

What about the other parameters of the ellipse?
Try to use variables there too!

Give them meaningful names.

Now use that variable to make the circle move from the left to the right!

wrap around the screen! (if)
go back and forth!

Print function
Often variables don’t have a visual representation but you may want to check their content for debugging and testing purposes. print() is the p5.js function to use:

print(myVariable);

print(myVariable+1);
//+-*/%

//this is actually a string concatenation, we'll get into strings later
print("My variable is "+myVariable+1);

The output will be visible only in the browser console and in the p5.js editor, and it’s not meant to be seen by the user.

Scoping

Some “temporary” variables can be declared inside functions and blocks. Note: these variables won’t be “visible” outside that block (scoping).

function draw()
{
  background( 0, 0, 0);

  var dx = mouseX - posX;
  var dy = mouseY - posY;

  posX += dx/10;
  posY += dy/10;

  ellipse(posX, posY, myDiameter, myDiameter);
}

Let’s analyze this.

How can we make the circle faster?

How can you make the circle follow the mouse pointer only when the mouse button is down?

Comments Off on Variables Posted in

Random and Noise

Let’s add a little bit of uncertainty:

function setup() {
  createCanvas(500, 500);
  frameRate(10);
}

function draw() {
  background(random(255), random(255), random(255));
}

What about creating ellipses in random positions?

Make them appear only in a central square of 300×300! Random can accept a minimum and a maximum value.

random(0, 100);

Add a random fill!

Try to restrict the color range!

Random can be used for triggering events every once in a while:


 var bingo = round(random(1,60));
 print(bingo);

  if(bingo == 2)
  {
 	//do something...
  }

Random positioning vs random walk:


function setup() {
  createCanvas (300, 300);
}

function draw() {
  background(200);

  var rx;
  var ry;
  rx = width/2;
  ry = height/2;

  rx = rx + random(-10, 10);
  ry = ry + random(-10, 10);
  ellipse(rx, ry, 40, 40);
}
var rx;
var ry; 

function setup() {
  createCanvas (300, 300);
  rx = width/2;
  ry = height/2;
}

function draw() {
  background(200);
  rx = rx + random(-10, 10);
  ry = ry + random(-10, 10);
  ellipse(rx, ry, 40, 40);
}

Noise

Perlin noise is an infinite random sequence of values changing harmonically. It is the basis of a lot of special effects and procedural computer graphics and it’s much more interesting than random.

The sequence will appear “natural” if you take contiguous samples (xoff).

var xoff = 0.0;

function draw() {
  background(204);
  xoff = xoff + .01;
  var n = noise(xoff) * width;
  line(n, 0, n, height);
}

Noise example with variable xoff

Comments Off on Random and Noise Posted in

p5 Dynamic Mode + mouse input

Let’s make our first interactive sketch

function setup() {
createCanvas(500, 500);
}

function draw() {
background(255, 255, 255);
line(250, 250, mouseX, mouseY);
}

What if we move the background line in the setup function?

function setup() {
createCanvas(500, 500);
background(255, 255, 255);
}

function draw() {
line(250, 250, mouseX, mouseY);
}

Before, the background was filled every frame, which is very fast 60 fps.
With this layering it works like a creative tool.

Change the rectangle with an ellipse (they happen have the same number of parameters)

function draw() {
line(mouseX, mouseY, pmouseX, pmouseY);
}

pmouseX, pmouseY is the last mouse position, they are useful system variables.

Make a circle that follows the mouse!

Try to switch the mouse:

ellipse(mouseY, mouseX, 50, 50);

And try this:

background(255, 255, 255);
ellipse(mouseX, height-mouseY, 50, 50);

height and width are constant representing the size of the canvas.
The expression width-mouseY will be resolved before the ellipse gets drawn.

Draw an ellipse that mirrors the mouse position on both axis!

You can draw more than one object on each draw iteration:

background(255, 255, 255);
ellipse(mouseX, mouseY, 50, 50);
ellipse(width-mouseX, height-mouseY, 50, 50);

A less predictable behavior:
background(255, 255, 255);
ellipse(mouseX, mouseY, 50, 50);
ellipse(width-mouseY, mouseX, 50, 50);

You can create all sorts of complex relationships starting from the mouse coordinate

ellipse(mouseX, height-mouseY, 50, 50);
ellipse(mouseX/2, height-mouseY/2, 50, 50);

Make a complex set of relationships between 5 or more shapes!
(redraw the background at every refresh)

P5 provides two ways to detect the mouse clicks, as an event and as a state variables:


function setup() {
createCanvas(500, 500);
}

function draw() {
background(237, 34, 93);

fill(0);

if (mouseIsPressed)
    ellipse(250, 250, 100, 100);
else
    rect(250, 250, 100, 100);
}

//this function is called every time you press a mouse button
function mousePressed() {
println("mouse has been clicked");
}

//this function is called every time you release a mouse button
function mouseReleased() {
println("mouse has been released");
}

Now we can make a simple drawing application that draw a line only if the mouse is down.

Here’s a simple trick using distance. I save the distance between the previous coordinates in a variable – that’s the speed…

  var d = dist(mouseX, mouseY, pmouseX, pmouseY);

  //...and I use it to change the thickness of the line
  strokeWeight(d/6);

  line(mouseX, mouseY, pmouseX, pmouseY);
  

Try to paint different colors based on the mouse position or speed.

This is a bit more advanced but quite intuitive. Variables connected to sliders.

//declare the slider object as global variable
//so it can be accessed from all functions
var colorSlider;

function setup() {
  createCanvas(800, 600);
  background("#b5ffaf");

  //create slider - goes from 0 to 255, starts at 100
  colorSlider = createSlider(0, 255, 100);
  //position
  colorSlider.position(20, 20);

  //change color mode to Hue Saturation and brightness
  colorMode(HSB);
}

function draw() {
  //get the hue from the slider
  var h = colorSlider.value();

  //change the hue
  stroke(h, 255, 255);

  //draw line only if mouse is pressed
  if(mouseIsPressed)
    line(mouseX, mouseY, pmouseX, pmouseY);
}

Check the reference for more mouse related functions
mouseMoved()
mouseDragged()
mousePressed()
mouseReleased()
mouseClicked()
mouseWheel()

Comments Off on p5 Dynamic Mode + mouse input Posted in

Drawing in P5

Let there be line!

function setup() {
  line(10, 10, 40, 60);
}

Run, commands, syntax, parameters / arguments, typography, non alphanumeric characters, parenthesis vs. brackets, semicolon, coordinates…

 

Canvas

createCanvas(800, 600);
background (255, 255, 255);

 

How do colors work?

2D Primitives

point(300, 300);
triangle(10, 20, 50, 200, 200, 100);

Make it isosceles!
Make it rectangle!

Quadrilateral

quad(10, 10, 120, 20, 100, 150, 10, 100);

Make a square!
Make a butterfly!

Rectangle

rect(100, 100, 200, 100);

Make a square!
Center it!

Ellipse

ellipse(300, 200, 300, 200);

How does it work? Check the Processing reference manual
Inscribe the circle in the canvas!

Comments

//why comments
/*
Because they make you code readable.
(O_o)
*/

 

Attributes

strokeWeight(4);

Camelback convention. keepItInMind.
Processing is case sensitive strokeWeight and strokeweight are not the same.

Pen state

createCanvas(500, 500);
background (255, 255, 255);
line(10, 10, 360, 50);
stroke(255, 0, 0);
line(10, 30, 360, 70);

The state of your pen and your canvas remains the same until you change it.
If you don’t touch it, processing uses the default.

Colors

//try this
background (255, 255, 255);
//and then try this
//background (0, 0, 0);

Red green blue 0-255.
Make it red!
Try the color picker!

...
strokeWeight(4);
stroke(255, 0, 0);
//noStroke();
fill(0, 255, 0);
//noFill()
triangle(10, 20, 50, 200, 200, 100);

Ok, you are an artist now. Reproduce the Mondrian!

 

Transparency

createCanvas(500,500);
background (255, 255, 255);
smooth();
noStroke();
fill(255,0,0);
rect(100, 100, 100, 100);
fill(0,0,255,127); //255/2
rect(150, 150, 100, 100);

Also known as alpha channel.

 

Drawing mode
Sometimes you want to draw a circle from the top left corner or a square from the center. Here’s how to do it:

createCanvas(500,500);
rectMode(CENTER);
rect(35, 35, 50, 50);
rectMode(CORNER);
fill(102);
rect(35, 35, 50, 50);
createCanvas(500,500);
ellipseMode(CENTER);
ellipse(35, 35, 50, 50);
ellipseMode(CORNER);
fill(102);
ellipse(35, 35, 50, 50);

 

Vertex
You can use this combo to draw any polygon specifying the vertexes.

createCanvas(500,500);
//remember to specify a noFill() if you don't want a fill
beginShape();
vertex(20, 20);
vertex(40, 20);
vertex(40, 40);
vertex(60, 40);
vertex(60, 60);
vertex(20, 60);
endShape(CLOSE);
//if you don't specify CLOSE the outline will left open

Curves
curveVertex is the easiest way to draw continuous curves. It works like vertex (begin, points, end).

noFill();
beginShape();
curveVertex(84,  91);
curveVertex(84,  91);
curveVertex(68,  19);
curveVertex(21,  17);
curveVertex(32, 100);
curveVertex(32, 100);
endShape();

Arcs

createCanvas(500,500);
background (255, 255, 255);
smooth();
fill(142, 199, 242);
arc(150, 150, 300, 300, 0, PI/2);

The beginning and the end are a little tricky.
Remember: 0 is center right, 2*PI is the full circle. PI half circle. PI/2 a quarter etc…

Or just use radians(angleindegrees); to convert:

arc(150, 150, 300, 300, radians(180), radians(360) );

Draw a pacman!
Draw a smiley face!

p5js.org is the manual

Always check the examples

Always consult keep the reference open

Comments Off on Drawing in P5 Posted in

Hello p5

Screen Shot 2015-09-30 at 8.49.18 AM

P5.js is a javascript library (and a community) that aims to make coding accessible for artists, designers, educators, and beginners.

1) Watch the intro video

2) Download the code editor down in this page if it’s not installed in your computer.

Organizing your projects

You are going to make a lot of assignments and exercises. It’s crucial that you learn where your files are and how to organize them. This is what I recommend:

1) make a folder for this class

2) backup the folder on a USB stick or external hard drive, andrew space or cloud storage every time

3) make a folder for each p5 project by duplicating the example project and renaming it. Don’t use spaces or strange symbols for filenames

project_org

If you use the editor this is unnecessary. Just create a new project every time.

No let’s take a look at a project structure…

Some examples

Things done in Processing or p5

Data visualization
screen-shot-2016-09-28-at-10-18-37-am
http://benfry.com/zipdecode/

martin_wattenberg_and_fernanda_viegas1348616947
http://hint.fm/wind/

vivaldi-autumn-600
http://www.bewitched.com/song.html

Generative art / animation

Interactive toys/installations
yellowtail00
http://fox-gieg.com/dev/yellowtail_p5js/ (port)

Artificial Life

moth_gen
Moth Generator

Comments Off on Hello p5 Posted in

How to publish on your Andrew space

All CMU students have a personal web space at:

www.andrew.cmu.edu/user/yourusername
(obviously insert your andrew id)

We are going to use this space to publish the assignments.
In order to do from a computer in the lab you simply have to copy all of your files in the directory www of your “home”. You have a link to home in your desktop, if you log in in the lab.

Screen Shot 2015-09-02 at 8.48.57 PM

And go to the andrew publish page here

Type your id in the field and hit “publish”. Now your files are on the internet for the world to see at the corresponding address:
www.andrew.cmu.edu/user/yourusername/filename.ext

Please create a folder for each assignment or it will get very messy in there!

From your computer

Download Fetch Filezilla or equivalent FTP client.

Install and unpack.
Hostname: unix.andrew.cmu.edu
Insert your andrew id and password
Use: SFTP
Hit connect
Go to the www folder and upload your files and folders

fetch FTP

Go to the andrew publish page here

Hopefully your files will be accessible here
www.andrew.cmu.edu/user/yourusername/filename.ext

If something doesn’t work for mysterious reasons, you can just publish on a free neocities website

Comments Off on How to publish on your Andrew space Posted in

Twine: changing style and variables

For an overview of variable and conditionals download the variables in twine example

Stylesheet

Copy paste this example in the story > edit story stylesheet page

 

@import url(https://fonts.googleapis.com/css?family=Poiret+One);
/* this is a font import see below what it means */

/* Everything between these symbols is a comment and it won't affect the appearance */

/*
Cascading Style Sheets (CSS) is a language for specifying how documents (usually web pages) are presented to users. CSS code doesn't include content, only how parts of a document will appear in the browser.

To set the appearance of certain elements you need to know the names of the HTML elements. In case of twine2 there are only a few of them so it will be easy.
--- This tutorial refers to the Harlowe format ---
*/

/*
In the example below body is the selector, background-color is the property, #0f0f0f; is the value of the property.
The property:value; syntax is mandatory, including the semicolon. 

body is the container for everything else in the page.
*/

body {
background-color: #E2FFED;
}

/*
Multiple properties can defined for each element. Try to copy and paste these lines:

background-image: url("http://mycours.es/gamedesign2015/files/2015/09/colorful-triangles-background_yB0qTG6.jpg");


*/

/*
Color values in CSS can take five different forms: two hexadecimal, and two decimal, and plain-text color names like "black," "red," "pink," etc.

Hexadecimal goes from 0 to F, where A is 10, B is 11, etc. and F is 15. The max value for any color is FF, or 255 in decimal. When used to represent color, each third of the string represents a different color - red, green, and blue, in that order. So the components of a six-length hex string are like so: #ffffff

Here's red in 6-length hex: #ff0000

And here's the same color in 3-length hex, in which each value is effectively doubled (f -> ff, 0->00, etc.), resulting in an identical color value of the above 6-length hex: #f00

The max value for decimal notation is 255. So if we wanted to represent red with decimal notation, it'd look like this:

Here's red in decimal notation: rgb(255, 0, 0) 

You can have a 4th channel too, which is the alpha, i.e. opacity

rgba(255, 0, 0, 0.5)
*/

/* tw-passage is the style of each passage. Here are some common properties */

tw-passage {
background-color: #4FFFB8;
width: 400px;
padding:10px;
border: 5px solid #3CE8B7;
border-radius: 10px;
color:#248F84;
}

/* 
You can use custom fonts from google fonts https://www.google.com/fonts#
Here's how:
1. pick a font you like
2. click "quick use"
3. copy and paste the @import code at the very top of this page
4. copy and paste the font-family code inside the element you want to change (see below)
*/

tw-passage {
font-family: 'Poiret One', cursive;
font-size: 30px;
}

/* Note how you can have multiple selectors pointing at the same element the properties below will override the properties above 
*/

/* offset-x | offset-y | blur-radius | color */
tw-passage {
text-shadow: 1px 1px 2px rgba(0,0,0,0.5); 
}

/* tw-link will change the links' appearance */
tw-link {
color: rgb(255, 0, 215); 
}

/* uncomment this if you want the "undo" arrow to disappear */

/*
tw-icon.undo {
    display:none;
}

tw-icon.redo {
    display:none;
}

*/

/*
You can find a more extensive tutorial about CSS here:
http://furkleindustries.com/fictions/twine/twine2_CSS_tutorial/
*/

Images

If you want to add an image to a passage you can use the html tag img specifying the full URL of the image on the internet.

This displays an image I found on the internet:
<img src=”http://www.ms-tech.illinois.edu/_shared/images/current-students.jpg” alt=”” />

This displays an image I uploaded on my personal space
<img src=”http://www.andrew.cmu.edu/user/paolop/tarantula.png” alt=”” />

Scripting

Scripting in twine beyond variables and “if” is kind of complicated but here’s a complete tutorial that works only with the Harlowe style

Advanced twine example with macros

Made by Katie Rose Pipkin. It includes:

-Custom CSS for individual passages

-Images

-Audio playback across the whole story

-Additional scripts like timed passages

HOWEVER!

To use all of these features (except for custom CSS for tagged passages), you will need to use a story format that does not come installed with Twine 2. It is included in the ZIP file I’ve attached below- the file is called ‘format.js’. Installing it is pretty easy! On the home page of twine, you’ll click the menu item called ‘formats’ in the right-hand sidebar.

Screen Shot 2015-09-12 at 12.06.05 AM

Open it, and click ‘Add new format’

Screen Shot 2015-09-12 at 12.07.00 AM

Now, you’ll need to paste where the file is on your computer. If you are on a Mac (or Linux), the path will look something like this-

file:///Users/you/desktop/twine example/format.js

If you are on windows, it will look more like this-

file:///C:/Users/you/documents/twine example/format.js

But remember each path is specific to where it is on your machine! You can usually look at a file’s info to get its path. (If you have trouble with this, feel free to get in touch with me via email).

On Mac you can see the path of your file by right clicking and selecting get info (don't forget to add file:// at the beginning and format.js ad the end)
On Mac you can see the path of your file by right clicking and selecting get info (don’t forget to add file:// at the beginning and format.js ad the end). Twine may get stuck in loading state forever, but it should install the format correctly

That’s it! Now that your new story format is installed, it is available in a list of options when you change your story format. You’ll want to pick Sugarcube 2.

Screen Shot 2015-09-12 at 12.15.40 AM

You can now use advanced macros, music, and other neat things built into this story format. Full documentation is available here – or you can just download my example and play around with some options.

Download a zip file containing a twine example using sugarcube and additional macros

Comments Off on Twine: changing style and variables Posted in

Tool: Twine

twine2-storymap

Twine 2 is the tool we are using for this assignment. You can download it from here.

There are many resources and tutorials online however most of them refer to the previous version of Twine which had a more rudimentary interface. The Twine 2 guide is the best resource. Start from here:

Getting started with Twine 2

*Don’t forget to publish to file (bottom left) when you are done working. If you want to open a project from another computer import the published html file from Twine’s story list.

If you want to add an image to a passage you can use the html tag img specifying the full URL of the image on the internet.

This displays an image I found on the internet:
<img src=”http://www.ms-tech.illinois.edu/_shared/images/current-students.jpg” alt=”” />

This displays an image I uploaded on my personal space
<img src=”http://www.andrew.cmu.edu/user/paolop/tarantula.png” alt=”” />

Variable and style tutorial

Old Twine
If you want to use many images or add interactivity beyond simple links you should use Twine 1.4.2. I collected some resources for my advanced class here.

Comments Off on Tool: Twine Posted in