/* * Alec Jacobson * */ import java.awt.*; import java.util.LinkedList; /** * * @author ajx */ public class HW01 extends BufferedApplet{ int w, h;//bounds of applet //centers of eyes int right_eye_x = 400; int right_eye_y = 100; int left_eye_x = 200; int left_eye_y = 100; //rough center of fly int fly_x, fly_y; //Direction of fly's spiral path //1 -> CCW, -1 -> CW int dir = 1; //not really depth, but effect of mouseUp double depth = 0; //time counter int counter = 0; //bounds of entire head int head_left, head_right, head_top, head_bottom; //number of trailing points on fly's path int MAX_TRAIL = 25; //biggest ring of eye final int EYE_MAX = 120; //thickness of eyebrow final int EYEBROW_THICK = 40; //roughthickness of hair final int HAIR_THICK = 40; //nose dimmensions final int NOSE_H = 100; final int NOSE_W = 75; //boolean for if the fly is stopped boolean stopped = false; //queue for trail of points along fly path LinkedList trail = new LinkedList(); public void render(Graphics g) { if (true||w == 0) {//true here for resizing appletviewer w = bounds().width; h = bounds().height; right_eye_y = h-EYE_MAX/2-10; left_eye_y = h-EYE_MAX/2-10; } //clear the screen g.setColor(Color.blue); g.fillRect(0, 0, w, h); g.setColor(Color.BLACK); //draw human drawHead(g); drawEyebrows(g,right_eye_x,right_eye_y); drawEyebrows(g,left_eye_x,left_eye_y); drawEye(g,right_eye_x,right_eye_y); drawEye(g,left_eye_x,left_eye_y); //if the fly is moving then update path if(!stopped){ fly_x += ( (int)(Math.random()*3)-1)*10; fly_y += ( (int)(Math.random()*3)-1)*10; //System.out.println((int)(Math.random()*3)-1); fly_x += dir*(int)(30*Math.sin(0.2*counter)); fly_y += (int)(30*Math.cos(0.2*counter)); } //draw the fly and path drawFly(g,fly_x,fly_y); animating = true; //update time counter++; //decrease effect of mouseUp depth *= 0.9; } public void drawHead(Graphics g){ int x = left_eye_x+EYE_MAX/2; int y = (right_eye_y+left_eye_y)/2; int width = 3*(EYE_MAX); int height = (int)(2.5*EYE_MAX); int round = 150; //draw hair Color oldColor = g.getColor(); g.setColor(Color.RED); g.fillRect(x-width/2-(int)(HAIR_THICK*.75),y-height/2-(int)(HAIR_THICK*.75),width+HAIR_THICK,height+HAIR_THICK); g.setColor(oldColor); g.drawRect(x-width/2-(int)(HAIR_THICK*.75),y-height/2-(int)(HAIR_THICK*.75),width+HAIR_THICK,height+HAIR_THICK); //define EYE_MAX of entire head for later use head_left = x-width/2-(int)(HAIR_THICK*.75); head_right = x-width/2-(int)(HAIR_THICK*.75)+width+HAIR_THICK; head_top = y-height/2-(int)(HAIR_THICK*.75); head_bottom = h; //draw face g.setColor(Color.ORANGE); g.fillRoundRect(x-width/2,y-height/2,width,height,round,round); g.setColor(oldColor); g.drawRoundRect(x-width/2,y-height/2,width,height,round,round); //draw nose x = (right_eye_x+left_eye_x)/2; y = left_eye_y+EYE_MAX/2; g.setColor(Color.ORANGE); g.fillOval(x-NOSE_W/2,y-NOSE_H/2,NOSE_W,NOSE_H); g.setColor(oldColor); g.drawOval(x-NOSE_W/2,y-NOSE_H/2,NOSE_W,NOSE_H); g.setColor(Color.ORANGE); g.fillOval(x-NOSE_W/2-10,y-NOSE_H/2-10,NOSE_W,NOSE_H); //ear // g.setColor(Color.ORANGE); // g.fillOval(left_eye_x-EYE_MAX-EAR_W/2,left_eye_y+EYE_MAX/4-EAR_H/2,EAR_W,EAR_H); // g.setColor(oldColor); // g.drawOval(left_eye_x-EYE_MAX-EAR_W/2,left_eye_y+EYE_MAX/4-EAR_H/2,EAR_W,EAR_H); // g.setColor(Color.ORANGE); // g.fillOval(left_eye_x-EYE_MAX-EAR_W/2+10,left_eye_y+EYE_MAX/4-EAR_H/2+10,EAR_W,EAR_H); // // g.setColor(oldColor); } public void drawEyebrows(Graphics g, int x, int y){ int w = (int)(5*depth)+5; int[] px = {x-EYE_MAX/2,x-EYE_MAX/4,x,x+EYE_MAX/4,x+EYE_MAX/2, x+EYE_MAX/2,x+EYE_MAX/4,x,x-EYE_MAX/4,x-EYE_MAX/2}; int[] py = {y-EYE_MAX/2-(int)(EYEBROW_THICK*.75),y-EYE_MAX/2-EYEBROW_THICK-(int)(w*.75),y-EYE_MAX/2-EYEBROW_THICK-w,y-EYE_MAX/2-EYEBROW_THICK-(int)(w*.75),y-EYE_MAX/2-(int)(EYEBROW_THICK*.75), y-EYE_MAX/2, y-EYE_MAX/2-(int)(w*.75), y-EYE_MAX/2-w, y-EYE_MAX/2-(int)(w*.75),y-EYE_MAX/2}; int n = px.length; Color oldColor = g.getColor(); g.setColor(Color.RED); g.fillPolygon(px, py, n); g.setColor(oldColor); g.drawPolygon(px, py, n); } public void drawFly(Graphics g, int x, int y){ //draw the actual fly //body and head g.setColor(Color.BLACK); g.fillOval(x-20,y-10,40,20); g.fillOval(x-30,y-15,25,25); //wings g.setColor(Color.WHITE); g.fillOval(x-5,y-20,40,10); g.fillOval(x-10,y-15,40,10); g.setColor(Color.BLACK); g.drawOval(x-5,y-20,40,10); g.drawOval(x-10,y-15,40,10); //legs g.drawLine(x, y, x+20, y+20); g.drawLine(x, y, x+10, y+20); g.drawLine(x, y, x+5, y+20); g.drawLine(x, y, x, y+20); g.drawLine(x, y, x-5, y+20); g.drawLine(x, y, x-10, y+20); g.drawLine(x, y, x-20, y+20); //only kill points if trail is too big while(trail.size()>MAX_TRAIL){ trail.removeFirst(); } //add new point on path trail.addLast(new Point(fly_x,fly_y)); //draw existing points for(Point p:trail){ g.drawRect(p.x, p.y, 2, 2); } //update whether fly is stopped or moving //infrequently stop on head but not on top of eyes if(!stopped&& fly_xhead_left&&fly_yhead_top&& Math.sqrt((fly_x-left_eye_x)*(fly_x-left_eye_x)+(fly_y-left_eye_y)*(fly_y-left_eye_y))>EYE_MAX/2&& Math.sqrt((fly_x-right_eye_x)*(fly_x-right_eye_x)+(fly_y-right_eye_y)*(fly_y-right_eye_y))>EYE_MAX/2){ stopped = Math.random()>0.95; } //infrequently get going after stopping if(stopped){ stopped = Math.random()>0.01; } } public void drawEye(Graphics g, int x, int y){ //circles of the eye int[] sizes = {110,109,100,60,53,51,50,30}; //{30,50,51,53,60,100,109,110}; int pupil = 20; double uvec_x = getUnitFlyX(x,y); double uvec_y = getUnitFlyY(x,y); //System.out.println("Unit:\t<"+uvec_x+","+uvec_y+">"); //get some colors ready Color line = g.getColor(); Color scalera = Color.WHITE; Color iris_1 = Color.GREEN; Color iris_2 = Color.CYAN; //draw outline of eye g.setColor(scalera); g.fillOval(x-EYE_MAX/2, y-EYE_MAX/2, EYE_MAX,EYE_MAX); g.setColor(line); g.drawOval(x-EYE_MAX/2, y-EYE_MAX/2, EYE_MAX,EYE_MAX); //draw eyeball with proper effect of mouseUp double d = 1; for(int val: sizes){ int off_x = (int)(uvec_x*d); int off_y = (int)(uvec_y*d); if((double)val/(double)EYE_MAX<0.45){ g.setColor(iris_2); }else if((double)val/(double)EYE_MAX<0.75){ g.setColor(iris_1); }else{ g.setColor(scalera); } g.fillOval(x-val/2+off_x, y-val/2+off_y,val, val); g.setColor(line); g.drawOval(x-val/2+off_x, y-val/2+off_y,val, val); //more effect on inner circles d += 2+depth; } //draw pupil..same as other but filled in black int off_x = (int)(uvec_x*d); int off_y = (int)(uvec_y*d); g.fillOval(x-pupil/2+off_x, y-pupil/2+off_y, pupil,pupil); } /** * Get x component of unit vector from given x,y to fly * @param x * @param y * @return */ public double getUnitFlyX(int x, int y){ //vector to mouse double vec_x = fly_x-x; double vec_y = fly_y-y; double vec_norm = Math.sqrt(vec_x*vec_x+vec_y*vec_y); //unit vector to mouse double uvec_x = (fly_x-x)/vec_norm; double uvec_y = (fly_y-y)/vec_norm; return uvec_x; } /** * Get y component of unit vector from given x,y to fly * @param x * @param y * @return */ public double getUnitFlyY(int x, int y){ //vector to mouse double vec_x = fly_x-x; double vec_y = fly_y-y; double vec_norm = Math.sqrt(vec_x*vec_x+vec_y*vec_y); //unit vector to mouse double uvec_x = (fly_x-x)/vec_norm; double uvec_y = (fly_y-y)/vec_norm; return uvec_y; } public boolean mouseUp(Event e, int x, int y) { //mouseUp cause effect on eyes and eyebrows depth = 10.0; //also kicks up fly if stopped stopped = false; //also changes direction of spiral dir *= -1; damage = true; return true; } public boolean mouseDrag(Event e, int x, int y) { //mouse can drag fly to new location fly_x = x; fly_y = y; trail.clear(); stopped = true; damage = true; return true; } public boolean keyUp(Event e, int key) { switch (key) { case ' ': //space cause effect on eyes and eyebrows depth = 10.0; //also kicks up fly if stopped stopped = false; //also changes direction of spiral dir *= -1; break; case '+': MAX_TRAIL += 30; break; case '-': MAX_TRAIL -= 5; if (MAX_TRAIL<=0) MAX_TRAIL=1; break; } damage = true; return true; } } // (x,y) point class...just made the queue easier to code class Point{ int x; int y; public Point(int u, int v){ x=u; y=v; } }