/************************************************************ /* Author: Dr. Parson /* Creation Date: 2/21/2018 /* Due Date: 3/9/2018 /* Course: CSC120 Intro. to Creative Graphical Coding /* Professor Name: Dr. Parson /* Assignment: 2. /* Sketch name: avatarFunction2018 /* Purpose: Add a display() function and a loop to assignment 1. /* http://faculty.kutztown.edu/parson/fall2017/avatar2017NoModulo.txt /* is the assignment 1 starting point for this code. /* http://faculty.kutztown.edu/parson/spring2018/avatarFunction2018.txt /* has a copy of this sketch. *********************************************************/ // Modeled after photo http://www.gradprofiles.com/images/kutzlib.gif // These variables can hold integers, i.e., whole numbers with no fractional parts. int backgroundColor = 0 ; // Bounces from 1 to 254 to 1 using backgroundColorSpeed. // backgroundColor flickers if I let it go < 0 or > 255, hence I am using range 1..254. int backgroundColorSpeed = 1 ; // Starts in a positve direction. int avatarX = 0 ; // Move the avatar left-right-left in cycles. int avatarXspeed = 1 ; // Initially move to the right. int legX = 0 ; // How far is leg from X endpoint, range -10 + 10. int legXspeed = 1 ; // go to 10, then reverse direction. // Also use 2 * lexG offset to wiggle arms up & down (in Y coordinate); // HIGHPOINTS OF MINE (not requirements): // 1. Use semi-transparency of grass and sky to pass through background light to dark, // which also cycles smoothly from day-night-day. backgroundColor used for both // background gray scale and tree red/green mix. void setup() { size(750, 500); background(backgroundColor); } void draw() { // Make the background cyclic through light & dark, no jumps. backgroundColor = backgroundColor + backgroundColorSpeed ; if (backgroundColor < 1 || backgroundColor > 254) { // It went out of range backgroundColorSpeed = - backgroundColorSpeed ; // reverse direction } background(backgroundColor); // PAINT BACKGROUND SCENERY. rectMode(CENTER); // Semi-transparent green grass uses the background's light-to-dark. fill(0, 100, 0, 100); rect(width/2, height*3/4, width, height/2); // Semi-transparent blue sky uses the background's light-to-dark. fill(0, 0, 100, 100); rect(width/2, height/4, width, height/2); // Create the building (library). fill(108, 57, 15); rect(width/2, height/4, width/2, height/3); rect(width/2, height/2-35, width, height/3); fill(100); rect(width/2, height/2, width*2/3, height/5); // Create poles leading into library, make one foreground later. strokeWeight(4); stroke(200); ellipseMode(CENTER); fill(255); line(width/3, height/3, width/3, height*2/3); line(width*2/3, height/3, width*2/3, height*2/3); arc(width/3, height/3, 40, 40, PI, 2*PI, PIE); arc(width*2/3, height/3, 40, 40, PI, 2*PI, PIE); // Make the next poll be the same distance further. int newx = (width/3 - width/4) + width/3 ; // Do the same for its height -- shrink by same amount. int newy = (height/3 - height/4) + height/3 ; line(newx, newy, newx, height-newy); line(width-newx, newy, width-newx, height-newy); arc(newx, newy, 30, 30, PI, 2*PI, PIE); arc(width-newx, newy, 30, 30, PI, 2*PI, PIE); // DRAW THE AVATAR // The following function call has the same drawing effect // as assignment 1's avatar code, which has now moved down // into the function. THIS IS STEP 4 IN ASSIGNMENT 2. display(avatarX, height/2, 1.0, legX); // My loop at the borrom of draw() displays 2 stationary avatars. // AVATAR MOVE CODE MUST STAY IN draw(): // get ready for movement in next frame. // STEP 6 requires using an "if", done here. avatarX = avatarX + avatarXspeed ; if (avatarX < -10 || avatarX > width+10) { // It went out of range avatarXspeed = - avatarXspeed ; // reverse direction } legX = legX + legXspeed ; if (legX < -10 || legX > 10) { // It went out of range legXspeed = - legXspeed ; // reverse direction } /* move this to foreground */ // Create last pole leading into library. strokeWeight(6); stroke(200); ellipseMode(CENTER); fill(255); line(width/4, height/4, width/4, height*3/4); line(width*3/4, height/4, width*3/4, height*3/4); arc(width/4, height/4, 50, 50, PI, 2*PI, PIE); arc(width*3/4, height/4, 50, 50, PI, 2*PI, PIE); // fill(0, 100, 0) ; // dark green for some foreground trees fill(255 - abs(backgroundColor - 255), abs(backgroundColor - 255), 0); noStroke(); triangle(0, 0, 100, 180, 0, 180); triangle(0, 135, 100, 315, 0, 315); triangle(0, 270, 100, 450, 0, 450); fill(85, 73, 25); rectMode(CORNER); rect(0, 450, 20, height-450); // Put another tree on the right. // fill(0, 100, 0) ; // dark green for some foreground trees fill(255 - abs(backgroundColor - 255), abs(backgroundColor - 255), 0); noStroke(); triangle(width, 0, width-100, 180, width, 180); triangle(width, 135, width-100, 315, width, 315); triangle(width, 270, width-100, 450, width, 450); fill(85, 73, 25); rectMode(CORNER); rect(width-20, 450, width, height-450); // I SATISFIED STEPS 5 (more avatars) & 7 (a loop) // IN THIS LOOP. YOU CAN USE A LOOP TO DRAW SOMETHING // OTHER THAN THE AVATAR, FOR EXAMPLE SOME PART OF // SCENERY. I USED IT TO DRAW AVATARS. YOU MUST DRAW AT // LEAST A SECOND AVATAR FOR STEP 5, BUT THE AVATAR // DOES NOT HAVE TO BE PART OF THE LOOP. for (int clonex = width/4 ; clonex < width ; clonex += width/2) { // start clonex at width/4; adding width/2 comes back into the // loop only a second time. display(clonex, height/8, 0.5, 16*legX); } /* DEMO A LOOP THAT DOES NOT INVOLVE THE AVATAR: fill(0,75,0); // dark green bushes noStroke(); int bushx = 50 ; while (bushx < width-50) { ellipse(bushx, height - 30, 30, 20); bushx += 50 ; } */ } // THE display() FUNCTION DISPLAYS AN AVATAR BASED SOLELY ON ITS PARAMETER VALUES. // DO NOT USE ANY GLOBAL VARIABLES IN display(). // STEP 1: Write your version of the next line: void display(int avx, int avy, float avscale, int avwiggle) { // avy is this avatar's x location; avy is its y location; // float avscale is its scaling factor; avwiggle wiggles body parts. // STEPS 2 & 3: Move the avatar push, translate, scale, and pop code here, // but keep the avatar move code up in draw(). // USE GEOMETRIC TRANSFORMS TO POSITION THE AVATAR // All avatar-specific coordinates are relative to the translated center of the avatar. pushMatrix(); // After popmatrix() we can draw the foregorund scenery. translate(avx, avy); // This is where to center the avatar. scale(avscale); noStroke(); fill(240, 150, 150); ellipse(0, 0, 50, 40); // head quad(-5, 0, 5, 0, 10, 0+40, -10, 0+40); // neck fill(0); // professor gown ellipse(0, 0+60, 40, 80); // torso stroke(0); // stick arms & legs strokeWeight(8); line(0, 0+60, -20+avwiggle, 0+120); // left leg line(0, 0+60, 20-avwiggle, 0+120); // right leg strokeWeight(5); line(0, 0+60, -40, 0+20-2*avwiggle); // left arm line(0, 0+60, 40, 0+20-2*avwiggle); // right arm strokeWeight(2); fill(0, 50, 255); ellipse(-10, 0-5, 10, 10); // avatar's right side of glasses ellipse(10, 0-5, 10, 10); // avatar's right side of glasses line(-5, 0-5, 5, 0-5); // glasses connector line(-15, 0-5, -22, 0-8); // left earpiece line(15, 0-5, 22, 0-8); // right earpiece fill(0); ellipse(0, 0+1, 5, 5); // nose arc(0, 0+10, 20, 10, 0, PI); // mouth quad(-30, 0-15, 30, 0-15, 15, 0-30, -35, 0-30); popMatrix(); // Move popMatrix from draw() to bottom of display(). }