Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
//"roadtrip" by NOLAN GRANT, student number 991412483, september 20, 2017

/*NOTE: all objects that make up the car are mirrored across x=200, with the left shape being defined on top and the right shape defined below
 the right side shapes x-values are written as (400 minus the respective value from the left side's shape) to make adjustments easier. 
 also, the sawtooth function is made up of 25 sin operations, adding more or removing some will make it more or less accurate respectively*/

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

void draw() {

  background(12, 3, 54);

  //road
  fill(64, 54, 54);
  noStroke();
  strokeWeight(1);
  quad(165, 115, 235, 115, (((mouseX/400.0))*(-1000))+1500, 400, (((mouseX/400.0))*(-750.0))-100.0, 400);

  //solid middle line on road
  fill(127);
  noStroke();
  quad(199, 115, 201, 115, (((mouseX/400.0))*(-535))+475, 400, (((mouseX/400.0))*(-535))+455, 400);

  //occluders to make road line appear dotted
  noStroke();
  rectMode(CENTER);
  fill(64, 54, 54);

  rect(200, (4*tan(frameCount*.005)*400.0), 400, 43);
  rect(200, (4*tan(frameCount*.005)*400.0)+800, 400, 43);
  rect(200, (4*tan(frameCount*.005)*400.0)+1200, 400, 43);
  rect(200, (4*tan(frameCount*.005)*400.0)+400, 400, 43);

  rect(200, (4*tan((frameCount*.005)+(PI/2.0))*400.0), 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/2.0))*400.0)+800, 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/2.0))*400.0)+1200, 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/2.0))*400.0)+400, 400, 43);

  rect(200, (4*tan((frameCount*.005)+(PI/4.0))*400.0), 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/4.0))*400.0)+800, 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/4.0))*400.0)+1200, 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/4.0))*400.0)+400, 400, 43);

  rect(200, (4*tan((frameCount*.005)+(PI/(4.0/3.0)))*400.0), 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/(4.0/3.0)))*400.0)+800, 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/(4.0/3.0)))*400.0)+1200, 400, 43);
  rect(200, (4*tan((frameCount*.005)+(PI/(4.0/3.0)))*400.0)+400, 400, 43);


  //dirt beside road, covers the edges of the road line occluder
  fill(42, 30, 16);
  triangle(0, 115, 165, 115, (((mouseX/400.0))*(-750.0))-100.0, 400);
  triangle(235, 115, 400, 115, (((mouseX/400.0))*(-1000))+1500, 400);


  //sky, darkens and brightens with day/night cycle
  rectMode(CORNER);
  fill((((sin(frameCount*.01)+1)/2)*0), (((sin(frameCount*.01)+1)/2)*100), (((sin(frameCount*.01)+1)/2)*170)+60);
  rect(0, 0, 400, 115);

  //sun, moves in an ellipse in and out of frame
  fill(255, 255, 255, ((((sin(frameCount*.01)+1)/2)*555)-255));
  ellipse(((cos(frameCount*.01)+1)/2)*500, (((sin(frameCount*.01)+1)/2)*250)-200, (((sin(frameCount*.01)+1)/2))*100, (((sin(frameCount*.01)+1)/2)*100));

  //sun occluders, creates shutter effect at noon
  fill((((sin(frameCount*.01)+1)/2)*0), (((sin(frameCount*.01)+1)/2)*100), (((sin(frameCount*.01)+1)/2)*170)+60);
  rectMode(CENTER);
  rect(200, 75, 400, 7);
  rect(200, 85, 400, 6);
  rect(200, 95, 400, 5);
  rect(200, 103, 400, 4);

  //headlights, strobe faintly and turn off during day

  //headlights left
  noStroke();
  fill(255, 255, 160, ((sin(-frameCount*.01)+1)/2)*90-55);
  ellipse(127, 196, (sin(frameCount*.02)*5)+55, (sin(frameCount*.02)*5)+55);
  ellipse(127, 196, (sin(frameCount*.02)*3)+40, (sin(frameCount*.02)*3)+40);
  ellipse(127, 196, (sin(frameCount*.02)*3)+30, (sin(frameCount*.02)*3)+30);

  //left headlight beams
  fill(255, 255, 160, ((sin(-frameCount*.01)+1)/2)*90-55);
  quad(50, 135, 219, 135, 128, 204, 120, 205);

  //headlights right
  noStroke();
  fill(255, 255, 160, ((sin(-frameCount*.01)+1)/2)*90-55);
  ellipse(400-127, 196, (sin(frameCount*.05)*5)+55, (sin(frameCount*.05)*5)+55);
  ellipse(400-127, 196, (sin(frameCount*.05)*3)+40, (sin(frameCount*.05)*3)+40);
  ellipse(400-127, 196, (sin(frameCount*.05)*3)+30, (sin(frameCount*.05)*3)+30);

  //right headlight beams 
  fill(255, 255, 160, ((sin(-frameCount*.01)+1)/2)*90-55);
  quad(400-50, 135, 400-219, 135, 400-128, 204, 400-120, 205);

  //headlight projection onto road
  ellipse(200, 190, 200, 40);
  fill(255, 255, 160, ((sin(-frameCount*.01)+1)/2)*90-55);
  quad(218, 135, 400-218, 135, 400-271, 205, 271, 205);
  triangle(200, 150, 400-273, 205, 273, 205);

  //car, static in middle of display

  //base shape
  noStroke();
  fill(182, 10, 10);
  quad(0, 350, 400, 350, 280, 195, 120, 195);

  quad(0, 350, 400, 350, 400, 400, 0, 400);

  //middle of hood
  fill(218, 10, 10);
  quad(125, 250, 200, 250, 200, 180, 168, 184);

  fill(194, 9, 9);
  quad(400-125, 250, 400-200, 250, 400-200, 180, 400-168, 184);

  //outer headlight countour
  fill(230, 21, 21);
  quad(122, 185, 127, 183, 82, 255, 68, 255);

  fill(194, 9, 9);
  quad(400-122, 185, 400-127, 183, 400-82, 255, 400-68, 255);

  //inner headlight contour
  fill(194, 9, 9);
  quad(127, 183, 131, 184, 95, 255, 78, 255);

  fill(230, 21, 21);
  quad(400-127, 183, 400-131, 184, 400-95, 255, 400-78, 255);

  //inner headlight wall
  fill(167, 12, 12);
  quad(131, 184, 137, 194, 102, 255, 92, 255);

  fill(218, 11, 11);
  quad(400-131, 184, 400-137, 194, 400-102, 255, 400-92, 255);

  //hood opening seams
  stroke(1);
  fill(10);
  line(105, 255, 140, 196);

  stroke(1);
  fill(10);
  line(400-105, 255, 400-140, 196);

  //center hood shaded bevels
  noStroke();
  fill(230, 21, 21);
  quad(167, 185, 171, 183, 127, 255, 123, 255);

  fill(189, 9, 9);
  quad(400-167, 185, 400-171, 183, 400-127, 255, 400-123, 255);

  //light grey plastic dashboard
  fill(65);
  quad(82, 255, 200, 250, 200, 257, 82, 257);
  quad(400-82, 255, 400-200, 250, 400-200, 257, 400-82, 257);

  //brown wood dash
  fill(145, 95, 50);
  quad(82, 257, 400-82, 257, 400-65, 267, 65, 267);

  //dark grey plastic dashboard
  fill(120);
  quad(64, 266, 400-64, 266, 400-64, 274, 64, 274);

  //windshield side frame
  fill(0);
  quad(40, 157, 53, 149, 83, 256, 58, 265);
  triangle(83, 256, 58, 265, 66, 268);

  quad(400-40, 157, 400-53, 149, 400-83, 256, 400-58, 265);
  triangle(400-83, 256, 400-58, 265, 400-66, 268);

  //side mirrors
  fill(116);
  quad(0, 258, 38, 256, 38, 289, 0, 292);
  triangle(13, 271, 46, 264, 46, 278);
  fill(152);
  quad(0, 261, 36, 258, 36, 287, 0, 290);

  fill(116);
  quad(400-0, 258, 400-38, 256, 400-38, 289, 400-0, 292);
  triangle(400-13, 271, 400-46, 264, 400-46, 278);
  fill(152);
  quad(400-0, 261, 400-36, 258, 400-36, 287, 400-0, 290);

  //wood windshield support brace
  fill(113, 73, 39);
  triangle(40, 305, 50, 207, 66, 275);
  triangle(400-40, 305, 400-50, 207, 400-66, 275);

  //metal windshield support brace
  stroke(180, 10, 10);
  strokeWeight(3);
  line(40, 305, 50, 207);
  line(400-40, 305, 400-50, 207);

  //top windshield frame
  noStroke();
  fill(0);
  quad(53, 149, 200, 135, 200, 146, 53, 160);
  quad(400-53, 149, 400-200, 135, 400-200, 146, 400-53, 160);

  //rearview mirror
  rectMode(CENTER);
  fill(0);
  rect(200, 160, 62, 17, 5, 5, 5, 5);
  fill(155);
  rect(200, 160, 60, 15, 5, 5, 5, 5);

  //reflection on rearview mirror, uses sawtooth function to approximate looping linear left-right movement
  noStroke();
  fill(255, 255, 255, 100);
  //sawtooth function for reflections movement
  quad(
    //x1,y1
    ((sin(frameCount*.1) - sin(2*frameCount*.1)/2.0 + sin(3*frameCount*.1)/3.0 - sin(4*frameCount*.1)/4.0 + sin(5*frameCount*.1)/5.0 - sin(6*frameCount*.1)/6.0 + 
    sin(7*frameCount*.1)/7.0 - sin(8*frameCount*.1)/8.0 + sin(9*frameCount*.1)/9.0 - sin(10*frameCount*.1)/10.0 + sin(11*frameCount*.1)/11 - sin(12*frameCount*.1)/12.0 + 
    sin(13*frameCount*.1)/13.0 - sin(14*frameCount*.1)/14.0 + sin(15*frameCount*.1)/15.0) - sin(16*frameCount*.1)/16.0 + sin(17*frameCount*.1)/17.0 - sin(18*frameCount*.1)/18.0 + 
    sin(19*frameCount*.1)/19.0 - sin(20*frameCount*.1)/20.0 + sin(21*frameCount*.1)/21.0 - sin(22*frameCount*.1)/22.0 + sin(23*frameCount*.1)/23.0 - sin(24*frameCount*.1)/24.0 + 
    sin(25*frameCount*.1)/25.0)*12.0+199, 167, 
    //x2,y2
    ((sin(frameCount*.1) - sin(2*frameCount*.1)/2.0 + sin(3*frameCount*.1)/3.0 - sin(4*frameCount*.1)/4.0 + sin(5*frameCount*.1)/5.0 - sin(6*frameCount*.1)/6.0 + 
    sin(7*frameCount*.1)/7.0 - sin(8*frameCount*.1)/8.0 + sin(9*frameCount*.1)/9.0 - sin(10*frameCount*.1)/10.0 + sin(11*frameCount*.1)/11 - sin(12*frameCount*.1)/12.0 + 
    sin(13*frameCount*.1)/13.0 - sin(14*frameCount*.1)/14.0 + sin(15*frameCount*.1)/15.0) - sin(16*frameCount*.1)/16.0 + sin(17*frameCount*.1)/17.0 - sin(18*frameCount*.1)/18.0 + 
    sin(19*frameCount*.1)/19.0 - sin(20*frameCount*.1)/20.0 + sin(21*frameCount*.1)/21.0 - sin(22*frameCount*.1)/22.0 + sin(23*frameCount*.1)/23.0 - sin(24*frameCount*.1)/24.0 + 
    sin(25*frameCount*.1)/25.0)*12.0+199+8, 167, 
    //x3,y3
    ((sin(frameCount*.1) - sin(2*frameCount*.1)/2.0 + sin(3*frameCount*.1)/3.0 - sin(4*frameCount*.1)/4.0 + sin(5*frameCount*.1)/5.0 - sin(6*frameCount*.1)/6.0 + 
    sin(7*frameCount*.1)/7.0 - sin(8*frameCount*.1)/8.0 + sin(9*frameCount*.1)/9.0 - sin(10*frameCount*.1)/10.0 + sin(11*frameCount*.1)/11 - sin(12*frameCount*.1)/12.0 + 
    sin(13*frameCount*.1)/13.0 - sin(14*frameCount*.1)/14.0 + sin(15*frameCount*.1)/15.0) - sin(16*frameCount*.1)/16.0 + sin(17*frameCount*.1)/17.0 - sin(18*frameCount*.1)/18.0 + 
    sin(19*frameCount*.1)/19.0 - sin(20*frameCount*.1)/20.0 + sin(21*frameCount*.1)/21.0 - sin(22*frameCount*.1)/22.0 + sin(23*frameCount*.1)/23.0 - sin(24*frameCount*.1)/24.0 + 
    sin(25*frameCount*.1)/25.0)*12.0+199, 153, 
    //x4,y4
    ((sin(frameCount*.1) - sin(2*frameCount*.1)/2.0 + sin(3*frameCount*.1)/3.0 - sin(4*frameCount*.1)/4.0 + sin(5*frameCount*.1)/5.0 - sin(6*frameCount*.1)/6.0 + 
    sin(7*frameCount*.1)/7.0 - sin(8*frameCount*.1)/8.0 + sin(9*frameCount*.1)/9.0 - sin(10*frameCount*.1)/10.0 + sin(11*frameCount*.1)/11 - sin(12*frameCount*.1)/12.0 + 
    sin(13*frameCount*.1)/13.0 - sin(14*frameCount*.1)/14.0 + sin(15*frameCount*.1)/15.0) - sin(16*frameCount*.1)/16.0 + sin(17*frameCount*.1)/17.0 - sin(18*frameCount*.1)/18.0 + 
    sin(19*frameCount*.1)/19.0 - sin(20*frameCount*.1)/20.0 + sin(21*frameCount*.1)/21.0 - sin(22*frameCount*.1)/22.0 + sin(23*frameCount*.1)/23.0 - sin(24*frameCount*.1)/24.0 + 
    sin(25*frameCount*.1)/25.0)*12.0+199-8, 153);

  //occluder for mirror reflection, turns on to prevent flicker that arises from sawtooth funtion's inaccuracies
  fill(155, 155, 155, -(cos(frameCount*.1)*900.0)-900.0+255.0);
  rect(200, 160, 60, 15, 5, 5, 5, 5);

  //floor mats
  fill(44);
  quad(54, 300, 400-54, 300, 400-39, 400, 39, 400);

  //door upholstery
  fill(182, 171, 164);
  stroke(2);
  quad(54, 300, 52, 379, 45, 440, -25, 412);
  quad(400-54, 300, 400-52, 379, 400-45, 440, 400+25, 412);

  //car seats
  rectMode(CORNERS);
  fill(182, 171, 164);
  rect(58, 385, 200, 423, 200, 385, 58, 423);
  rect(400-58, 385, 400-200, 423, 400-200, 385, 400-58, 423);

  //front face of dashboard
  noStroke();
  fill(93);
  quad(71, 273, 400-71, 273, 400-47, 306, 47, 306);
  rectMode(CORNERS);
  rect(47, 306, 400-47, 334, 0, 0, 50, 50);

  //gas pedal
  fill(70);
  quad(155, 342, 168, 342, 165, 371, 152, 371);

  //brake pedal
  fill(70);
  quad(109, 348, 143, 348, 140, 360, 108, 360);

  //guage housing
  rectMode(CORNERS);
  stroke(0);
  strokeWeight(1);
  fill(70);
  rect(73, 293, 198, 330, 50, 0, 0, 0);

  //spedometer
  fill(70);
  ellipse(181, 312, 21, 21);

  //steering wheel rim
  stroke(0);
  strokeWeight(2);
  noFill();
  ellipseMode(CENTER);
  ellipse(126, 312, 75, 75);

  stroke(113, 73, 39);
  strokeWeight(4);
  noFill();
  ellipseMode(CENTER);
  ellipse(126, 312, 72, 72);

  stroke(0);
  strokeWeight(1);
  noFill();
  ellipseMode(CENTER);
  ellipse(126, 312, 69, 69);

  //steering wheel center, rotates with mouseX
  fill(0);
  stroke(0);
  strokeWeight(10);
  line(
    (cos(((mouseX/400.0)*(PI*1.0)))*35)+126, 
    (sin(((mouseX/400.0)*(PI*1.0)))*35)+312, 
    (cos(((mouseX/400.0)*(PI*1.0)-PI))*35)+126, 
    (sin(((mouseX/400.0)*(PI*1.0)-PI))*35)+312);
  noStroke();
  ellipse(126, 312, 32, 32);

  //glovebox
  stroke(0);
  strokeWeight(1);
  line(225, 300, 225, 333);
  line(225, 300, 348, 300);
  rectMode(CORNERS);
  rect(236, 307, 262, 315);
  fill(52);
  rect(252, 307, 262, 315);

  //glovebox shading
  noStroke();
  fill(70);
  rect(225, 325, 353, 329);
  fill(60);
  rect(225, 329, 353, 335, 0, 0, 50, 0);

  //passenger ac
  rectMode(CORNERS);
  stroke(0);
  fill(43);
  rect(234, 281, 324, 300);
  fill(113, 73, 39);
  rect(234+20, 281, 324-20, 300);

  //driver ac
  rectMode(CORNERS);
  fill(47);
  rect(55, 308, 72, 330);

  //doorhandles
  fill(70);
  quad(39, 356, 39, 375, 34, 388, 34, 368);
  quad(400-39, 356, 400-39, 375, 400-34, 388, 400-34, 368);
  line(34, 388, 27, 400);
  line(400-34, 388, 400-27, 400);


  //shadow effect, darkens bottom during night
  rectMode(CORNER);
  fill(0, 0, 0, ((sin(-frameCount*.01)+1)/2)*55);
  rect(0, 115, 400, 375);

  //lighting effect, brightens bottom during day
  fill(255, 255, 255, ((sin(frameCount*.01)+1)/2)*50);
  rect(0, 115, 400, 375);

  //stars, x translation during night, shimmering outline that varies by group, alpha reduced to 0 during day 
  noStroke();
  fill(255, 255, 255, (((sin(-frameCount*.01)+1)/2)*255)-70);
  stroke(255, 255, 255, ((sin(-frameCount*.01)+1)/2)*123);
  //group 1
  strokeWeight(((sin(-frameCount*.1)+1)/2)*2.0);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+50, 50, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+123, 68, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+345, 12, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+390, 24, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+245, 50, 2, 2);
  //group 2
  strokeWeight(((sin(-frameCount*.85)+1)/2)*2.0);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+190, 7, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+300, 79, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+90, 26, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+78, 76, 2, 2);
  strokeWeight(((sin(-frameCount*.93)+1)/2)*2.0);
  //group3
  ellipse((-(cos(frameCount*.01)+1)/2)*20+178, 77, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+234, 107, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+363, 95, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+5, 82, 2, 2);
  ellipse((-(cos(frameCount*.01)+1)/2)*20+4, 8, 2, 2);
}

void mouseClicked() {
  //tells viewer distance travelled upon mouse click, they are going 100km/h
  println("you have travelled", frameCount*4, "kilometers.", frameCount/480, "day(s) have passed.");
}

void keyPressed() {
  //tells viewer how cool they are upon key press
  println("Synthwave music is playing on the radio, you are wearing cool sunglasses.");
}