/*CSE142, Spring 2000 Homework 4 David Rozsnyai BD */ #include "gp142.h" #include #include #include /* is included so the current time can be accessed * to initialize the random number generator. If you don't * use random numbers (and you don't have to) you can either * ignore this #include or delete it.*/ /* Logical constants */ #define TRUE 1 #define FALSE 0 /*For many of the GP142 functions, a line width of zero means to fill the shape being drawn. The constant FILL is used in function calls when a solid shape is desired.*/ #define FILL 0 /* Symbolic constants. Change as needed. */ /* Menu buttons: */ /* Top-left coordinates of button palette */ #define MENU_TOP (GP142_YMAX - 5) #define MENU_LEFT (-GP142_XMAX + 5) /* Height and width of buttons in pixels */ #define BUTTON_HEIGHT 25 #define BUTTON_WIDTH 100 /* Number of buttons */ #define NUM_BUTTON 5 /* Possible locations of mouse clicks: */ /* Mouse click in some button */ #define BUTTON_CLICK 1 /* Mouse click elsewhere */ #define OTHER_CLICK 0 /* Coordinates of objects in the drawing */ /* y-coordinate of the top of the ground in the landscape */ #define HORIZON (- 2 * (GP142_YMAX / 10)) /* Other constants pertaining to objects in the scene */ #define MOON_RADIUS 20 #define MOON_FULLNESS 2.5 #define MAX_STAR_RADIUS 4 #define MAX_BUG_SIZE 10 #define MAX_BUGS 5 #define MAX_FLOWERS 15 #define MAX_STARS 10 #define MAX_SNOW 75 /*************FUNCTION PROTOTYPES*******************************************/ void initialize_random_numbers();/* Initialize random number generator. [Ignore or */ /* remove if your program doesn't use random numbers.] */ void snowfall(int *snow_y); /* Makes snow flakes fall down the screen */ void init_moon(int *moon_x, int *moon_y);/* Initializes the moon parameters */ void draw_boat(int boat_x, int boat_y, int boat_len, int boat_mast);/*Draw a single boat*/ void move_boat(int *boat_x, int *boat_y, int *mover, int *boatsize, int *boatsize2); /* Moves the boat around the lake and changes the size accordingto its position on the lake */ void draw_bug(int bug_x, int bug_y, int bug_size); /* Draw a single bug (buttefly) */ void mult_bug(int bugx[], int bugy[], int bug_size, int bug_num); /* Draws more bug up to max bugs */ void change_colors(int *petal_color, int *flower_color, int petalcol[], int flowcol[]); /* Change flower field colors */ void multflow(int flow_x[],int flow_y[],int treenumber,int petal_radius,int flower_radius, int petalcol[], int flowcol[]); /* Draws multiple flowers */ void clouds(int cloud_x, int cloud_y); /* Draws a cloud in the sky */ void move_clouds(int *cloud_x, int *cloud_x2); /* Moves cloud across sky */ void waves(int wavex, int wavey); /* Draws waves in the lake */ void movewaves(int *wavex, int *wavenum, int *waveway); /* Makes waves move in lake */ /* Draw the background, including the moon at coordinates moon_x and moon_y, the stars */ /* the tree, the flower(s), the boat, and the bug(s) */ void draw_landscape(int moon_x, int moon_y, int moonfullx, int star_x, int star_y, int star_radius, int star_color, int star2_x, int star2_y, int star2_radius, int star2_color, int flower_x, int flower_y, int flower_radius, int flower_color, int petal_radius, int petal_color, int boat_x, int boat_y, int boat_len, int boat_mast, int bug_x, int bug_y, int bug_size, int treenumber, int snowx[], int snowy[], int flow_x[], int flow_y[], int petalcol[], int flowcol[], int flowers, int bugx[], int bugy[], int bug_num, int dayornite,int starx[], int stary[], int wavex, int wavey, int cloud_x, int cloud_y, int cloud_x2); void snowcaps(void); /* Draws snow on top of mountains in winter */ void blink_star(int *star_radius, int *star_color); /* Make stars blink */ void move_bug(int *bug_x, int *bug_y, int *bug_size, int bugx[], int bugy[]); /* Move bug(s) */ void move_moon(int *moon_x,int *moon_y,int *moonfullx, /* moves moon across screen and */ int *moonmover,int *daytotal,int *dayornite); /* changes between nite and day */ void draw_buttons(void); /* Draw buttons */ /* Return kind of mouse click (in a button, etc.) */ int classify_mouse_click(int mouse_x, int mouse_y); /* Process button click at location x, y. React appropriately, depending on the requested event */ void handle_button(int x, int y, int *petal_color, int *flower_color, int *tree, int *treecount, int *wind, int *windon, int petalcol[], int flowcol[],int *flowerpressed ,int *flowers, int *bugpressed, int *bug_num); /* Display error message if internal error is detected. */ void something_is_wrong (void); /* Draws different treetop for each season */ void treetop(int treenumber, int treecol1, int treecol2, int treecol3); /************************************ MAIN *****************************************/ /* Main program contents: - Major program variables that persist throughout execution - Event loop that processes GP142 events until the user quits, and updates variables and redraws the window as needed. */ int main(void){ /* Event handling and buttons: */ int quit; /* = "user has selected quit" */ int event; /* the most recent GP142 event */ char key_pressed; /* last keyboard character from key event */ int mouse_x, mouse_y; /* x and y coordinates of latest mouse event*/ int click_kind; /* kind of mouse click (button, etc.) */ int n = 0; /* used for counting loops */ /* Information about the moon and stars: */ int moon_x, moon_y; /* screen x and y coordinates */ int moonfullx, moonmover=0; /* makes moon become full */ int daytotal=0, dayornite=0; /* changes between day and nite */ int star_x, star_y; /* screen x and y coordinates */ int star_radius, star_color; /* radius and color of a star */ int star2_x, star2_y; /* screen x and y coordinates */ int star2_radius, star2_color; /* radius & color of other star */ int starx[MAX_STARS]; int stary[MAX_STARS]; /* arrays used for star coord.*/ /* Information about the flowers */ int flower_x, flower_y; /* screen x and y coordinates */ int flower_radius, petal_radius;/* flower and petal radii */ int flower_color, petal_color; /* flower and petal colors */ int flow_x[MAX_FLOWERS]; int flow_y[MAX_FLOWERS]; /* arrays for flower placement */ int petalcol[MAX_FLOWERS]; int flowcol[MAX_FLOWERS]; /* array for flower colors */ int flowerpressed=0 ,flowers=0; /* adds and subtracts flowers */ /* Information about the tree */ int treenumber =0, treecount =0;/* used to cycle through trees */ /* Info for snow */ int snowx[MAX_SNOW], snowy[MAX_SNOW];/* arrays used to draw snow*/ /* Info for waves */ int wavex = -GP142_XMAX + 25; /* coord. for first wave and */ int wavey = HORIZON - 30; /* then used to make waves go */ int wavenum =0, waveway =0; /* back and forth in water */ /* Information about the boat */ int boat_x, boat_y; /* screen x and y coordinates */ int boat_len, boat_mast; /* length of the boat and height of the mast */ int mover=0; /* counter to move the boat */ int windcount=0, windnum=0; /* determines if the wind is on */ /* Information about the bug(s) */ int bug_x, bug_y, bug_size; /* screen x and y coordinates and size of the bug */ int bugx[MAX_BUGS], bugy[MAX_BUGS]; /* arrays used to draw extra bugs */ int bugpressed=0, bug_num=0; /* counters determine how many extra bugs to draw */ /* Info for clouds */ int cloud_x = 150; /* initial place for first cloud */ int cloud_x2 = -125; /* initial place for other cloud */ int cloud_y = 190; /* y coord. for clouds */ initialize_random_numbers(); /* Initialize random number generator */ /* Initialize graphics package, clear the window, */ /* turn logging off, and start animation. */ GP142_open(); GP142_logging(LOG_OFF); GP142_clear(); GP142_animate(ANI_RUN); /* set initial location of the moon */ init_moon(&moon_x, &moon_y); moonfullx = moon_x; /* set initial location of the stars */ star_x = GP142_XMAX - 200; star_y = GP142_YMAX - 90; star_radius = 3; star_color = WHITE; star2_x = -GP142_XMAX + 150; star2_y = GP142_YMAX - 80; star2_radius = 2; star2_color = YELLOW; /* set initial flower parameters */ flower_x = GP142_XMAX / 3; flower_y = -GP142_YMAX + 40; flower_radius = 2; flower_color = YELLOW; petal_radius = 8; petal_color = RED; /* set conditions for stars */ while(n=0 && treenumber <2) treetop(treenumber,treecol[0],treecol[0],treecol[0]); else treetop(treenumber,treecol[1],treecol[2],treecol[3]); /* Draw boat */ draw_boat(boat_x, boat_y, boat_len, boat_mast); /* Draw butteflies */ draw_bug(bug_x, bug_y, bug_size); mult_bug(bugx, bugy,bug_size,bug_num); /* Draw snow and icicles on bugs and flowers */ if (treenumber==5){ snowcaps(); n=0; while(n < bug_num){ GP142_triangleXY(11,bugx[n] + 7,bugy[n] -5, bugx[n] + 5,bugy[n] -5, bugx[n] + 6, bugy[n] - 17,FILL); GP142_triangleXY(11,bugx[n] - 6,bugy[n] -6, bugx[n] - 8,bugy[n] -6, bugx[n] -7, bugy[n] - 14,FILL); n++;} n=0; while(n < flowers){ GP142_triangleXY(11,flow_x[n] + 6,flow_y[n] -5, flow_x[n] + 4,flow_y[n] -5, flow_x[n] + 5,flow_y[n] - 17,FILL); GP142_triangleXY(11,flow_x[n] -7,flow_y[n] -2, flow_x[n] -5,flow_y[n] -3, flow_x[n] -6,flow_y[n] - 12,FILL); n++;} n=0; GP142_triangleXY(11,bug_x + 7,bug_y -5, bug_x + 5,bug_y -5, bug_x + 6, bug_y - 17,FILL); GP142_triangleXY(11,bug_x - 6,bug_y -6, bug_x - 8,bug_y -6, bug_x -7, bug_y - 14,FILL); GP142_triangleXY(11,flower_x + 6,flower_y -5, flower_x + 4,flower_y -5, flower_x + 5,flower_y - 17,FILL); GP142_triangleXY(11,flower_x -7,flower_y -2, flower_x -5,flower_y -3, flower_x -6,flower_y - 12,FILL); n=0; while(n<76){ snowy[n] = snowy[n] - rand()%10 + 1; n++;} n=0; while (n<76){ GP142_circleXY(WHITE,snowx[n],snowy[n],3); if (snowy[n] < -250){ snowy[n] = GP142_YMAX;} n++;}} /* Draw multiple flowers */ multflow(flow_x,flow_y,flowers,petal_radius,flower_radius,petalcol,flowcol); } /*end draw_landscape */ /***************************************************************************** BUTTONS AND MOUSE CLICKS *****************************************************************************/ /* Draws the buttons */ void draw_buttons(void) { int i; int text_offset = MENU_LEFT+10; /* offset of button text in button */ int font_size = 12; /* size of button text */ /* draw rectangles for each button */ for(i = 0; i < NUM_BUTTON; i++) { GP142_rectangleXY(BLACK, MENU_LEFT, MENU_TOP - i * BUTTON_HEIGHT, MENU_LEFT + BUTTON_WIDTH, MENU_TOP - (i + 1) * BUTTON_HEIGHT, 1); } /* display button text */ i = MENU_TOP - (BUTTON_HEIGHT/2) - (font_size/2); GP142_printfXY(BLACK, text_offset, i, font_size, "Change Colors"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Alter Tree Tops"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Simulate Wind"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Add Flowers"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Add Bugs"); } /* Classify mouse click at (mouse_x,mouse_y) and return kind */ int classify_mouse_click(int mouse_x, int mouse_y) { if ((mouse_x > MENU_LEFT) && (mouse_x < MENU_LEFT + BUTTON_WIDTH) && (mouse_y < MENU_TOP) && (mouse_y > (MENU_TOP - NUM_BUTTON * BUTTON_HEIGHT))) return BUTTON_CLICK; else return OTHER_CLICK; } /* Process button click at location x, y. React appropriately: */ /* i.e. change colors, tree tops, etc. if requested. */ void handle_button(int x, int y, int *petal_color, int *flower_color, int *tree, int *treecount ,int *wind, int *windon, int petalcol[], int flowcol[], int *flowerpressed ,int *flowers, int *bugpressed, int *bug_num) { int buttonNum; /* number of selected button */ int over15=0, over5=0; /* Complain if x coordinate couldn't be inside a button */ if (x < MENU_LEFT || x > MENU_LEFT + BUTTON_WIDTH) { something_is_wrong(); return; } /* Convert y coordinate to button number from top. */ buttonNum = (MENU_TOP - y)/BUTTON_HEIGHT; switch(buttonNum) { case 0: /* change flower field colors */ change_colors(petal_color, flower_color, petalcol, flowcol); break; case 1: /* changes tree through seasons */ *treecount= *treecount + 1; *tree= *treecount % 6; break; case 2: /* turns wind on or off */ *wind = *wind + 1; *windon = *wind % 2; break; case 3: /* adds or subtracts flowers */ *flowerpressed = *flowerpressed + 1; if(*flowerpressed % 31 < 16 && *flowerpressed % 31 > 0){ *flowers = *flowerpressed % 31;} else if (*flowerpressed % 31 == 0){ *flowers = 0;} else{over15 = 2 * (*flowerpressed % 31 -15); *flowers = *flowerpressed % 31 - over15;} break; case 4: /* adds or subtracts bugs */ *bugpressed = *bugpressed + 1; if(*bugpressed % 11 < 6 && *bugpressed % 11 > 0){ *bug_num = *bugpressed % 11;} else if (*bugpressed % 11 == 0){ *bug_num = 0;} else{over5 = 2 * (*bugpressed % 11 - 5); *bug_num = *bugpressed % 11 - over5;} break; default: /*Bad news if this is ever reached! */ GP142_animate(ANI_HALT); something_is_wrong(); break; } } /***************************************************************************** ANIMATED OBJECTS *****************************************************************************/ /* shifts clouds across screen when wind is on */ void move_clouds(int *cloud_x, int *cloud_x2){ *cloud_x = *cloud_x - 2; *cloud_x2 = *cloud_x2 - 2; if (*cloud_x < -400){*cloud_x = GP142_XMAX + 20;} if (*cloud_x2 < -400){*cloud_x2 = GP142_XMAX + 20;}} /* draws waves in water */ void waves(int wavex, int wavey){int n=0;int y=0; while(n<232){ GP142_ovalXY(BLACK, wavex + n, wavey - 1 + y, wavex + n + 20, wavey - 13 + y, FILL); GP142_ovalXY(BLUE, wavex + n, wavey + y, wavex + n + 20, wavey - 12 + y, FILL); n = n + 21;} y=12; n=-16; while(n<297){ GP142_ovalXY(BLACK, wavex + n, wavey - 1 + y, wavex + n + 20, wavey - 13 + y, FILL); GP142_ovalXY(BLUE, wavex + n, wavey + y, wavex + n + 20, wavey - 12 + y, FILL); n = n + 21;} y=24; n=2; while(n<255){ GP142_ovalXY(BLACK, wavex + n, wavey - 1 + y, wavex + n + 20, wavey - 13 + y, FILL); GP142_ovalXY(BLUE, wavex + n, wavey + y, wavex + n + 20, wavey - 12 + y, FILL); n = n + 21;}} /* makes waves move back and forth with wind on */ void movewaves(int *wavex, int *wavenum, int *waveway){ if(*waveway<8){*wavex = *wavex + 2;} else{*wavex = *wavex - 2;} *wavenum = *wavenum + 1; *waveway = *wavenum % 16;} /* makes snowflakes fall */ void snowfall(int *snow_y){ *snow_y = *snow_y -2;} /* moves boat in a circle and makes it bigger and smaller */ void move_boat(int *boat_x, int *boat_y, int *mover, int *boatsize, int *boatsize2){ *mover=*mover +1; if(*boat_x <= GP142_XMAX / 3 - 20 && *boat_x > GP142_XMAX / 3 -188 && *boat_y >= HORIZON -24){ *boat_x = *boat_x -7; *boat_y = *boat_y +1; if (*mover % 4 == 3){ *boatsize = *boatsize - 1; *boatsize2 = *boatsize2 - 2;}} if(*boat_x <= GP142_XMAX / 3 -188 && *boat_x > GP142_XMAX / 3 -356 && *boat_y > HORIZON -24){ *boat_x = *boat_x -7; *boat_y = *boat_y -1; if (*mover % 4 == 3){ *boatsize = *boatsize + 1; *boatsize2 = *boatsize2 + 2;}} if(*boat_x < GP142_XMAX / 3 -188 && *boat_x >= GP142_XMAX / 3 -356 && *boat_y <= HORIZON -24){ *boat_x = *boat_x +7; *boat_y = *boat_y -1; if (*mover % 4 == 3){ *boatsize = *boatsize + 1; *boatsize2 = *boatsize2 + 2;}} if(*boat_x >= GP142_XMAX / 3 -188 && *boat_x < GP142_XMAX / 3 -20 && *boat_y < HORIZON -24){ *boat_x = *boat_x +7; *boat_y = *boat_y +1; if (*mover % 4 == 3){ *boatsize = *boatsize - 1; *boatsize2 = *boatsize2 - 2;}} } /* Make the stars blink */ void blink_star(int *star_radius, int *star_color) { *star_radius = rand() % MAX_STAR_RADIUS + 1; *star_color = rand() % MAX_COLORS; } /* Update moon coordinates moon_x, moon_y by one tick */ void move_moon(int *moon_x, int *moon_y, int *moonfullx, int *moonmover, int *daytotal, int *dayornite) { /* Move the moon to the left. If it reaches the edge, move it */ /* to the other side and down a bit. */ (*moon_x) --; if(*moonmover % 25 != 24) (*moonfullx) --; if (*moon_x < -GP142_XMAX -30) { *moon_x = - *moon_x; *moonfullx = *moon_x - 4; *moon_y = GP142_YMAX - 105; *daytotal = *daytotal + 1; *dayornite = *daytotal % 2; } if (*moon_x % 4 == 1 || *moon_x % 4 == -1){ if (*moon_x > 0){*moon_y = *moon_y + 1;} if (*moon_x <= 0){*moon_y = *moon_y - 1;}} *moonmover = *moonmover + 1; } /* Make the bug(s) move around and flutter */ void move_bug(int *bug_x, int *bug_y, int *bug_size, int bugx[], int bugy[]) {int n=0; while(n<5){ bugx[n]= bugx[n] + rand() % 3 -1; bugy[n]= bugy[n] + rand() % 3 -1; n++;} *bug_x = *bug_x + rand() % 3 - 1; *bug_y = *bug_y + rand() % 3 - 1; *bug_size = MAX_BUG_SIZE/2 + rand() % MAX_BUG_SIZE/2; draw_bug(*bug_x, *bug_y, *bug_size); } /**********************************OTHER******************************** /* Initialize random number generator */ /* [Ignore or delete if your program */ /* doesn't user random numbers.] */ void initialize_random_numbers() { time_t t; /* current time */ srand (time(&t));} /* Display error message if internal error is detected. */ void something_is_wrong (void) { GP142_printfXY (RED, 0, 0, 16, "Program error!");}