/* * Alec Jacobson * */ import java.awt.*; import java.util.LinkedList; /** * * @author aj */ public class HW02 extends BufferedApplet{ int w, h;//bounds of applet final double MAX_BODY_SX = 2;//max body scale x final double MIN_UPPER = -Math.PI/8; final double MAX_UPPER = Math.PI/2; final double MAX_LOWER = Math. PI/4; final double MIN_LOWER = -Math.PI/2; final double EAT_DIST = 20; int[][] FULL = {{ -256, -58}, { -256, -46}, { -256, -45}, { -255, -34}, { -255, -32}, { -255, -24}, { -255, -17}, { -255, -10}, { -256, 59}, { -257, 68}, { -257, 70}, { -257, 72}, { -257, 74}, { -257, 75}, { -257, 77}, { -257, 78}, { -220, 81}, { -218, 81}, { -216, 81}, { -215, 81}, { -214, 81}, { -212, 81}, { -213, 53}, { -213, 49}, { -214, 39}, { -214, 38}, { -213, 38}, { -204, 38}, { -202, 38}, { -180, 37}, { -180, 35}, { -180, 34}, { -180, 33}, { -180, 4}, { -180, 2}, { -213, 2}, { -214, 2}, { -214, 1}, { -214, 0}, { -214, -12}, { -213, -19}, { -213, -23}, { -213, -31}, { -211, -55}, { -200, -55}, { -198, -54}, { -168, -51}, { -130, -49}, { -128, -49}, { -127, -49}, { -127, -50}, { -127, -51}, { -127, -71}, { -126, -75}, { -125, -77}, { -125, -78}, { -117, -79}, { -116, -79}, { -113, -79}, { -111, -77}, { -109, -75}, { -109, -74}, { -107, -68}, { -107, -66}, { -106, -24}, { -107, -21}, { -107, -15}, { -108, -8}, { -108, -7}, { -94, 66}, { -89, 68}, { -85, 68}, { -72, 68}, { -55, 64}, { -52, 63}, { -44, 59}, { -41, 58}, { -31, 57}, { -27, 55}, { -1, 13}, { 0, 4}, { 0, -1}, { 0, -7}, { 0, -8}, { 0, -16}, { 1, -19}, { 1, -26}, { 2, -47}, { 2, -52}, { -6, -69}, { -14, -71}, { -18, -73}, { -23, -73}, { -26, -73}, { -33, -54}, { -33, -47}, { -34, -42}, { -34, -39}, { -34, -38}, { -36, -33}, { -36, -32}, { -37, -4}, { -44, 17}, { -50, 25}, { -50, 27}, { -51, 27}, { -52, 27}, { -55, 27}, { -73, 16}, { -76, 10}, { -76, 8}, { -79, 1}, { -81, -7}, { -74, -54}, { -64, -69}, { -63, -70}, { -62, -70}, { -58, -71}, { -37, -71}, { 2, -74}, { 8, -74}, { 9, -74}, { 20, -74}, { 21, -74}, { 34, -71}, { 35, -70}, { 48, 3}, { 52, 52}, { 52, 74}, { 70, 71}, { 72, 71}, { 75, 70}, { 76, 70}, { 77, 70}, { 133, 65}, { 133, 64}, { 131, 45}, { 131, 44}, { 131, 43}, { 128, 43}, { 100, 45}, { 96, 45}, { 89, 47}, { 85, 47}, { 84, 47}, { 72, 17}, { 72, 16}, { 72, 14}, { 73, 10}, { 75, -18}, { 75, -37}, { 75, -38}, { 75, -39}, { 75, -41}, { 75, -42}, { 76, -49}, { 76, -50}, { 76, -52}, { 76, -59}, { 76, -60}, { 136, -69}, { 140, -69}, { 142, -69}, { 153, -66}, { 154, -62}, { 154, -60}, { 157, -44}, { 157, -35}, { 158, -29}, { 161, 33}, { 163, 45}, { 163, 48}, { 165, 69}, { 165, 70}, { 189, 70}, { 212, 66}, { 228, 65}, { 233, 65}, { 235, 62}, { 234, 49}, { 233, 43}, { 233, 38}, { 232, 38}, { 232, 37}, { 229, 37}, { 190, 41}, { 189, 41}, { 189, 37}, { 189, 36}, { 189, 25}, { 183, -21}, { 177, -44}, { 173, -59}, { 173, -62}, { 172, -62}, { 152, -62}, { 147, -62}, { 123, -61}, { 113, -61}, { 98, -60}, { 88, -59}, { 60, -56}, { -2, -60}, { -13, -61}, { -34, -63}, { -37, -64}, { -116, -70}, { -117, -70}, { -140, -70}, { -151, -70}, { -213, -74}, { -218, -74}, { -220, -73}, { -221, -73}, { -229, -71}, { -230, -71}, { -237, -71}, { -241, -71}, { -244, -71}, { -248, -72}, { -250, -72}}; int[][] mouth = {{ 16, 0}, { 15, 0}, { 14, -1}, { 13, -1}, { 11, -3}, { 10, -4}, { 8, -5}, { 7, -5}, { 6, -5}, { 5, -5}, { -3, -6}, { -4, -6}, { -8, -7}, { -12, -7}, { -15, -7}, { -21, -2}, { -21, -1}, { -21, 1}, { -20, 2}, { -19, 3}, { -18, 3}, { -12, 5}, { -11, 5}, { -6, 5}, { -6, 6}, { 8, 8}, { 10, 8}, { 11, 8}, { 12, 8}, { 18, 6}, { 18, 5}, { 19, 4}, { 19, 3}}; int[][] head = { {12,-67}, {11,-67}, {10,-67}, {6,-68}, {5,-68}, {-15,-67}, {-16,-66}, {-19,-64}, {-34,-55}, {-35,-54}, {-36,-52}, {-36,-51}, {-37,-47}, {-41,-38}, {-41,-37}, {-41,-36}, {-42,-34}, {-49,-19}, {-53,-12}, {-55,-10}, {-56,-6}, {-57,-4}, {-60,5}, {-60,10}, {-60,11}, {-57,16}, {-55,18}, {-54,19}, {-53,21}, {-48,27}, {-46,30}, {-45,31}, {-44,32}, {-30,41}, {-29,41}, {-24,43}, {-8,48}, {2,52}, {14,56}, {20,56}, {26,55}, {32,49}, {33,48}, {34,47}, {34,46}, {49,28}, {57,17}, {62,10}, {63,9}, {76,-9}, {76,-10}, {78,-15}, {78,-16}, {78,-18}, {78,-21}, {74,-29}, {61,-42}, {57,-48}, {46,-58}, {46,-59}, {45,-59}, {31,-59}, {26,-60}, {25,-61}, {24,-61}, {23,-61}}; //lefteye int[][] left_eye = { {-10,-29}, {-11,-29}, {-12,-28}, {-13,-23}, {-13,-18}, {-13,-5}, {-13,-2}, {-14,6}, {-5,18}, {-4,19}, {0,19}, {2,19}, {3,19}, {5,18}, {7,18}, {11,14}, {13,14}, {15,12}, {18,6}, {19,-1}, {20,-5}, {20,-7}, {19,-14}, {19,-15}, {18,-16}, {17,-16}, {16,-17}, {10,-22}, {5,-27}, {5,-28}, {2,-28}, {-1,-28}, {-3,-28}, {-4,-29}, {-5,-29}, {-6,-29}}; //right eye int[][] right_eye = { {-3,-29}, {-4,-27}, {-6,-26}, {-7,-24}, {-8,-23}, {-9,-23}, {-12,-17}, {-13,-16}, {-14,-16}, {-16,-11}, {-17,-4}, {-17,-1}, {-17,1}, {-16,9}, {-9,14}, {-9,15}, {-4,16}, {1,20}, {6,22}, {6,23}, {10,23}, {21,19}, {25,16}, {27,14}, {27,13}, {34,4}, {35,4}, {36,2}, {36,-1}, {36,-4}, {34,-7}, {31,-9}, {30,-11}, {29,-12}, {24,-16}, {22,-18}, {21,-19}, {20,-20}, {13,-25}, {9,-28}, {8,-28}, {7,-29}, {5,-30}, {4,-30}, {3,-30}, {2,-30}}; //scalera int[][] scalera = { {-7,-6}, {-5,8}, {8,9}, {14,0}, {13,-11}, {2,-15}}; //pupil int[][] pupil = { {-2,-4}, {2,4}, {7,-3}}; //nose int[][] nose = { {-4,-8}, {-11,2}, {-7,8}, {2,9}, {10,7}, {9,-4}}; //ear int[][] ear = { {-11,15}, {-15,-6}, {-11,-16}, {-4,-20}, {9,-18}, {18,-6}, {18,7}, {-1,17}}; //theigh int[][] leg = { {-18,-33}, {-26,-23}, {-41,-10}, {-51,3}, {-59,16}, {-68,41}, {-75,46}, {-78,53}, {-70,70}, {-37,88}, {-17,79}, {-1,66}, {29,50}, {45,30}, {49,6}, {45,-19}, {35,-40}, {14,-43}, {6,-42}}; //foot int[][] foot = { {23,24}, {23,1}, {22,-19}, {8,-45}, {-15,-53}, {-28,-50}, {-34,-45}, {-40,-32}, {-35,-1}, {-9,32}, {8,32}}; //hand int[][] hand = { {18,7}, {18,-6}, {18,-23}, {5,-32}, {3,-27}, {3,-20}, {-5,-23}, {-15,-28}, {-23,-21}, {-28,-2}, {-22,3}, {-13,11}, {8,22}, {13,18}}; int[][] leaf = {{ 5, 101}, { 6, 76}, { 6, 45}, { 5, 19}, { 5, -10}, { 0, -34}, { -9, -65}, { -12, -75}, { -13, -72}, { -11, -59}, { -13, -39}, { -8, -25}, { -1, -11}, { 7, 2}, { 7, 21}, { 7, 35}, { 7, 52}, { 7, 61}, { 9, 75}, { 11, 108}}; int[][] body = { //body {0,-200}, {20,-190}, {40,-180}, {50,-100}, {70,-80}, {90,-60}, {100,0}, {80,30}, {40,50}, {0,60}, {-45,60}, {-80,30}, {-75,0}, {-70,-40}, {-60,-80}, {-55,-110}, {-55,-150}, {-40,-180} }; int[][] lower = { //lower arm {0,-20}, {20,-15}, {30,0}, {20,30}, {0,50}, {-30,60}, {-50,70}, {-60,50}, {-30,10}}; Matrix3x3 bear_m = new Matrix3x3(); //thetas double upper_th = Math.PI/4; //rotation angle of upper arm double lower_th = -Math.PI/2; //rotation angle of lower arm double head_th = 0; //rotation angle of head arm double hand_th = -Math.PI/8; double foot_th = Math.PI/2; double leaf_th = 0; //scales double full_s = 0;//scale to shrink feet double foot_s = 0.6;//scale to shrink feet double pupils_s = 1.;//scale to shrink pupil double body_sx = 1.;//scale in x direction of body double mouth_sx = .5;//scale in x direction of body double mouth_sy = .5;//scale in x direction of body //hinges and offsets int[] bod2upr = {50,-160};//hing offset from upper to lower int[] bod2upl = {-40,-160};//hing offset from upper to lower int[] bod2legr = {50,20};//hing offset from upper to lower int[] bod2legl = {-40,20};//hing offset from upper to lower int[] leg2foot = {-60,90}; int[] up2low = {50,60};//hing offset from upper to lower int[] low2hand = {-70,60};//lower arm to hand int[] hand2leaf = {-20,0};//hand to leaf(ves) int[] bod2head = {-50,-150};//body to head int[] head2nose = {-10,20};//head to nose int[] head2mouth = {0,40};//head to mouth int[] head2eyer = {20,-10}; int[] head2eyel = {-20,-10}; int[] head2earr = {40,-50}; int[] head2earl = {-40,-50}; int[][] upper = { //upper arm {0,-30}, {30,-20}, {60,0}, {70,40}, {60,80}, {50,81}, {-10,50}, {-30,20}, {-35,-20}}; double vec1[] = new double[2]; double vec2[] = new double[2]; double mouthLoc[] = new double[2]; double foodLoc[] = new double[2]; int x,y = -Integer.MAX_VALUE; boolean uninit = true; int counter = 0; //weights double foot_w = 0.0; double pupils_w = 0.0; double mouth_w = 0.0; double leaf_w = 0.0; double head_w = 0.0; //some frequencies double head_f = 2; double foot_f = 0.5; double pupils_f = 5; double mouth_f = 3; double leaf_f = 0.5; //some amplitutes double head_a = Math.PI/33; double foot_a = Math.PI/32; double pupils_a = 1; double mouth_a = 1.5; double leaf_a = Math.PI/64; double curBodyMax = 1;//one for now boolean eating = false; boolean full = false; public void initVals(){ mouthLoc = new double[2]; foodLoc = new double[2]; mouth_sx = .5;//scale in x direction of body mouth_sy = .5;//scale in x direction of body //thetas upper_th = Math.PI/4; //rotation angle of upper arm lower_th = -Math.PI/2; //rotation angle of lower arm head_th = 0; //rotation angle of head arm hand_th = -Math.PI/8; foot_th = Math.PI/2; leaf_th = 0; //scales full_s = 0;//scale to shrink feet foot_s = 0.6;//scale to shrink feet pupils_s = 1.;//scale to shrink pupil body_sx = 1.;//scale in x direction of body mouth_sx = .5;//scale in x direction of body mouth_sy = .5;//scale in x direction of body //weights foot_w = 0.0; pupils_w = 0.0; mouth_w = 0.0; leaf_w = 0.0; head_w = 0.0; //some frequencies head_f = 2; foot_f = 0.5; pupils_f = 5; mouth_f = 3; leaf_f = 0.5; //some amplitutes head_a = Math.PI/33; foot_a = Math.PI/32; pupils_a = 1; mouth_a = 1.5; leaf_a = Math.PI/64; curBodyMax = 1;//one for now eating = false; full = false; } public void render(Graphics g) { if (true||w == 0) {//true here for resizing appletviewer w = bounds().width; h = bounds().height; if(uninit){ x = 2*w/3;//default locations y= 2*h/3; initVals(); uninit = false; } } //clear the screen g.setColor(Color.CYAN); g.fillRect(0, 0, w, h/3); g.setColor(Color.GREEN); g.fillRect(0, h/3, w, h); g.setColor(Color.BLACK); update(); drawBear(g); animating = true; //set animating to true; counter++;//increase time step } public void drawBear(Graphics g){ //move bear with mouse bear_m.identity(); bear_m.translate(x,y); //draw left arm //draw upper arm Matrix3x3 upper_m = bear_m.getCopy(); upper_m.translate(bod2upl[0], bod2upl[1]); upper_m.rotate(upper_th*0.5-Math.PI/8); g.setColor(Color.BLACK); drawShape(g, upper, upper_m); //draw lower arm Matrix3x3 lower_m = upper_m.getCopy(); lower_m.translate(up2low[0],up2low[1]); lower_m.rotate(lower_th*0.5); g.setColor(Color.BLACK); drawShape(g, lower, lower_m); //draw hand Matrix3x3 hand_m = lower_m.getCopy(); hand_m.translate(low2hand[0],low2hand[1]); hand_m.rotate(hand_th); g.setColor(Color.WHITE); drawShape(g, hand, hand_m); //draw left leg Matrix3x3 leg_m = bear_m.getCopy(); leg_m.translate(bod2legl[0]*body_sx, bod2legl[1]); g.setColor(Color.BLACK); drawShape(g, leg, leg_m); //left foot leg_m.translate(leg2foot[0], leg2foot[1]); leg_m.scale(foot_s,foot_s); leg_m.rotate(foot_th); g.setColor(Color.WHITE); drawShape(g, leg, leg_m); //draw body Matrix3x3 body_m = bear_m.getCopy(); body_m.scale(body_sx,1.0); g.setColor(Color.WHITE); drawShape(g, body, body_m); //draw head Matrix3x3 head_m = bear_m.getCopy(); head_m.translate(bod2head[0], bod2head[1]); head_m.rotate(head_th); g.setColor(Color.WHITE); drawShape(g, head, head_m); //draw eyes //draw left path Matrix3x3 face_m = head_m.getCopy(); face_m.translate(head2eyel[0], head2eyel[1]); g.setColor(Color.BLACK); drawShape(g, left_eye, face_m); g.setColor(Color.WHITE); drawShape(g, scalera, face_m); face_m.scale(pupils_s,pupils_s); g.setColor(Color.BLACK); drawShape(g, pupil, face_m); //draw riught patch face_m = head_m.getCopy(); face_m.translate(head2eyer[0], head2eyer[1]); g.setColor(Color.BLACK); drawShape(g, left_eye, face_m); g.setColor(Color.WHITE); drawShape(g, scalera, face_m); face_m.scale(pupils_s,pupils_s); g.setColor(Color.BLACK); drawShape(g, pupil, face_m); //draw ears //draw left ear face_m = head_m.getCopy(); face_m.translate(head2earl[0], head2earl[1]); g.setColor(Color.BLACK); drawShape(g, ear, face_m); //draw right ear face_m = head_m.getCopy(); face_m.translate(head2earr[0], head2earr[1]); g.setColor(Color.BLACK); drawShape(g, ear, face_m); //draw nose face_m = head_m.getCopy(); face_m.translate(head2nose[0], head2nose[1]); g.setColor(Color.BLACK); drawShape(g,nose, face_m); //draw mouth face_m = head_m.getCopy(); face_m.translate(head2mouth[0], head2mouth[1]); face_m.scale(mouth_sx,mouth_sy); g.setColor(Color.RED); drawShape(g,mouth, face_m); //save mouth loc before leaving face_m.transform(0.0, 0.0, mouthLoc); // System.out.println ("mouht: <"+mouthLoc[0]+","+mouthLoc[1]+">"); //draw right arm //draw upper arm upper_m = bear_m.getCopy(); upper_m.translate(bod2upr[0], bod2upr[1]); upper_m.rotate(upper_th); g.setColor(Color.BLACK); drawShape(g, upper, upper_m); //draw lower arm lower_m = upper_m.getCopy(); lower_m.translate(up2low[0],up2low[1]); lower_m.rotate(lower_th); g.setColor(Color.BLACK); drawShape(g, lower, lower_m); //draw hand hand_m = lower_m.getCopy(); hand_m.translate(low2hand[0],low2hand[1]); hand_m.rotate(hand_th); //draw leaf before finishing hand Matrix3x3 leaf_m = hand_m.getCopy(); leaf_m.translate(hand2leaf[0],hand2leaf[1]); leaf_m.rotate(leaf_th); g.setColor(new Color(100,255,100)); drawShape(g, leaf, leaf_m); //save mouth loc before leaving leaf_m.transform(0.0, 0.0, foodLoc); // System.out.println ("food: <"+foodLoc[0]+","+foodLoc[1]+">"); // System.out.println (); //another leaf_m.translate(1,-3); leaf_m.rotate(leaf_th-Math.PI*.9); g.setColor(new Color(100,255,100)); drawShape(g, leaf, leaf_m); //another leaf_m.translate(-4,5); leaf_m.rotate(leaf_th+Math.PI/32); g.setColor(new Color(100,255,100)); drawShape(g, leaf, leaf_m); g.setColor(Color.WHITE); drawShape(g, hand, hand_m); //draw right leg leg_m = bear_m.getCopy(); leg_m.translate(bod2legr[0]*body_sx, bod2legr[1]); g.setColor(Color.BLACK); drawShape(g, leg, leg_m); //right foot leg_m.translate(leg2foot[0], leg2foot[1]); leg_m.scale(foot_s,foot_s); leg_m.rotate(foot_th); g.setColor(Color.WHITE); drawShape(g, leg, leg_m); if(eating && full){ Matrix3x3 full_m = bear_m.getCopy(); full_m.scale(full_s,full_s); g.setColor(Color.YELLOW); drawShape(g, FULL, full_m); } } public void update(){ if(eating && full){ full_s *=0.95; if(full_s<=0.1){ eating = false; full = true; full_s =1; } }else if(eating){ //System.out.println("Eating..."+eating+"curbodyMax:\t"+curBodyMax+"body_sx"+body_sx); if(curBodyMax<= body_sx){ curBodyMax = body_sx*1.2; if(curBodyMax> MAX_BODY_SX){ curBodyMax = MAX_BODY_SX;//cap on size full=true; full_s =1; } foot_w = foot_a; head_w = head_a; leaf_w = leaf_a; mouth_w = mouth_a; pupils_w = pupils_a; } //decrease weights foot_w *=0.95; head_w *=0.95; leaf_w *=0.95; mouth_w *=0.95; pupils_w *=0.95; //shake feet foot_th += (foot_w*Math.sin(foot_f*counter)); //shake head head_th += (head_w*Math.sin(head_f*counter)); //shake branch leaf_th += (leaf_w*Math.sin(leaf_f*counter)); //open and close mouth mouth_sx -= (mouth_w*Math.cos(mouth_f*counter)); mouth_sy -= 0.5*(mouth_w*Math.cos(mouth_f*counter)); pupils_s -= (pupils_w*Math.sin(pupils_f*counter)); if(mouth_sx> 1.5) mouth_sx = 1.5;//cap on size if(mouth_sy> 1.5) mouth_sy = 1.5;//cap on size if(pupils_s> 2) pupils_s = 2;//cap on size //enlargen body //haven't increase max yet then do it body_sx *= 1.001; if(curBodyMax <= body_sx ){ eating = false; body_sx = curBodyMax; } //put down arms? }else{ double curDist = Math.sqrt( (mouthLoc[0]-foodLoc[0])* (mouthLoc[0]-foodLoc[0])- (mouthLoc[1]-foodLoc[1])* (mouthLoc[1]-foodLoc[1]) ); eating = curDist MAX_LOWER) lower_th = MAX_LOWER;//cap on size break; case Event.LEFT: case '_': lower_th-=Math.PI/32; if(lower_th< MIN_LOWER) lower_th = MIN_LOWER;//cap on size break; case Event.UP: case '=': upper_th+=Math.PI/32; if(upper_th> MAX_UPPER) upper_th = MAX_UPPER;//cap on size break; case Event.DOWN: case '-': upper_th-=Math.PI/32; if(upper_th< MIN_UPPER) upper_th = MIN_UPPER;//cap on size 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; } }