This is my final project about collecting raindrops. Your health starts to lose from dehydration and the one way to survive is through collecting raindrops!. Watch out for those black ones, as they deplete your health if you touch them!
//Yunfeng Jiang
//Section E
//setting up variables
var myCanvas;
var waterN = 10;
var water = [];
var p;
var plat;
var waterSlopeProj = []
var acc = 0.5;
var size = 40;
var score = 0;
var health = 100;
function setup() {
myCanvas = createCanvas(500, 300);
//push water object to water array
for(var i = 0; i < waterN; i++){
var w = createWater(random(20, width-20), random(-200, -10), 2);
water.push(w);
}
//add platform object
if(random()<0.5){
plat = createPlatform(-125, random(25, 50), random(200, 250), 0);
}
else{
plat = createPlatform(width+125, random(25, 50), random(200, 250), 1);
}
//push waterslopeProj to array
for(var i = 0; i < waterN; i++){
var k = plat.h / plat.w; //slope
if(plat.sdir > 0.5){
var wsp = 100-tan(k)*(-water[i].x+plat.x+0.5*plat.w)
}
else{
var wsp = 100-tan(k)*(-water[i].x+plat.x-0.5*plat.w)
} //expression of the slope
waterSlopeProj.push(wsp);
}
//add player object
p = player();
}
function draw() {
//draw scene
background(176, 192, 200);
myCanvas.parent('canvasPlaceholder');
scene();
strokeWeight(1)
//add rain
updateWater();
addWater();
//update player
p.display(size);
p.moveY();
playerMove();
//add platform
updatePlatform();
addPlatform();
//gameplay properties
updateHealth();
updateProj();
checkHitRain();
checkHitPlat();
}
//draw scene
function scene(){
rectMode(CORNER)
strokeWeight(0);
fill(128, 96, 67);
rect(0, 250, width, 50)
text('score = '+ score, 10, 20);
text('health = '+ health, 10, 50)
}
//jump
function keyPressed(){
if (keyCode === 32 & p.y == 230){
p.dy = -10
}
}
//move player left and right
function playerMove(){
if (keyIsPressed === true){
if (keyIsDown(65) || keyIsDown(LEFT_ARROW)){
if(p.x > size/2){
p.moveX(-5);
}
}
if (keyIsDown(68) || keyIsDown(RIGHT_ARROW)){
if(p.x < width-size/2){
p.moveX(5);
}
}
}
}
//update health
function updateHealth(){
//deplete health
if (frameCount%30 == 0){
health = health - 1
}
//game over
if (health < 0){
textAlign(CENTER, CENTER)
fill(255, 0, 0);
textSize(50);
text("GAME OVER", width/2, height/2)
noLoop()
}
}
//check player location to raindrops
function checkHitRain(){
//check distance from player to rain
for(var i = 0 ; i < waterN; i++){
if(dist(p.x, p.y, water[i].x, water[i].y) < size*0.75){
score += 1;
//water that hits platform are considered bad water that depletes health
if(water[i].bad == false){
health += 1;
}
else{
health -= 1;
}
var w = createWater(random(20, width-20), random(-200, -10), 2);
water[i] = w;
}
}
}
function updateProj(){
for(var i = 0; i < waterN; i++){
var k = plat.h / plat.w; //slope
if(plat.sdir == 1){
waterSlopeProj[i] = 100-tan(k)*(-water[i].x+plat.x+0.5*plat.w) //expression of the slope
}
else{
waterSlopeProj[i] = 100+tan(k)*(-water[i].x+plat.x-0.5*plat.w) //expression of the slope
}
}
}
function checkHitPlat(){
for(var i = 0 ; i < waterN; i++){
var k = plat.h / plat.w
if(water[i].x > plat.x-plat.w*0.5 & water[i].x < plat.x + plat.w*0.5 && water[i].y > waterSlopeProj[i] && water[i].y < 100){
water[i].bad = true;
if(plat.sdir == 1){
water[i].x += 0.25*water[i].v/k
water[i].y += 0.25*water[i].v
}
else{
water[i].x -= 0.25*water[i].v/k
water[i].y += 0.25*water[i].v
}
}
else{
water[i].y += water[i].v
}
}
}
]]>This project is inspired by the tensions between dams, the environment, and people displaced or otherwise affected by dams.
In this animation, you become the dam builder. By pressing the mouse anywhere on the canvas, a dam emerges in the river, affecting the water level, marine life (fish and plants), and nearby communities (houses). Moving the mouse from left to right raises the dam and increases its impact, killing fish and making houses disappear. Pressing the space bar replenishes the fish population. Clicking the mouse advances to different facts about dams, stored in an array. These facts are adapted from research summarized by Earth Law Center and HuffPost.
/* jaden luscher
jluscher
section a
dammit(!): an educational animation */
var waterlevel1; // water level left of dam (upstream)
var waterlevel2; // water level right of dam (downstream)
var damX = 100; // x location of dam
var fish = [];
var numFish = 40;
var house = []; // original array of houses
var newhouseProbability = 0.03; // likelihood of a new house popping up
var plants = [];
var plantNum = 100;
var sceneNum = 0; // main reference for changing objects
var factNum = 0; // determines index of damFacts array
var damFacts = ['what a beautiful ecosystem... click to screw it up!',
'great. you built a dam. the river’s flow is restricted. click to learn more.',
'the united states has over 9,000 dams...',
'...many are not equipped to handle the amount of water that could result from climate change.',
'pennsylvania has 145 high hazard dams in poor or unsatisfactory condition.',
'dams have fragmented two thirds of the worlds large rivers...',
'...and have flooded a land area the size of california.',
'their reservoirs contain three times as much water as all the world’s rivers, and speed up evaporation.',
'dams disrupt fish and bird migration, both physically and chemically...',
'...and habitat loss is the leading cause of extinction.',
'upstream: nutrients trapped in reservoirs can cause toxic algae blooms.',
'downstream: ecosystems suffer from a lack of sedimentation and nutrients.',
'less nutrients = less vegetation = more erosion',
'river deltas are deprived of the silt they need to defend against damage from the ocean.',
'removing damaged and aging dams protects the surrounding population from disaster...',
'...and allows the rivers to restore their natural and biological integrity.',
'but often what happens instead is...'
];
function setup() {
createCanvas(480, 360);
noStroke();
frameRate(20);
angleMode(DEGREES);
textFont("monospace");
textSize(12);
if (sceneNum == 0) {
waterlevel1 = 240;
waterlevel2 = 240;
}
for(var i = 0; i < numFish; i++) {
var newFish = makeFish();
fish.push(newFish);
}
// first house
for(var i = 0; i < 10; i++) {
var firstHouses = makehouse(random(width), 180);
house.push(firstHouses);
}
for (var i = 0; i < plantNum; i++) {
var newPlant = makePlant();
plants.push(newPlant);
}
}
function draw() {
drawSky();
if (sceneNum > 0) { // only occurs once mouse has been pressed
sceneNum = constrain(floor(map(mouseX, width/2, width, 1, 12)), 1, 12);
waterlevel1 = 240 - sceneNum * 6;
waterlevel2 = 240 + sceneNum * 9;
}
drawMountain(0, 0.02, 0.00004, 50, 220); // background mountains
drawMountain(1, 0.01, 0.00007, 50, 220); // midground mountains
drawMountainAndHouses(0.005, 0.0001, 40, 220); // foreground mountains and houses
for (var i = 0; i < house.length; i++) {
house[i].move();
house[i].show();
}
var keepHouses = []; // stores houses in range
// keep houses still in range
if (house.length > 0) {
for (var i = 0; i < house.length; i++) {
if (house[i].houseExists & house[i].x + house[i].w > 0) {
keepHouses.push(house[i]);
}
}
}
house = keepHouses; // thank you Chuong!
water();
push();
for (var i = 0; i < plantNum; i++) {
if (plants[i].plantExists) {
plants[i].show();
translate(width / plantNum, 0);
}
}
pop();
// draw fish
for (var i = 0; i < numFish; i++) {
if (fish[i].fishExists) {
fish[i].move();
fish[i].show();
}
}
makeDam();
spitfacts(factNum);
if(factNum > damFacts.length - 1) {
gameOver();
}
}
function mousePressed() {
sceneNum = 1;
factNum ++;
}
function keyPressed() {
if(key == ' ') {
sceneNum = 0;
waterlevel1 = 240;
waterlevel2 = 240;
fish = []; // clear fish array
for(var i = 0; i < numFish; i++) {
var newFish = makeFish();
fish.push(newFish);
}
}
}
function gameOver() {
background("orange");
fill(255);
textSize(32);
text('DAMMIT!', 170, 180);
textSize(14);
textAlign(CENTER);
text('(YOU KILLED ALL THE FISH AND HAVE CAUSED SEVERE DAMAGE TO THE ECOSYSTEM)',
40, 250, 400)
noLoop();
}
function drawSky() {
background("orange");
push();
fill("yellow");
translate(400, 80);
scale(map(mouseY, 0, height, 0.5, 1));
ellipse(0, 0, 50, 50);
pop();
}
function spitfacts(f) {
push();
fill(255);
text(damFacts[f], 30, 30, 220, 80);
pop();
}
function drawMountain(mc, a, speed, high, low) {
noStroke();
if(mc == 0) fill(240, 150, 120); // background mountain color
if(mc == 1) fill(220, 130, 100); // midground mountain color
if(mc == 2) fill(20, 50, 180); // water color
beginShape();
vertex(width, height);
vertex(0, height);
for(var i = 0; i < width + 1; i ++){
var x = (i * a) + (millis() * speed);
var y = map(noise(x + mc*1000), 0, 1, high, low);
// x + mx*100 ensures mountains look different
vertex(i, y);
}
endShape();
}
function drawMountainAndHouses(a, speed, high, low) {
noStroke();
fill(200, 100, 60); // foreground mountain color
beginShape();
vertex(width, height);
vertex(0, height);
for(var i = 0; i < width + 1; i ++){
var x = (i * a) + (millis() * speed);
var y = map(noise(x), 0, 1, high, low);
vertex(i, y);
}
endShape();
if (newhouseProbability > random(1.0)) {
// make new house randomly
var newhouse = makehouse(width + 1, y);
house.push(newhouse);
}
}
function makehouse(px, py) {
var newhouse = {x : px,
y : random(220, py),
w : random(10, 30),
h : random(10, 30),
rh : random(3, 15),
c : color(random(100, 255), random(100), 0),
dx : -1,
houseExists: true,
move : movehouse,
show : showhouse}
return newhouse;
}
function showhouse() { // house x, y, width, height, roof height
push();
fill(this.c);
rect(this.x, this.y, this.w, this.h);
beginShape();
vertex(this.x - 2, this.y);
vertex(this.x + (this.w/2), this.y - this.rh); // roof peak
vertex(this.x + this.w + 2, this.y);
endShape();
fill(230, 180, 120);
rect(this.x + this.w / 2 - 4, this.y + this.h, this.w / 4, -this.h / 2); // door
pop();
}
function movehouse() {
this.x += this.dx;
if(this.y + this.h > waterlevel1) {
this.houseExists = false;
}
}
function makePlant() {
var plant = {x: 0,
y: 0,
c: color(random(50), random(100, 200), random(100)),
n: floor(random(3, 6)),
len: random(-5, -40),
plantExists: true,
show: showPlant,
}
return plant;
}
function showPlant() {
push();
translate(0, height + 10 + sceneNum * 3);
rotate(15 / this.n)
stroke(this.c);
strokeWeight(6/this.n);
for (var i = 0; i < this.n; i++) {
line(0, 0, 0, this.len + random(-1, 1));
rotate(-30 / this.n);
}
pop();
}
function makeFish() {
var newFish = {x: random(0, width),
y: random(waterlevel1 + 10, height-20),
w: int(random(10, 25)), h: int(random(5, 10)),
dx: random(-3, 3),
c: color(random(100, 255), random(100), random(100)),
fishExists: true,
fishDead: false,
show: showFish,
move: moveFish,
}
return newFish;
}
function moveFish() {
this.x += this.dx;
if (sceneNum == 0) {
// with no dam, fish change directions (off canvas)
if(this.x > width + 20 || this.x < -20) {
this.dx = -this.dx;
}
} else {
// if fish is to the left of dam, disappears
if(this.x < damX + 30) {
this.fishExists = false;
} // if fish is above water, dies
else if(this.y < waterlevel2 + 5) {
this.fishDead = true;
}
// if fish hits dam or goes off screen, change direction
if(this.x > width + 20 || this.x <= damX + 33) {
this.dx = -this.dx;
}
}
}
function showFish() {
fill(this.c);
ellipse(this.x, this.y, this.w, this.h);
if(this.dx < 0) { // facing left
if(this.fishDead) {
// if fish is dead, eyes make it appear belly-up
fishEye(this.x - 3, this.y + 3, this.w / 4);
} else {
fishEye(this.x - 3, this.y - 3, this.w / 4, true);
}
triangle(this.x + this.w/3, this.y,
this.x+this.w, this.y-5,
this.x+this.w, this.y+5);
} else { // facing right
if(this.fishDead) {
// if fish is dead, eyes make it appear belly-up
fishEye(this.x + 3, this.y + 3, this.w / 4);
} else {
fishEye(this.x + 3, this.y - 3, this.w / 4, true);
}
triangle(this.x - this.w/3,this.y,
this.x-this.w, this.y-5,
this.x-this.w, this.y+5);
}
// if fish is dead, stay floating at water level
if(this.fishDead) {
this.y = waterlevel2;
this.dx = 0;
}
}
function fishEye(x, y, sz, alive) {
push();
fill(255);
ellipse(x, y, sz, sz);
if (alive) {
fill(0);
ellipse(x, y, 2, 2);
}
pop();
}
function water() {
if(sceneNum == 0) { // initial river ripples using mountain function
drawMountain(2, 0.005, 0.0005, waterlevel1+10, waterlevel1-10);
}
push();
// water line shows gradient of water loss
for(var i = 0; i < sceneNum; i++) {
var alph = 10; // alpha
fill(0, alph); // waterline
rect(0, 240, width, height -240);
alph += 3;
translate(0, 10);
}
pop();
fill(20, 50 + sceneNum * 6, 180 - sceneNum * 6); // blue water
if (sceneNum == 0) {
rect(0, waterlevel1, width, height - waterlevel1);
} else {
if (factNum > 9) { // fact 10 is about algae blooms
fill(20, 100, 50);
}
// water left of dam
rect(0, waterlevel1, damX, height - waterlevel1);
// water right of dam
rect(damX, waterlevel2, width - damX, height - waterlevel2);
}
}
function makeDam() {
fill(180, 180, 150);
if (sceneNum > 0) {
beginShape();
vertex(damX - 10, waterlevel1 - 20);
vertex(damX + 5, waterlevel1 - 20);
vertex(damX + 30, height);
vertex(damX - 10, height);
endShape();
}
}
//hfroling
//section c
var level = 1;
var spot;
var a;
var b;
var lilies = [];
var fishies = [];
var turtles = [];
var heights = [80,140,200,260,320,380,440,500];
var bunny;
function preload() {
bunnyStopped = loadImage("https://i.imgur.com/ASG9W87.png"); //loads image
bunnySitting = loadImage("https://i.imgur.com/fouQhgx.png"); //loads image
bunnyDead = loadImage("https://i.imgur.com/9d2vjo4.png");
lilyPadImg = loadImage("https://i.imgur.com/Z69HCHs.png");
killerFishImg = loadImage("https://i.imgur.com/mRGD4oC.png");
turtleImg = loadImage("https://i.imgur.com/4JEWEFk.png");
}
function setup() {
createCanvas(800,600);
background(120, 150, 81);
imageMode(CENTER)
a = width/2-35;
b = 295;
noStroke();
print(bunnyStopped.width); // displays in console
print(bunnyStopped.height);
for(j=0;j<8;j++){ //lily pad object setup
lilies[j] = new Object();
lilies[j].x = (floor(random(60,width-60)/60)*60)-20;
lilies[j].y = heights[j];
}
for(k=0;k<8;k++){ //fish set up
fishies[k] = new Object();
fishies[k].x = random(width-50);
fishies[k].y = heights[k];
fishies[k].dx = random(1,6);
}
for(l=0;l<8;l++){ //turtles set up
turtles[l] = new Object();
turtles[l].x = random(width-50);
turtles[l].y = heights[l];
turtles[l].dx = random(-3,3);
}
bunny = makeBunny(width/2,320,0);
}
function draw() { //draw the image
background(120, 150, 81);
textSize(18);
textAlign(CENTER, CENTER);
fill('white');
if(frameCount < 150){
text('PRESS UP ARROW KEYS TO HOP ACROSS THE RIVER', width/2, 30);
}
river();
bunny.draw();
bunny.collideLily();
bunny.onTurtle = false;
for(i=0;i<8;i++){
bunny.collideTurtle(turtles[i])
}
for(i=0;i<8;i++){
bunny.collideWater(fishies[i],turtles[i],lilies[i])
}
bunny.dieBunny();
}
function river(){ //make river
var depth = 60;
spot = 50;
if(level == 1){
text('LEVEL 1',100, height-30);
for(var i=1; i<3; i++){
fill('lightblue');
rect(0,spot,width,depth);
fill(208,228,247);
rect(0,spot+depth,width,depth);
spot += depth*2;
}
for(k=0;k<4;k++){ //fishies on river
drawFish(fishies[k]);
fishies[k].x += fishies[k].dx
if (fishies[k].x > width) {
fishies[k].x = -40;
fishies[k].dx = random(1,6);
}
}
for(l=0; l<4; l++){ //turtles on river
drawTurtle(turtles[l]);
turtles[l].x += turtles[l].dx
if (turtles[l].x >= width -25 & turtles[l].dx > 0) {
turtles[l].dx = -turtles[l].dx;
}
if (turtles[l].x <= 25 & turtles[l].dx < 0) {
turtles[l].dx = -turtles[l].dx;
}
}
}
for(j=0;j<4;j++){ //lilies on river
drawLily(lilies[j]);
}
if(level == 2){
text('LEVEL 2',100, height-30);
for(var i=1; i<4; i++){
fill('lightblue');
rect(0,spot,width,depth);
fill(208,228,247);
rect(0,spot+depth,width,depth);
spot += depth*2;
}
for(k=0;k<6;k++){ //fishies on river
drawFish(fishies[k]);
fishies[k].x += fishies[k].dx
if (fishies[k].x > width) {
fishies[k].x = -40;
fishies[k].dx = random(1,6);
}
}
for(l=0; l<6; l++){ //turtles on river
drawTurtle(turtles[l]);
turtles[l].x += turtles[l].dx
if (turtles[l].x >= width -25 & turtles[l].dx > 0) {
turtles[l].dx = -turtles[l].dx;
}
if (turtles[l].x <= 25 & turtles[l].dx < 0) {
turtles[l].dx = -turtles[l].dx;
}
}
for(j=0;j<6;j++){ //lilies on river
drawLily(lilies[j])
}
}
if(level == 3){
text('LEVEL 3',100, height-30);
for(var i=1; i<5; i++){
fill('lightblue');
rect(0,spot,width,depth);
fill(208,228,247);
rect(0,spot+depth,width,depth);
spot += depth*2;
}
for(k=0;k<8;k++){ //fishies on river
drawFish(fishies[k]);
fishies[k].x += fishies[k].dx
if (fishies[k].x > width) {
fishies[k].x = -40;
fishies[k].dx = random(1,6);
}
}
for(l=0; l<8; l++){ //turtles on river
drawTurtle(turtles[l]);
turtles[l].x += turtles[l].dx
if (turtles[l].x >= width -25 & turtles[l].dx > 0) {
turtles[l].dx = -turtles[l].dx;
}
if (turtles[l].x <= 25 & turtles[l].dx < 0) {
turtles[l].dx = -turtles[l].dx;
}
for(j=0;j<8;j++){ //lilies on river
drawLily(lilies[j])
}
}
}
if(level == 4){
fill('lightblue');
rect(0,0,width,450)
textSize(36);
fill('white')
text('YOU WON!',width/2, height/2-50);
image(bunnySitting,(width/2),450,200,200);
textSize(12);
text('PRESS RELOAD TO PLAY AGAIN!',100, 30);
noLoop();
}
}
function makeBunny(a,b,da){ // make bunny
var bunny = {ba: a, bb: b, bda: da,
draw: drawBunny,
step: stepBunny,
collideLily: collideLily,
onLily: false,
collideTurtle: collideTurtle,
onTurtle: false,
collideWater: collideWater,
dieBunny: dieBunny
}
return bunny;
}
function drawBunny(){
image(bunnyStopped,this.ba,this.bb,50,50);
if(this.bb<=0){
level+=1;
this.bb +=level*120 + 240
}
}
function stepBunny(keyCode){ /// add this .y
if (keyCode === UP_ARROW){
this.bb -= 60;
}
if (keyCode === DOWN_ARROW){
this.bb += 60;
}
if (keyCode === RIGHT_ARROW){
this.ba += 60;
}
if (keyCode === LEFT_ARROW){
this.ba -= 60;
}
}
function collideLily(lily){
this.onLily=false;
for(i=0;i<lilies.length;i++){
if(dist(lilies[i].x,lilies[i].y,this.ba,this.bb)<=10){
this.onLily = true;
this.bda = 0;
console.log("should be on a lily")
}
}
}
function collideWater(fish,turtle,lily){ //work on
if(this.onLily == false & this.onTurtle==false && this.bb < 180+(level*120) && this.bb > 60){
if(dist(this.ba,this.bb,turtle.x,turtle.y)>15||(dist(lily.x,lily.y,this.ba,this.bb)>10)){
this.ba += 1;
}
}
}
function collideTurtle(turtle){
if (this.onLily == false){
if(dist(turtle.x,turtle.y,this.ba,this.bb)<=20){
this.ba += turtle.dx
console.log("on a turtle")
this.onTurtle = true;
}
}
}
function dieBunny(){
if(this.ba > width){
fill(135, 6, 4);
rect(0,0,width,height);
fill(82, 25, 21);
rect(0,330,width,height);
textSize(36);
fill('white')
text('YOU LOST!',width/2, 100);
image(bunnyDead,(width/2),350,200,150);
textSize(12);
text('PRESS RELOAD TO PLAY AGAIN!',100, 30);
noLoop();
}
}
function keyPressed() {
bunny.step(keyCode);
}
function drawLily(lily){
image(lilyPadImg, lily.x,lily.y, 50,50);
}
function drawFish(fish){
image(killerFishImg, fish.x, fish.y,50,50);
}
function drawTurtle(turtle){
if(turtle.dx < 0){
push()
translate(turtle.x, turtle.y);
rotate(radians(180));
image(turtleImg, 0, 0, 50,50);
pop()
}
else{
image(turtleImg, turtle.x, turtle.y, 50,50);
}
}
/* Evan Stuhfire
* estuhlfi@andrew.cmu.edu section B
* Project-14: Municiple Water Management Game
*/
// map repair state variables
var rsGreen = 0;
var rsYellow = 1;
var rsOrange = 2;
var rsRed = 3;
// variable to track dam cracks
var dYellow = false;
var dOrange = false;
var dRed = false;
// map facility icons to text
var fDam = "Dam";
var fFiltration = "Filter";
var fPumping = "Pump";
var fHydro = "Hydro\nPower";
// Array to hold facility icons
var iconArray = [];
// Array to hold house objects
var houseArray = [];
var numHouses = 5;
// arrays to store house coordinates
var houseX = [35, 80, 140, 210, 190];
var houseY = [315, 335, 310, 285, 330];
// global worker object
var workerObj;
// player stats, number of fixes
var statsObj;
// control for directions page
var gameStart = true;
function drawIcon() {
fill(this.repairColor);
// Draw both the tray and the facility icons
drawIconHelper(this.trayx, this.trayy,
this.traySize, this.facilityIcon, 13);
drawIconHelper(this.facilityx, this.facilityy,
this.facilitySize, this.facilityIcon, 10);
}
function drawIconHelper(x, y, size, label, txs) {
push();
translate(x, y);
ellipse(0, 0, size);
strokeWeight(1);
fill(10);
textAlign(CENTER);
textSize(txs);
text(label, 0, -3);
pop();
}
function drawWorker() {
fill(255);
// draw circle to contain the worker
ellipse(this.wx, this.wy, this.size);
// draw stickman worker
drawStickFigure(this.wx, this.wy, this.headSize);
textAlign(CENTER);
textSize(12);
fill(255);
strokeWeight(1);
text("1. Click the worker", this.wx, this.wy + 50);
}
function drawStickFigure(x, y, h) {
fill(255);
strokeWeight(1.5);
// body
line(x, y - 15, x, y + 20);
// legs
line(x, y + 20, x - 10, y + 30);
line(x, y + 20, x + 10, y + 30);
// arms
line(x, y + 10, x -10, y + 15);
line(x, y + 10, x + 10, y + 15);
// head
circle(x, y - 15, h);
// hat
fill(255, 255, 0);
arc(x, y - 20, 30, 33, PI, 2 * PI, OPEN);
arc(x, y -25, 30, 15, 0, PI, CHORD);
// eyes
line(x - 5, y - 15, x - 5, y - 12);
line(x + 5, y - 15, x + 5, y - 12);
// mouth
line(x - 5, y - 5, x + 5, y - 5);
}
function drawHouse() {
// draw a house
// brick red
fill(153, 0, 0);
rect(this.hx, this.hy, this.hw, this.hh);
// draw roof
fill(50); // grey for roof
triangle(this.hx, this.hy, this.hx + this.hw/2, this.hy - 15,
this.hx + this.hw, this.hy);
// draw windows
if(this.power == true) {
fill(255, 255, 153); // yellow for lit windows
} else {
fill(5); // black for unlit windows, no power
}
rect(this.hx + 5, this.hy + 5, 10, 12);
rect(this.hx + 25, this.hy + 5, 10, 12);
// draw door
fill(153, 102, 51); // brown for door
rect(this.hx + 15, this.hy + 15, 10, 15);
}
function houseState() {
// change power to house based on probability of
// an outage, chances increae with higher repair state
var chanceOfOutage = 0;
var highState = 0;
// find highest repair state of hydro power
for(i = 0; i < iconArray.length; i++) {
var currentIcon = iconArray[i];
if(currentIcon.facilityIcon.slice(0, 1) == "H" &
currentIcon.repairState > highState) {
highState = currentIcon.repairState;
}
}
if(highState >= rsOrange & this.power == false){
return;
}
// green repair state all houses have power
switch (highState) {
case rsGreen:
chanceOfOutage = 0;
break;
case rsYellow:
// yellow repair state, probability of outage = low
chanceOfOutage = .005;
break;
case rsOrange:
// orange repair state, probability of outage = medium
chanceOfOutage = .01;
break;
case rsRed:
// red repair state, probability of outage = high
chanceOfOutage = .5
break;
}
if(random(0, 1) < chanceOfOutage) {
this.power = false; // outage
} else {
this.power = true; // no outage
}
}
function changeState() {
if(gameStart == true) {
return;
}
repairFacility(this);
// generate a problem based on likelyhood
if(random(0, 1) < this.problemLikely) {
this.ageOfState++;
// increase likelihood of problems over time
this.problemLikely += .002;
}
if(this.ageOfState > 15 & this.repairState == rsYellow) {
// set state and color to orange
// reset ageOfState and increase likelyhood of problem
this.repairState = rsOrange;
this.repairColor = color(255, 102, 0);
this.ageOfState = 0;
this.problemLikely = .015;
} else if(this.ageOfState > 10 & this.repairState == rsOrange) {
// set state and color to red
// reset ageOfState and increase likelyhood of problem
this.repairState = rsRed;
this.repairColor = color(204, 0, 0);
this.ageOfState = 0;
this.problemLikely = .02;
if(this.facilityIcon.slice(0, 1) == "D" ||
this.facilityIcon.slice(0, 1) == "P") {
statsObj.floods++;
} else if(this.facilityIcon.slice(0, 1) =="F"){
statsObj.filterFail++;
} else {
statsObj.powerLoss++;
}
} else if(this.ageOfState > 5 & this.repairState == rsGreen) {
// set state and color to yellow
// reset ageOfState and increase likelyhood of problem
this.repairState = rsYellow;
this.repairColor = color(255, 255, 0);
this.ageOfState = 0;
this.problemLikely = .01;
}
// Check for failing services
if(this.facilityIcon.slice(0, 1) == "D") {
damFailure(this);
} else if(this.facilityIcon.slice(0, 1) == "P" &
this.repairState == rsRed) {
pumpFailure(this);
} else if(this.facilityIcon.slice(0,1) == "F" &
this.repairState == rsRed) {
filterFailure(this);
}
}
function makeIconObj(tx, ty, fx, fy, fac) {
// object def for game icons
var icon = {trayx: tx,
trayy: ty,
facilityx: fx,
facilityy: fy,
traySize: 50,
facilitySize: 35,
facilityIcon: fac,
repairState: rsGreen,
repairColor: color(0, 200, 0),
ageOfState: 0,
problemLikely: .05,
trayClick: false,
facillityClick: false,
drawFunction: drawIcon,
stateFunction: changeState
}
return icon;
}
function makeWorker(x, y) {
// object def for worker
var icon = {wx: x,
wy: y,
size: 80,
headSize: 30,
clicked: false,
drawFunction: drawWorker
}
return icon;
}
function makeHouse(x, y) {
// object def for houses
var house = {hx: x,
hy: y,
hw: 40, // house width
hh: 30, // house height
power: true,
drawFunction: drawHouse,
stateFunction: houseState}
return house;
}
function makeStats() {
// object definition for game stats
var stats = {maxRepairs: 10,
maxAge: 60,
repairs: 0,
floods: 0,
filterFail: 0,
powerLoss: 0}
return stats;
}
function createIcons() {
// create icons for equipment tray
iconArray.push(makeIconObj(200, 430, 295, 140, fDam));
iconArray.push(makeIconObj(270, 430, 60, 217, fFiltration));
iconArray.push(makeIconObj(340, 430, 397, 300, fPumping));
iconArray.push(makeIconObj(410, 430, 305, 235, fHydro));
// create worker icon
workerObj = makeWorker(70, 425);
// create game stats object
statsObj = makeStats();
}
function createHouses() {
// make numHouses number of houses
for(i = 0; i < numHouses; i++) {
houseArray[i] = makeHouse(houseX[i], houseY[i]);
}
}
function setup() {
createCanvas(480, 480);
createIcons();
createHouses();
}
function draw() {
background(204, 239, 255);
drawScene();
// draw houses
for(j = 0; j < houseArray.length; j++) {
var currentHouse = houseArray[j];
currentHouse.stateFunction();
currentHouse.drawFunction();
}
// draw game icons
var cIcon = 10;
for(i = 0; i < iconArray.length; i++) {
var currentIcon = iconArray[i];
currentIcon.stateFunction();
currentIcon.drawFunction();
// if the tray icon was clicked show on mouse
if(currentIcon.trayClick == true) {
fill(currentIcon.repairColor);
// transform to make small icon at mouse pointer
push();
scale(.5);
translate(mouseX, mouseY);
drawIconHelper(mouseX - 70, mouseY + 30,
currentIcon.traySize,
currentIcon.facilityIcon);
pop();
}
}
// draw worker icon
workerObj.drawFunction();
// if the worker and/or icon has been clicked,
// draw worker/icon at mouse pointer
if(workerObj.clicked == true) {
push();
// transformation to make small worker at mouse pointer
scale(.5);
translate(mouseX, mouseY);
drawStickFigure(mouseX - 20, mouseY + 40, workerObj.headSize);
pop();
}
drawScore();
// at the start of game show instructions
if(gameStart == true) {
instructions();
}
// Display game stats
// if at least maxRepairs
if(statsObj.repairs >= statsObj.maxRepairs ||
iconArray[0].ageOfState >= 100) {
gameStats();
noLoop();
}
}
function mouseClicked() {
// start game
if(gameStart == true) {
gameStart = false;
return;
}
// check if worker was clicked
var d = dist(mouseX, mouseY, workerObj.wx, workerObj.wy);
if(d < workerObj.size/2) {
if(workerObj.clicked == false) {
workerObj.clicked = true;
} else {
workerObj.clicked = false;
}
return;
}
// check if worker has been clicked
if(workerObj.clicked == true) {
// check if tool was clicked in equipement tray
for(var i = 0; i < iconArray.length; i++) {
var icon = iconArray[i];
var d = dist(mouseX, mouseY, icon.trayx, icon.trayy);
if(d < icon.traySize/2) {
setTrayIcon(i);
return;
}
// check if facility was clicked
if(icon.trayClick == true) {
var d = dist(mouseX, mouseY, icon.facilityx, icon.facilityy);
if(d < icon.facilitySize/2) {
icon.facilityClick = true;
}
}
}
}
}
function gameStats() {
// draw final game stats from statsObj
push();
fill(255, 255, 255, 235);
rectMode(CENTER);
rect(width/2, height/2, 400, 400);
fill(5);
textSize(24);
strokeWeight(1);
textAlign(CENTER);
text("You made "+statsObj.repairs+" repairs", width/2, 75);
textSize(16);
text("The town flooded "+statsObj.floods+" time(s)",
width/2, 115);
text("The town filtration failed "+statsObj.filterFail+" time(s)",
width/2, 145);
text("The town lost all power "+statsObj.powerLoss+" time(s)",
width/2, 175);
textSize(24);
text("Refresh to Play Again", width/2, 380);
pop();
}
function instructions() {
// Create instruction front page
fill(255, 255, 255, 235);
push();
rectMode(CENTER);
rect(width/2, height/2, 400, 400);
fill(5);
textSize(24);
strokeWeight(1);
textAlign(CENTER);
text("Municipal Water Management Game", width/2, 75);
// create a click to start message
text("Click Anywhere to Start", width/2, 420);
textAlign(LEFT);
textSize(14);
var x = 55;
var y = 110;
// Display instructions
text("Welcome! You are managing the repairs for a town's water",
x, y);
text("supply. If the dam or pump fail the town will flood. If the",
x, y + 20);
text("filtration system fails the water will be dirty. If the hydro",
x, y + 40);
text("electric plant falters the lights in the houses will flicker and",
x, y + 60);
text("go out. Circle icon colors change as urgency increases.",
x, y + 80);
textAlign(CENTER);
textSize(20);
text("To Play: Make Repairs", width/2, y + 120);
textAlign(LEFT);
textSize(14);
text("1. Click the worker. The icon will appear at the mouse pointer.",
x, y + 150);
text("2. Click a yellow, orange, or red icon from the icon tray.",
x, y + 180);
text("3. Click the matching facility in need of repair.",
x, y + 210);
pop();
}
function setTrayIcon(index) {
// when setting icon clicked = true, set the others = false
for(i = 0; i < iconArray.length; i++) {
if(i == index) {
iconArray[i].trayClick = true;
}else {
iconArray[i].trayClick = false;
}
}
}
function drawScore() {
fill(5);
strokeWeight(1);
textAlign(LEFT);
text("Repairs made: " + statsObj.repairs, 3, 15);
}
function repairFacility(cur) {
// reset icons, player repairs the service
if(cur.facilityClick == true) {
if(cur.repairState == rsGreen) {
// there was nothing to repair
return;
}
// increment number of fixes for player score
statsObj.repairs++;
cur.trayClick = false;
cur.facilityClick = false;
workerObj.clicked = false;
// update for repaird facilities repaired
if(cur.facilityIcon.slice(0, 1) == "D") {
damFail = false;
} else if(cur.facilityIcon.slice(0, 1) == "P") {
pumpFail = false;
} else if (cur.facilityIcon.slice(0, 1) == "F") {
filterFail = false;
}
// user clicked to repair
// reset state to green
cur.repairState = rsGreen;
cur.repairColor = color(0, 200, 0);
// reset age of facility to 0
cur.ageOfState = 0;
// reset probability of problem
cur.problemLikely = .007;
return;
}
}
// variables to track failure
var damFail = false;
var pumpFail = false;
var filterFail = false;
function filterFailure(filter) {
if(filter.repairState == rsRed) {
filterFail = true;
}
}
function pumpFailure(pump) {
if(pump.repairState == rsRed) {
pumpFail = true;
}
}
function damFailure(dam) {
if(dam.repairState == rsGreen & dYellow == true){
// reset cracks
dYellow = false;
dOrange = false;
dRed = false;
}
if(dam.repairState == rsRed) {
dRed = true;
damFail = true;
} else if(dam.repairState == rsOrange) {
dOrange = true;
} else if(dam.repairState == rsYellow) {
dYellow = true;
}
}
function drawScene() {
// draw horizon line
fill(0, 102, 0);
rect(0, height/3, width, height);
drawStaticElements();
drawCracks();
drawFlood();
drawFilterFail();
}
function drawStaticElements() {
// draw static elements for the game background
// function are in static.js
drawMountains();
drawWater(r, g, b);
drawDam();
drawFiltration();
drawPumpStation();
drawHydro();
drawIconTray();
}
var r = 0;
var g = 0;
var b = 204;
var ft = 0; // filter transparency
function drawFilterFail() {
// turn water brown to show it is polluted
// when the filter fails
if(filterFail == true) {
r = 134;
g = 89;
b = 45;
ft = min(t + 1, 255);
} else {
r = 0;
g = 0;
b = 204;
ft = 0; // filter transparency
}
}
var t = 0; // variable to control transparency
function drawFlood() {
// flood the town when the dam fails
if(damFail == true || pumpFail == true) {
t = min(t + 3, 255);
}
else if (damFail == false & pumpFail == false) {
// dam is repaired decrease transparency
// to make grass green again
t = max(t - 3, 0);
}
fill(r, g, b, t);
rect(0, height/3, width, height);
drawStaticElements();
drawCracks();
}
function drawCracks() {
// draw crack in dam
if(dYellow == true) {
// draw small cracks
noFill();
strokeWeight(1);
beginShape();
vertex(355, 170);
vertex(365, 162);
vertex(370, 140);
endShape();
}
if(dOrange == true) {
// draw more cracks
noFill();
beginShape();
vertex(350, 170);
vertex(342, 180);
vertex(333, 164);
vertex(325, 168);
endShape();
strokeWeight(2);
beginShape();
vertex(355, 170);
vertex(380, 180);
vertex(392, 164);
endShape();
}
if(dRed == true) {
// draw many cracks
noFill();
beginShape();
vertex(350, 170);
vertex(347, 175);
vertex(355, 182);
vertex(358, 190);
vertex(383, 192);
vertex(400, 194);
vertex(425, 205);
endShape();
strokeWeight(3);
beginShape();
vertex(345, 170);
vertex(340, 160);
vertex(325, 155);
vertex(315, 152);
endShape();
}
strokeWeight(1);
}
// Functions to draw static game elements
function drawIconTray() {
fill(230);
textAlign(LEFT);
textSize(12);
strokeWeight(1);
text("Icon Tray", 165, 395);
text("2. Click icon from tray 3. Click matching facility",
165, 475);
rect(165, 400, 285, 60);
}
function drawHydro() {
// draw hydro electric power
fill(179, 179, 204);
beginShape();
vertex(255, 220);
vertex(365, 237);
vertex(365, 254);
vertex(255, 237);
endShape(CLOSE);
// draw top
beginShape();
vertex(255, 220);
vertex(320, 200);
vertex(388, 208);
vertex(365, 237);
endShape(CLOSE);;
// draw side
beginShape();
vertex(365, 237);
vertex(388, 208);
vertex(388, 215);
vertex(365, 254);
endShape();
}
function drawPumpStation() {
// draw pumpStation
fill(179, 179, 204);
rect(width * .75, 275, 75, 50);
// pump station top
beginShape();
vertex(width *.75, 275);
vertex(width *.75 + 15, 265);
vertex(width * .75 + 90, 265);
vertex(width * .75 + 75, 275);
endShape(CLOSE);
// pump station side
beginShape();
vertex(width * .75 + 90, 265);
vertex(width * .75 + 90, 310);
vertex(width * .75 + 75, 325);
vertex(width * .75 + 75, 275);
endShape(CLOSE);
// Draw pipe
beginShape();
vertex(width * .75, 285);
vertex(width * .75 - 30, 285);
vertex(width * .75 - 30, 325);
vertex(width * .75 - 15, 325);
vertex(width * .75 - 15, 300);
vertex(width * .75, 300);
endShape(CLOSE);
}
function drawFiltration() {
// draw filtration faciity
fill(179, 179, 204);
rect(width/14, height/2.5, 50, 50);
// Draw top
beginShape();
vertex(width/14, height/2.5);
vertex(width/14 + 20, height/2.5 - 10);
vertex(width/14 + 70, height/2.5 - 10);
vertex(width/14 + 50, height/2.5);
endShape(CLOSE);
// Draw side
beginShape();
vertex(width/14 + 70, height/2.5 - 10);
vertex(width/14 + 70, height/2.5 + 40);
vertex(width/14 + 50, height/2.5 + 50);
vertex(width/14 + 50, height/2.5);
endShape(CLOSE);
// Draw pipe 1
ellipse(100, 202, 10, 10);
beginShape();
vertex(98, 198);
vertex(130, 200);
vertex(130, 240);
vertex(125, 240);
vertex(125, 205);
vertex(98, 205);
endShape(CLOSE);
// Draw pipe 2
ellipse(95, 222, 10, 10);
beginShape();
vertex(93, 218);
vertex(113, 218);
vertex(113, 245);
vertex(107, 245);
vertex(107, 225);
vertex(93, 225);
endShape(CLOSE);
}
function drawWater(r, g, b) {
// draw water as a multipoint curve vertex shape
fill(r, g, b);
beginShape();
curveVertex(425, 100);
curveVertex(280, 120);
curveVertex(320, 200);
curveVertex(250, 240);
curveVertex(0, 260);
curveVertex(0, 300);
curveVertex(270, 280);
curveVertex(470, 150);
endShape(CLOSE);
}
function drawDam() {
var x = width * .55;
var y = height/3;
fill(179, 179, 204);
// draw face of dam
beginShape();
vertex(x, y + 50);
vertex(x + 60, y + 45);
vertex(x + 90, y + 50);
vertex(x + 120, y + 55);
vertex(x + 150, y + 70);
vertex(x + 185, y + 90);
vertex(x + 185, y -20);
vertex(x, y - 50);
endShape(CLOSE);
// draw top ledge
beginShape();
vertex(x, y - 50);
vertex(x + 30, y - 55);
vertex(x + 215, y - 25);
vertex(x + 185, y - 20)
endShape();
// draw right side
beginShape();
vertex(x + 185 , y - 20);
vertex(x + 215, y - 25);
vertex(x + 215, y + 85);
vertex(x + 185, y + 90)
endShape();
}
function drawMountains() {
// set origin to 0, horizon line
push();
translate(0, height/3);
// draw curves for background mountains
fill(71, 71, 107);
beginShape();
vertex();
vertex(-20, 20);
vertex(0, -125);
vertex(45, -80);
vertex(120, -155);
vertex(200, -85);
vertex(250, -135);
vertex(290, -90);
vertex(360, -140);
vertex(440, -40);
vertex(500, -120);
vertex(510, 0);
endShape(CLOSE);
// draw curves for mid range mountains
fill(153, 153, 150);
beginShape();
vertex(-30, 30);
vertex(30, -65);
vertex(75, -30);
vertex(120, -90);
vertex(165, -35);
vertex(210, -65);
vertex(255, -25);
vertex(310, -80);
vertex(395, 25);
endShape(CLOSE);
// draw curves for near mountains
fill(0, 153, 51);
beginShape();
curveVertex(-30, 60);
curveVertex(0, -5);
curveVertex(50, -15);
curveVertex(95, -5);
curveVertex(135, -20);
curveVertex(175, -5);
curveVertex(220, -15);
curveVertex(275, 10);
curveVertex(300, 25)
endShape(CLOSE);
pop();
}
Here is my final project! It’s an interactive animation of a waterpark. Click anywhere to send someone down a random slide — or, if you prefer, click the top of a slide to send someone down that specific one!
//sam rauch, srauch, section B
//final project
//this code creates an animation of a waterpark. It's populated with people objects that have a
//skin tone and swimsuit color randomly picked from an array, so they are different every time
//you reload the page. In the foreground, people go by in a lazy river in tubes. In the background,
//people wait in line for waterslide towers.
//click anywhere to send someone down a random slide, or, click at the top of a slide to send
//a person down that specific slide!
//clouds x, y, and scale
var cloudsx = [];
var cloudsy = [];
var cloudsSc = [];
//skin tones and swimsuit colors
var skincolors;
var swimcolors;
//will hold people waiting for waterslide 1
var topSlide = [];
var slideToppers =[];
var groundWaiters1 = [];
var stairWaiters1 = [];
//will hold people waiting for waterslide 2
var groundWaiters2 = [];
var stairWaiters2 = [];
var topguy;
//bushes and trees
var bushSizes = [];
var bushColors = [];
var treeSizes = [];
var treeColors = [];
//people in lazy river
var tubers = [];
//color of wood in waterslide towers
var woodcolor;
//variables for people going down slides
var slider;
var slidetoggler;
var randomizer1;
//store mouseX and mouseY when clicked
var xWhenClick;
var yWhenClick;
function setup() {
createCanvas(600, 400);
background(220);
woodcolor = color(105, 89, 56);
//fill cloud array with clouds at random scales and positions
for (var i=0; i<8; i++){
cloudsx[i]= random(-10, width-10);
cloudsy[i] = random(-10, 200);
cloudsSc[i] = random(1,3);
}
//skin tones and swimsuit color values
skincolors = [color(235, 207, 176), color(204, 168, 126), color(107, 77, 43),
color(148, 98, 41), color(117, 84, 47), color(217, 195, 154),
color(235, 213, 192), color(69, 48, 29), color(247, 220, 195)];
swimcolors = [color(194, 78, 130), color(224, 49, 22), color(224, 144, 22),
color(102, 23, 11), color(102, 23, 11), color(102, 93, 11),
color(207, 195, 87), color(159, 207, 87), color(49, 145, 42),
color(42, 145, 89), color(92, 191, 186), color(92, 140, 191),
color(24, 73, 125), color(105, 89, 156), color(154, 89, 156),
color(55, 84, 179)]
//filling the array that handles the people in the lazy river
var tubespacer = 50;
for (var i=0; i<10; i++){
tubers[i] = makeTuber(tubespacer, random(340, 350));
tubespacer += random(30, 100);
}
//creating the size and color of the bushes and trees
for (var i=0; i<width+30; i++){
bushColors[i] = color(100, random(150, 170), 100);
bushSizes[i] = random(30, 60);
treeColors[i] = color(100, random(150, 170), 100);
treeSizes[i] = random(100, 150);
}
//filling the array of people waiting on top of waterslide1
var slideLocation = 410;
for (var i=0; i<3; i++){
topSlide[i] = makeDude(365+(i*15), 125, false);
slideToppers[i] = makeDude(slideLocation, 125, false);
slideLocation +=40;
}
//filling the array of people waiting for waterslide1 on the ground
var groundWaiters1Loc = 280;
for (var i=0; i<9; i++){
groundWaiters1[i] = makeDude(groundWaiters1Loc, 280, false);
groundWaiters1Loc += 20;
}
//filling the array of people waiting on the waterslide1 stairs
var stairWaiters1Loc = 460;
var stairHeight1 = 280;
for (var i=1; i<13; i++){
stairWaiters1[i] = makeDude(stairWaiters1Loc, stairHeight1, false);
stairWaiters1Loc += 17;
if (i<4 || i>=3) {stairHeight1-= 20;}
if (i%4 == 0) {stairWaiters1Loc = 460;}
if (i>4 & i<=8) {stairHeight1 = 205;}
}
//filling array of people waiting on ground for waterslide 2
var groundWaiters2Loc = 240;
for (var i=0; i<6; i++){
groundWaiters2[i] = makeDude(groundWaiters2Loc, 270, false);
groundWaiters2Loc -= 20;
}
//filling array of people waiting on stairs for waterslide 2
var stairWaiters2Loc = 120;
var stairHeight2 = 265;
var sidestep = 14;
var counter2 = 0;
for (var i=0; i<20; i++){
stairWaiters2[i] = makeDude(stairWaiters2Loc, stairHeight2, false);
counter2 += 1;
if (counter2%4==0){
sidestep = sidestep*-1;
}else{
stairWaiters2Loc -= sidestep;
}
stairHeight2 -= 11;
}
topguy = makeDude(85, 50, false);
//when this is true (set to true when mouse is clicked), an if statement in draw
//runs that sends someone down a slide
slidetoggler = false;
}
function draw() {
background(162, 219, 222);
backgroundstuff(); //draw clouds, trees, waterslides
slidego(); //send someone down slide when the mouse is clicked
foregroundstuff(); //draw lazy river and bushes
}
//trigger someone to go down slide in draw function
function mousePressed(){
xWhenClick = mouseX;
yWhenClick = mouseY;
slidetoggler = true;
slider = makeDude(0, 0, true);
randomizer1 = random(0,4);
}
//translate and rotate to the top of a specific slide
function slidemover(xpos,ypos,rot){
push();
translate(xpos,ypos);
rotate(radians(rot));
slider.y += 4;
slider.draw();
pop();
}
//send someone down specific slide if clicked, random otherwise
function slidego(){
if (slidetoggler==true){
//if click at the top of a specific slide, send someone down that slide
if (xWhenClick >= 70 & xWhenClick <= 130 && yWhenClick >= 40 && yWhenClick <= 100){
slidemover(88,50,-25);
} else if (xWhenClick >= 400 & xWhenClick <= 435 && yWhenClick >= 110 && yWhenClick <= 170){
slidemover(432,140,30);
} else if (xWhenClick >= 440 & xWhenClick <= 475 && yWhenClick >= 110 && yWhenClick <= 170){
slidemover(472,140,30);
} else if (xWhenClick >= 480 & xWhenClick <= 515 && yWhenClick >= 110 && yWhenClick <= 170){
slidemover(512,140,30);
} else { //otherwise, send down a random slide
push();
if(randomizer1<=3){ //for three slides on right tower
if (randomizer1 < 1){
translate(432,140);
} else if (randomizer1 >= 1 & randomizer1 < 2){
translate(472,140);
} else {
translate(512, 140);
}
rotate(radians(30));
} else { //for tall slide on left tower
translate(88,50);
rotate(radians(-25));
}
slider.y+= 4;
slider.draw();
pop();
}
}
}
//creates a person object
function makeDude(xpos, ypos, armpos){
var dude = {x:xpos, y:ypos, armsup:armpos,
swimsuit:swimcolors[floor(random(0,15))],
swimtype:random(0,2),
skin:skincolors[floor(random(0,9))],
draw:drawDude};
return dude;
}
function drawDude(){
noStroke();
fill(this.skin);
ellipse(this.x, this.y, 10, 10); //head
rect(this.x-5, this.y+7, 10, 16); //torso
stroke(this.skin);
strokeWeight(4.5);
line(this.x, this.y, this.x, this.y+10); //neck
strokeWeight(3.5); //toggles if arms are up or down based on this.armsup var declared in constructor
if (this.armsup == true){
line(this.x-4, this.y+7, this.x-11, this.y-2); //right arm
line(this.x+4, this.y+7, this.x+11, this.y-2); //left arm
} else {
line(this.x-4, this.y+7, this.x-10, this.y+16); //right arm
line(this.x+4, this.y+7, this.x+10, this.y+16); //left arm
}
strokeWeight(4);
line(this.x-3, this.y+22, this.x-3, this.y+35); //right leg
line(this.x+3, this.y+22, this.x+3, this.y+35); //left leg
noStroke();
if (this.swimtype<1){ //swim trunks
fill(this.swimsuit);
rect(this.x-6, this.y+18, 12, 5);
rect(this.x-6, this.y+23, 5, 5);
rect(this.x+1, this.y+23, 5, 5);
} else { //bikini
fill(this.swimsuit);
rect(this.x-5, this.y+10, 10, 13);
ellipse(this.x-2, this.y+10.5, 5, 5);
ellipse(this.x+2, this.y+10.5, 5, 5);
stroke(this.swimsuit);
noStroke();
fill(this.skin);
triangle(this.x-1, this.y+24, this.x-5, this.y+24, this.x-5, this.y+18);
triangle(this.x+1, this.y+24, this.x+5, this.y+24, this.x+5, this.y+18);
rect(this.x-5, this.y+13, 10, 4);
}
}
//creates a person in a tube object
function makeTuber(xpos, ypos){
var tuber = {x:xpos, y:ypos,
swimsuit:swimcolors[floor(random(0,15))],
swimtype:random(0,2),
skin:skincolors[floor(random(0,9))],
draw:drawTuber};
return tuber;
}
function drawTuber(){
push();
//inner tube
stroke(this.skin);
strokeWeight(4);
line(this.x-1, this.y+12, this.x-11, this.y+22);
noStroke();
fill(62, 158, 62);
rect(this.x-14, this.y+18, 28, 16);
ellipse(this.x-14, this.y+26, 16);
ellipse(this.x+14, this.y+26, 16);
stroke(30, 94, 30);
strokeWeight(4);
line(this.x-10, this.y+23, this.x+10, this.y+23);
//head, neck, torso, and back arm
push();
translate(this.x+6, this.y+4);
rotate(radians(10));
noStroke();
fill(this.skin);
ellipse(0, 0, 10, 10); //head
rect(-5, 7, 10, 16); //torso
stroke(this.skin);
strokeWeight(4.5);
line(0, 0, 0, 10); //neck
noStroke();
if (this.swimtype<1){ //swim trunks
fill(this.swimsuit);
rect(-6, 18, 12, 5);
rect(-6, 23, 5, 5);
rect(1, 23, 5, 5);
} else { //bikini
fill(this.swimsuit);
rect(-5, 10, 10, 13);
ellipse(-2, 10.5, 5, 5);
ellipse(+2, +10.5, 5, 5);
stroke(this.swimsuit);
noStroke();
fill(this.skin);
triangle(-1, 24, -5, 24, -5, 18);
triangle(1, 24, 5, 24, 5, 18);
rect(-5, 13, 10, 4);
}
pop();
strokeWeight(4.5);
stroke(this.skin);
line(this.x+4, this.y+25, this.x+4, this.y+25);
line(this.x, this.y+25, this.x-6, this.y+21);
//a few more details
noStroke();
fill(62, 158, 62);
rect(this.x-10, this.y+25, 20, 9);
strokeWeight(4.5);
stroke(this.skin);
line(this.x+10, this.y+14, this.x+16, this.y+25); //front arm
line(this.x-6, this.y+21, this.x-10, this.y+31); //right leg
line(this.x+2, this.y+25, this.x, this.y+34); //left leg
//water texture
noStroke();
fill(81, 181, 201, 100);
rect(this.x-22, this.y+30, 44, 6);
pop();
}
//draws the waterslide on the left
function waterslide1(x,y){
//stairs
fill(woodcolor);
beginShape();
vertex(x+100, y+80);
vertex(x+100, y+90);
vertex(x+170, y+20);
vertex(x+170, y+10);
endShape();
rect(x+100, y+80, 70, 8);
beginShape();
vertex(x+100, y+160);
vertex(x+113, y+160);
vertex(x+170, y+95);
vertex(x+170, y+80);
endShape();
//pillars
fill(95, 79, 46);
rect(x+5, y+5, 5, 155);
rect(x+100, y+5, 5, 155);
rect(x+170, y+5, 5, 155);
//shade poles
rect(x+3, y-50, 3, 50);
rect(x+180-6, y-50, 3, 50);
rect(x+50, y-55, 3, 55);
rect(x+130-6, y-55, 3, 55);
//shades
fill(35, 82, 168);
rect(x+3, y-55, 47, 6);
triangle(x+3, y-55, x+50, y-55, x+27, y-70);
rect(x+50, y-60, 77, 5);
triangle(x+50, y-60, x+127, y-60, x+88.5, y-85);
rect(x+127, y-55, 50, 5);
triangle(x+127, y-55, x+176, y-55, x+152, y-70);
//railings
fill(95, 79, 46);
var xpos = x;
for (var i = 0; i < 12; i++){
rect(xpos, y-15, 2, 15);
xpos += 5;
}
for (var j = 0; j<2; j++){
xpos += 22
for (var i = 0; i < 4; i++){
rect(xpos, y-15, 2, 15);
xpos += 5;
}
}
xpos += 19
for (var i = 0; i < 4; i++){
rect(xpos, y-15, 2, 15);
xpos += 5;
}
//deck
fill(woodcolor);
rect(x, y, 180, 10);
rect(x, y-15, 180, 3);
//draw slides
var color1 = color(166, 61, 124);
slide1(x+60, y, color1);
var color2 = color(186, 176, 67);
slide1(x+100, y, color2);
var color3 = color(57, 94, 163);
slide1(x+140, y, color3);
}
//draws slides for waterslide1 function
function slide1(x,y,color){
var slidewide = 22;
fill(color);
beginShape();
vertex(x, y);
vertex(x+slidewide, y);
vertex(x-80, y+180);
vertex(x-80-slidewide, y+180);
endShape();
var margin = 4;
fill(150, 255, 255, 50);
beginShape();
vertex(x+margin, y);
vertex(x+slidewide-margin, y);
vertex(x-80-margin, y+180);
vertex(x-80-slidewide+margin, y+180);
endShape();
}
//draws waterslide on left
function waterslide2(x,y){
//pillars and stairs
var loc = 310; //increment 46
for (var i = 0; i< 5; i++){
fill(woodcolor);
if (i%2==0 || i==0) {
beginShape();
vertex(x-30, loc-51);
vertex(x-30, loc-41);
vertex(x+30, loc);
vertex(x+30, loc-10);
endShape();
} else {
beginShape();
vertex(x-30, loc);
vertex(x-30, loc-10);
vertex(x+30, loc-51);
vertex(x+30, loc-41);
endShape();
}
loc -= 44;
}
fill(95, 79, 46);
rect(x-30, y, 6, 230); //bottom y = 310
rect(x+24, y, 6, 230);
rect(x-30, y-40, 3, 40);
rect(x+27, y-40, 3, 40);
fill(189, 65, 43);
rect(x-30, y-45, 60, 6);
triangle(x-30, y-45, x+30, y-45, x, y-60);
fill(woodcolor);
rect(x-30, y, 60, 10);
rect(x-30, y-15, 15, 2.5);
rect(x+15, y-15, 15, 2.5);
var location = x-30;
for (var i = 0; i<8; i++){
rect(location, y-15, 2, 15);
if (i != 3){location += 5;}
else {location += 28;}
}
fill(252, 165, 3);
beginShape();
vertex(x-15, y);
vertex(x+15, y);
vertex(x+140, y+260);
vertex(x+110, y+260);
endShape();
fill(150, 255, 255, 50);
beginShape();
vertex(x-10, y);
vertex(x+10, y);
vertex(x+130, y+250);
vertex(x+115, y+260);
endShape();
}
//draws cloud
function cloud(x,y, amt){
noStroke();
fill(218, 237, 236);
push();
translate(x,y);
scale(amt);
ellipse(0,0,40);
ellipse(-20, 5, 30);
ellipse(20, 5, 30);
pop();
}
//draws background
function backgroundstuff(){
//clouds
for (var i=0; i<8; i++){
cloud(cloudsx[i], cloudsy[i], cloudsSc[i]);
}
//trees
noStroke();
for (var i=0; i<width+30; i+= 80){
fill(treeColors[i]);
ellipse(i, 270, treeSizes[i]);
}
//fence
strokeWeight(2);
stroke(120);
line(0, 280, width, 280);
strokeWeight(.75);
for (var i=-12; i<width+12; i+=4){
line(i, 300, i+16, 280);
line(i, 300, i-16, 280);
}
//concrete
noStroke();
fill(199, 196, 163); //concrete color
rect(0, 300, width, 100);
fill(168, 162, 28);
//pool at base of slides
fill(81, 181, 201);
rect(80, 325, 420, 100);
ellipse(80, 350, 50);
ellipse(500, 350, 50);
//people in waterslide1 line
for (var i=0; i<topSlide.length; i++){
topSlide[i].draw();
slideToppers[i].draw();
}
for (var i=0; i<groundWaiters1.length; i++){
groundWaiters1[i].draw();
}
for (var i=1; i<stairWaiters1.length; i++){
stairWaiters1[i].draw();
}
//people in waterslide2 line
for (var i=0; i<stairWaiters2.length; i++){
stairWaiters2[i].draw();
}
for (var i=0; i<groundWaiters2.length; i++){
groundWaiters2[i].draw();
}
topguy.draw();
//draw waterslides
waterslide1(350, 160);
waterslide2(100, 80);
}
//draws bushes, draws and updates lazy river
function foregroundstuff(){
//bushes
for (var i=0; i<width+30; i+= 30){
fill(bushColors[i]);
ellipse(i, 350, bushSizes[i]);
}
//lazy river
fill(179, 176, 143);
rect(0, 350, width, 50);
fill(81, 181, 201);
rect(0, 355, width, 40);
//lazy river inhabitants
for (var i = 0; i < tubers.length; i++){
if (tubers[i].x <= -30){
var mover = tubers.shift();
mover.x = width + 28;
tubers.push(mover);
}
tubers[i].draw();
tubers[i].x -= 0.5;
}
}
I created my self-portrait using different symbols that are linked to the pixel colors on the image. When the mouse is pressed, the shapes are drawn to create the image.
//amy hu
//amyhu
//section d
var img;
var smallPoint, largePoint;
var symbols = ["❀", "❋", "✯"]
function preload() {
img = loadImage('https://i.imgur.com/2ZzOdG6.png');
}
function setup() {
createCanvas(450,450);
// smallPoint = 5;
// largePoint = 20;
imageMode(CENTER);
noStroke();
background(255);
img.loadPixels();
}
function draw() {
//mouse location determines point size
var pointillize = map(mouseX, 0, width, smallPoint, largePoint);
//picks random x y value
var x = floor(random(img.width));
var y = floor(random(img.height));
//gets pixel color form a xy value
var pix = img.get(mouseX, mouseY);
//fills pixel color
fill(pix, 128);
ellipse(x, y, pointillize, pointillize);
//draws symbols when mouse is pressed
if(mouseIsPressed){
textSize(random(10,35));
text(random(symbols), mouseX, mouseY);
}
}
I read “How Artists Can Bridge the Digital Divide and Reimagine Humanity“, and the societal issue that was addressed was access and affordability of information and communication technologies (ICT). The article discussed the problem in filling the digital divide known as the “production gap” and how the majority of user-generated content is built from a small sector of ‘elites’. This highlights the importance of digital collaboration with digital artists through transdisciplinary educational initiative can become the solution to bringing these multiple divides.
I liked how the writer showcased numerous artist-led experiments in order to give a visual representation of these unique creators. For instance, I thought Victoria Vesna‘s hacked gaming technology to show the destructive power of noise pollution across oceans was a great example of STEAM artists utilizing their resources and knowledge to foster both a positive and sharable attitude for using digital media. Overall, I enjoyed educating myself on the significance of creating a sustainable and equitable digital society.
My code shows a scrolling New Mexico landscape, with sagebrush in the foreground, sage-covered land stretching to the mountains in the middleground, and a mountain range in the background.
//Sam Rauch, section B, srauch@andrew.cmu.edu, project
//this code creates a randomly generated scrolling new mexico landscape with sagebrush
//in the foreground, distant bushes in the middleground, and mountains in the background.
//A late afternoon moon hangs low in the sky.
//arrays for objects
var sageArray = [];
var mountainArray = [];
var backbushes = [];
function setup() {
createCanvas(400, 200);
background(220);
text("p5.js vers 0.9.0 test.", 10, 15);
frameRate(30);
//fill sage array with random sagebrush
var initsageY = random(30, 40);
for (var i = 0; i<20; i++){
sageArray.push(newSage(initsageY, random(160, 190)));
initsageY += random(20, 40);
}
//fill mountain array with random starter mountains
var initmountX = random(0,40);
for (var i = 0; i < 20; i ++){
var mont = makeMountain(initmountX, random(70, 90), random(40, 60));
mountainArray.push(mont);
initmountX += random(30, 40);
}
//fill backbushes array with random starter bushes
var initBushX = random(0,10);
for (var i = 0; i<100; i++){
backbushes.push(newBush(initBushX, random(100, 150)));
initBushX += random(0, 10);
}
}
function draw() {
background(129, 173, 223);
noStroke();
//draw moon
var moonfill = color(235, 243, 247, 200);
fill(moonfill);
ellipse(300, 50, 20, 20);
//draw middleground
fill(111, 158, 148);
rect(0, 100, 400, 100);
//draw mountains, push in new mountains on right as they go off screen to left
for (var i = 0; i < mountainArray.length; i++){
mountainArray[i].peakX -= 0.25;
mountainArray[i].draw();
if (mountainArray[i].peakX <= -70){
mountainArray.shift();
mountainArray.push(makeMountain(random(440, 460), random(60, 90), random(40, 60)));
}
}
//draw backbushes, push in new ones as go off screen
for (var i = 0; i < backbushes.length; i++){
backbushes[i].x -= 0.5;
backbushes[i].draw();
if (backbushes[i].x <= -10){
backbushes.shift();
backbushes.push(newBush(random(402, 420), random(100, 150)));
}
}
//draw foreground
fill(156, 127, 70);
rect(0, 150, 400, 50);
//draw sagebrush in front
for (var i = 0; i < sageArray.length; i++){
//draw each sagebrush shadow; in seperate loop so it will always draw before
//(thus underneath) the sagebrush
fill(117, 98, 56);
ellipse(sageArray[i].x, sageArray[i].y, 20, 8);
}
for (var i = 0; i < sageArray.length; i++){
sageArray[i].x -= 2; //move each sagebrush along to left
sageArray[i].draw(); //draw each sagebush
}
if (sageArray[0].x < -10){ //if sagebrush is off the canvas, shift and push in a new one
sageArray.shift();
sageArray.push(newSage(random(410, 430), random(160, 190)));
}
}
//objects for sagebrush, mountain, and backbush
function newSage(xpos,ypos){
var sage = {x: xpos, y:ypos, draw:drawSagebrush};
return sage;
}
function drawSagebrush(){
stroke(66, 46, 23);
var bushstart = this.x-10;
for (var i = 0; i<8; i++){
line(this.x,this.y,bushstart,this.y-15);
bushstart += 3;
}
stroke(66, 110, 90);
fill(93, 135, 111);
ellipse(this.x-8, this.y-15, 7, 7);
ellipse(this.x+8, this.y-15, 7, 7);
ellipse(this.x-5, this.y-17, 8, 8);
ellipse(this.x+5, this.y-17, 8, 8);
ellipse(this.x,this.y-18, 10, 10);
noStroke();
}
function makeMountain(x, y, wide){
var mountain = {peakX: x, peakY: y, base:wide, draw: drawMountain};
return mountain;
}
function drawMountain(){
fill(96, 129, 181);
beginShape();
vertex(this.peakX, this.peakY);
vertex(this.peakX-this.base, 100);
vertex(this.peakX+this.base, 100);
endShape();
}
function newBush(xpos,ypos){
var bush = {x: xpos, y:ypos, draw: drawBush};
return bush;
}
function drawBush(){
strokeWeight(5);
stroke(106, 135, 124);
point(this.x, this.y);
strokeWeight(1);
noStroke();
}
link:https://www.vice.com/en/article/4x4p43/6-art-projects-prying-the-lid-off-online-privacy
Title: 6 Art Projects Prying The Lid Off Online Privacy
dvargas David Vargas
The artists printed out the downloaded profiles the collected and turned them into a wallpaper covering every surface of a room.
If anyone can use our photos to their own nefarious ends, how much are we sacrificing in personal value of our identity?
The vice article I read highlights a number of art exhibits that
deal with the question of privacy in the digital age. The artists
challenge the idea of relinquishing our data so easily to companies like
apple or facebook. One of the art exhibits was fbfaces where
the artist combed the internet for facebook profiles with a profile photo, name,
and other identifiers, downloaded the profiles and created a wallpaper with the data.
Each pixel of the wallpaper representing someone. This piece makes it clear
just how open our information is to be used by absolutely anyone for any reason.
The installation begs the question “If anyone can use our photos to their own nefarious ends, how much are we sacrificing in personal value of our identity?”
Another installation is “A charge for privacy”. This installtion is a power station
that charges your phone however it in exchange gets access to your phones saved photos after agreeing
to the ‘terms and service’ In this installtion the taking of your data is treated as a transaction just
as it is in real life. The photos are then legally owned by the gallery and are projected to be viewed
at the gallery for all to see. The installation lays bear the reality of digital privacy or the lack of it.
Anna Grubauer writes about a series of artists and activists that have faced prejudices or noticed prejudices made from Artificial Intelligence. She writes that, as AI becomes more and more common, it is important for us to be aware of the shortcomings and even harms of this system. For example, Joy Buolamwini and Timnit Gebru investigated AI face recognition and found that the error rate for this system is significantly higher among women, and even higher among women with darker skin. This is harmful as face recognition is often used in medical fields to detect skin cancers, so if it is not accurate for a certain group of people, it puts them at risk. In addition, Mary Flanagan pointed out more discrimination in her project “[help me know the truth]”. She found that AI often has stereotypes based on race and will label “leaders” as those with more western features. The good news is that there are many up and coming feminist computer programmers working to get rid of this gap in research. One of these names is Caroline Siders, who has a website called Feminist Data Set which is a multi year art project that combines resources for a collection of feminist data.
https://ars.electronica.art/aeblog/en/2020/04/10/women-in-media-arts-ai/
]]>