Hours by the Pigeons
This is a 24-hour clock that allows one to tell the time by counting how many pigeons are on the roof (The gifs above are sped-up versions of the clock). The location that the pigeons fly in from and out to are randomized, in addition to the pigeon’s sizes and colors. A big thanks to Golan Levin and John Choi for tirelessly explaining the inner workings of classes to me.
To improve on this project, I’d implement behavior that would allow the pigeons to shuffle around the rooftop after landing. I’d also add some visible wings to the pigeons when they fly on and off of the screen.
//Miranda Jacoby
//EMS Interactivity Section A
//majacoby@andrew.cmu.edu
//Copyright Miranda Jacoby 2014
//A big thanks o John Choi for walking me through OOP.
//Implement personal space
//for i
//if px[i] becomes a high or low value
//Implement hour spawn/despawn
//Implement nice movement for pigeon entering/leaving screen
//Initialize pigeon
Pigeon[] pigeonArray = new Pigeon[24];//22? at 0 o'ckloc there is no pigeon.
int hours = hour();//second()% 24;
int pigeonCount = hours;
float detailOffset = width/20;
int newvar = 0;
int oldvar = 0;
boolean deleted = true;
int delay = 0;
void setup(){
size(600, 400);
for (int i =0; i < pigeonCount; i ++){
pigeonArray[i] = new Pigeon(i);
}
}
void draw(){
background(50, 130, 230);
hours = hour();//second()% 24;
//Function calls!
//draw pigeons first so that they are layered under the building
newvar = hours;
if (oldvar != newvar){
if (oldvar == 23 && newvar == 0){
flyAllAway();
delay = 10;
deleted = false;
}
else if (delay <= 0){
createPigeon();
}
}
oldvar = newvar;
delay = delay - 1;
if(deleted == false && delay <= 0){
pigeonArray = new Pigeon[24];
pigeonCount = 0;
deleted = true;
}
for (int i =0; i < pigeonCount; i ++){
pigeonArray[i].update();
}
drawBuilding();
}
void createPigeon(){
pigeonArray[pigeonCount] = new Pigeon(hours);
pigeonCount = pigeonCount + 1;
}
void flyAllAway(){
for (int i =0; i < pigeonCount; i ++){ pigeonArray[i].isFlyingAway = true; } } class Pigeon { //Final position float fpx, fpy; //Starting position float spx = random(0, 600), spy = -30; //Current position float cpx, cpy; //Fly away position float rpx, rpy; int hour; float pdiam = random (12, 16);//14; float colorPicker = random (0, 5); float spacing = 20; float velx = 0.1, vely = 0.1; boolean isFlyingAway = false; //Work on personal space boolean isLanded = false; //Constructor: draw the pigeon, initialize variables Pigeon (int hour){ fpx = (hour * spacing) + 50; fpy = 285;//height - height/3.5; cpx = spx; cpy = spy; rpx = random(0, 600);//random (-600, 1200); rpy = random (-200, -300); } void update(){ if (isFlyingAway == true){ flyAway(); } if (isFlyingAway == false){ move(); } display(cpx, cpy, colorPicker); } void display(float px, float py, float colPicker){ //draws individual pigeon, does not increment noStroke(); //body bodyColor(colPicker); ellipse(px, py + pdiam/2, pdiam * 1.5, pdiam * 1.5); fill(192, 190, 214); ellipse(px, py + pdiam/1.5, pdiam * 1.2, pdiam * 1.2); //neck //for (colPicker >= 0){
bodyColor(colPicker);
//}
ellipse(px, py, pdiam, pdiam * 1.2);
//eyes
fill(227, 121, 34);
//left eye
ellipse(px - pdiam/3, py - (pdiam - pdiam/2.7), pdiam/8, pdiam/8 );
//right eye
ellipse(px + pdiam/3, py - (pdiam - pdiam/2.7), pdiam/8, pdiam/8 );
//head
bodyColor(colPicker);
ellipse(px, py - (pdiam - pdiam/2.5), pdiam/2, pdiam/2);
//beak
stroke(0);
line(px - 1, py - (pdiam - pdiam/2.5), px - 1 + (pdiam/10), py - (pdiam - pdiam/2.5) );
noStroke();
fill(255);
ellipse(px, py - (pdiam - pdiam/2.7), pdiam/10, pdiam/10 );
}
void move(){
//Move pigeons between positions with easing
cpx = cpx + velx * (fpx - cpx);
cpy = cpy + vely * (fpy - cpy);
//Move pigeons between positions withouy easing
//cpx = fpx;
//cpy = fpy;
}
void flyAway(){
//Move pigeons between positions with easing
cpx = cpx + velx * (rpx - cpx);
cpy = cpy + vely * (rpy - cpy);
//Move pigeons between positions without easing
//cpx = rpx;
//cpy = rpy;
}
void bodyColor(float colPicker){
if ((colPicker == 0) || (colPicker < 1)){
fill(132, 95, 137);
}
else if ((colPicker == 1) || (colPicker < 2)){
fill(118, 145, 158);
}
else if ((colPicker == 2) || (colPicker < 3)){
fill(118, 122, 131);
}
else if ((colPicker == 3) || (colPicker < 3.5)){
fill(147, 107, 93);
//fill(137, 91, 73);
}
// else if ((colPicker == 4) || (colPicker < 5)){
// fill(245, 235, 225);
// }
else {
fill(115, 101, 131);
}
}
}
void drawBuilding(){
detailOffset = width/40;
noStroke();
//Orange Rect
fill(211, 135, 58);
rect(width/8, height - height/4, width - width/4, height - height/4);
//White trapezoid
fill(247, 225, 202);
quad(width/10 - detailOffset , height - height/4,
width - width/10 + detailOffset , height - height/4,
width - width/10 - detailOffset , height - height/8,
width/10 + detailOffset , height - height/8);
//Offwhite detail
stroke(219, 190, 161);
strokeCap(SQUARE);
//Middle line
strokeWeight(16);
line(width/10 , height - height/5.75,
width - width/10, height - height/5.75);
//Bottom line
strokeWeight(8);
line(width/10 + detailOffset , height - height/8,
width - width/10 - detailOffset, height - height/8);
//Top line
strokeWeight(12);
line(width/10 - detailOffset , height - height/4.30,
width - width/10 + detailOffset, height - height/4.30);
//Middle line white detail
stroke(247, 225, 202);
strokeWeight(4);
line(width/10 , height - height/5.75,
width - width/10, height - height/5.75);
}