Date: 2025-03-05
New media art self-consciously reworks technology into culture, and rereads technology as culture. What’s more, it does so in a concrete, applied way; it manipulates the technology itself, with a nonindustrial latitude that admits misapplication and adaptation, rewiring and hacking, pseudofunctionality and accident. p.5, Metacreation
A-life begins with a notion of life that is wholly materialistic, involving no soul, vital force, or essence. In the words of the convenor of the first artificial life workshop, Christopher Langton, ‘Living organisms are nothing more that complex biochemical machines.’ Langton contends that rather than being any special substance or force, life is ‘a property of the organization of matter.’ Further, this organization is not simply a complex structure but a dynamic structure, a system active in real time: for a-life, life is most importantly manifest in behavior. p.7, Metacreation
We are no longer creating a work, we are creating creation…We are able to bring forth…results…which go beyond the intentions of their originators, and this in infinite number. – Nicholas Schöffer p.16, Metacreation
Stephen Hawkings The Meaning of Life (John Conway’s Game of Life segment)
Inventing Game of Life (John Conway) - Numberphile
from p5.js examples - Game of Life
More explorations with Multiple Neighborhoods Cellular Automata by softology
Goal: Have a number of objects move independently and respond to environmental forces.
A force is a vector that causes an object with mass to accelerate.
Mass - measure of matter in an object,
(in kilograms)
Weight - the force of gravity on an object
(in newtons)
density - mass per unit (such as grams per
centimeter)
In our sketches, the acceleration of an object is its force.
Pseudocode - concept
//NOTE: this is PSEUDOCODE to understand a concept!
class Mover {
constructor(){
;
vector location;
vector velocity;
vector acceleration
} }
//PSEUDOCODE
// example applying methods
mover.applyForce(wind);
mover.applyForce(gravity);
....
//example method code inside a mover class
applyForce(vector force) {
acceleration = force;
}
Note: the force really needs to reflect the total of all of the forces acting together: wind, gravity, and anything else. This could change from moment to moment, such as changing wind, so we need to recalculate every draw loop. We can do this by multiplying the acceleration by 0 at the end of a loop.
function update() {
.add(acceleration);
velocity.add(velocity);
location.mult(0);
acceleration }
Now, let’s work in actual Javascript/p5.js. Let’s create a mover, and apply a force to it.
//modified from Daniel Shiffman's The Nature of Code
let m;
function setup() {
createCanvas(640, 360);
= new Mover();
m
}
function draw() {
background(50);
//change its x value to move to the right
let wind = createVector(0.01, 0);
.applyForce(wind);
m
.update(); //change position
m.display(); //draw to screen
m.checkEdges(); //did we run off screen?
m }
Now that we have the basic code mocked out, we need to build the actual Mover class.
class Mover {
constructor() {
this.mass = 1;
this.position = createVector(30, 30);
this.velocity = createVector(0, 0); //starts at 0 until applied
this.acceleration = createVector(0, 0); //starts at 0 until applied
}
applyForce(force) {
var f = p5.Vector.div(force, this.mass); [derived](//derived) from Newton's Second Law
this.acceleration.add(f); //add all the forces together (wind, gravity, etc)
}
update() {
this.velocity.add(this.acceleration); //acceleration is added to velocity
this.position.add(this.velocity); //velocity is added to position to get the next position
this.acceleration.mult(0); //we reset the force to 0 at end
}
display() {
stroke(0);
strokeWeight(2);
fill(255, 127);
ellipse(this.position.x, this.position.y, 48, 48);
}
checkEdges() {
if (this.position.x > width) {
this.position.x = width;
this.velocity.x *= -1;
else if (this.position.x < 0) {
} this.velocity.x *= -1;
this.position.x = 0;
}if (this.position.y > height) {
this.velocity.y *= -1;
this.position.y = height;
}
}
}
Our full code example.
At this point, we have a single mover. We can create an array of movers, each with their own starting position, and forces acting on them.
//modified from Dan Shiffman Nature of Code
let movers = [];
function setup() {
createCanvas(640, 360);
for (let i = 0; i < 20; i++) { //initializing an array of 20 movers
= new Mover(random(0.1, 5), 0, 0);
movers[i]
}
}
function draw() {
background(255);
for (let i = 0; i < movers.length; i++) { //this runs in a loop, so that it affects all movers individually
let wind = createVector(0.01, 0);
let gravity = createVector(0, 0.1);
.applyForce(wind);
movers[i].applyForce(gravity);
movers[i].update();
movers[i].display();
movers[i].checkEdges();
movers[i]
} }
Notice the smaller movers are faster. Acceleration is force divided by mass, so larger masses have smaller accelerations.
An example with mousePressed to create a wind force on 2 movers.
// The Nature of Code
let moverA;
let moverB;
function setup() {
createCanvas(640, 360);
// A large Mover on the left side of the window
= new Mover(200, 30, 10);
moverA // A smaller Mover on the right side of the window
= new Mover(440, 30, 2);
moverB createP('Click mouse to apply wind force.');
}
function draw() {
background(51);
let gravity = createVector(0, 0.1);
let gravityA = p5.Vector.mult(gravity, moverA.mass);
.applyForce(gravityA);
moverA
let gravityB = p5.Vector.mult(gravity, moverB.mass);
.applyForce(gravityB);
moverB
if (mouseIsPressed) {
let wind = createVector(0.1, 0);
.applyForce(wind);
moverA.applyForce(wind);
moverB
}
.update();
moverA.display();
moverA.checkEdges();
moverA
.update();
moverB.display();
moverB.checkEdges();
moverB }
array of movers with forces - code example