/* * CSE142, Spring 2000 * Homework 4 * Idyllic landscape animation STARTER PROGRAM * * */ #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 #define UNFILLED 1 /* * 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_BUTTONS 3 /* Possible locations of mouse clicks: */ /* Mouse click in some button */ #define BUTTON_CLICK 1 /* Mouse click elsewhere */ #define OTHER_CLICK 0 /* Max number of objects */ #define MAX_STARS 20 #define MAX_FLAKES 200 #define MAX_FLOWERS 16 #define MAX_BUGS (MAX_FLOWERS / 2) /* 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 MOONSUN_RADIUS 20 #define MOON_FULLNESS 2.5 #define MAX_STAR_RADIUS 4 #define MAX_BUG_SIZE 10 #define BOW_RADIUS 150 /* radius of the rainbow */ #define BAND_W 6 /* width of each color of the rainbow */ /* seasons and time-of-day */ #define SPRING 0 #define SUMMER 1 #define FALL 3 #define WINTER 4 #define NIGHT 0 #define DAY 1 /***************************************************************************** FUNCTION PROTOTYPES *****************************************************************************/ /* Initialize random number generator. [Ignore or */ /* remove if your program doesn't use random numbers.] */ void initialize_random_numbers(); /* Initializes the moon parameters */ void init_moonsun(int *moonsun_x, int *moonsun_y); /* Draw a single boat */ void draw_boat(int boat_x, int boat_y, int boat_len, int boat_mast); /* Draw a single bug (butterfly) */ void draw_bug(int bug_x[MAX_BUGS], int bug_y[MAX_BUGS], int bug_size[MAX_BUGS], int bug_color[MAX_BUGS]); /* Change flower and butterfly colors */ void change_colors(int petal_color[MAX_FLOWERS], int flower_color[MAX_FLOWERS], int bug_color[MAX_BUGS]); /* Draw the background, including the moon at coordinates moon_x and moon_y, the stars */ /* the tree, the flower(s), the boat, the bug(s), and the initial season. */ void draw_landscape(int * season, int * light, int moonsun_x, int moonsun_y, int star_x[MAX_STARS], int star_y[MAX_STARS], int star_radius[MAX_STARS], int star_color[MAX_STARS], int flower_x[MAX_FLOWERS], int flower_y[MAX_FLOWERS], int flower_radius[MAX_FLOWERS], int flower_color[MAX_FLOWERS], int petal_radius[MAX_FLOWERS], int petal_color[MAX_FLOWERS], int boat_x, int boat_y, int boat_len, int boat_mast, int bug_x[MAX_BUGS], int bug_y[MAX_BUGS], int bug_size[MAX_BUGS], int bug_color[MAX_BUGS], int flake_x[MAX_FLAKES], int flake_y[MAX_FLAKES]); /* Make stars blink */ void blink_star(int star_radius[MAX_STARS], int star_color[MAX_STARS]); /* Move bug(s) */ void move_bug(int bug_x[MAX_BUGS], int bug_y[MAX_BUGS], int bug_size[MAX_BUGS], int bug_color[MAX_BUGS]); /* Update moon coordinates moon_x, moon_y for one tick */ void move_moonsun(int *moonsun_x, int *moonsun_y); /* Making it snow */ void snowing(int flake_x[MAX_FLAKES], int flake_y[MAX_FLAKES]); /* Draw buttons */ void draw_buttons (void); /* 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[MAX_FLOWERS], int flower_color[MAX_FLOWERS], int bug_color[MAX_BUGS], int *light, int *season); /* Display error message if internal error is detected. */ void something_is_wrong (void); /***************************************************************************** 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.) */ /* Information about the moon and stars: */ int moonsun_x, moonsun_y; /* screen x and y coordinates */ int star_x[MAX_STARS], star_y[MAX_STARS]; /* screen x and y coordinates */ int star_radius[MAX_STARS], star_color[MAX_STARS]; /* radius and color of a star */ int star_n; /* element variable for stars */ /* Information about the flowers */ int flower_x[MAX_FLOWERS], flower_y[MAX_FLOWERS]; /* screen x and y coordinates */ int flower_radius[MAX_FLOWERS], petal_radius[MAX_FLOWERS]; /* flower and petal radii */ int flower_color[MAX_FLOWERS], petal_color[MAX_FLOWERS]; /* flower and petal colors */ int flower_n;/* element variable for flowers */ /* Information about the tree */ /* Fill in here! */ /* 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 */ /* Information about the butterflies */ int bug_x[MAX_BUGS], bug_y[MAX_BUGS]; /* screen x and y coordinates */ int bug_size[MAX_BUGS], bug_color[MAX_BUGS]; /* size and color of butterflies */ int bug_n; /* element variable for butterflies */ /* Information about the season/time-of-day */ int light; /* day or night */ int season; /* spring, summer, fall, or winterm*/ int flake_x[MAX_FLAKES], flake_y[MAX_FLAKES]; /*screen x and y coordintaes */ int flake_n; /* element variable for flakes */ /* Initialize random number generator */ initialize_random_numbers(); /* 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 season/time-of-day */ light = NIGHT; season = SPRING; /* set initial location of the moon */ init_moonsun(&moonsun_x, &moonsun_y); /* set initial location of the stars */ for (star_n = 0; star_n < MAX_STARS; star_n++) { star_x[star_n] = (rand () % (GP142_XMAX * 2)) - GP142_XMAX; star_y[star_n] = (rand () % (GP142_YMAX / 4)) + (GP142_YMAX * 3 / 4); star_radius[star_n] = 3; star_color[star_n] = WHITE; } /*set initial location for flakes */ for (flake_n = 0; flake_n < MAX_FLAKES; flake_n++) { flake_x[flake_n] = (rand () % (GP142_XMAX * 2)) - GP142_XMAX; flake_y[flake_n] = (rand () % (GP142_YMAX * 2)) - GP142_YMAX; } /* set initial flower parameters */ for (flower_n = 0; flower_n < MAX_FLOWERS; flower_n++) { flower_x[flower_n] = (rand () % (GP142_XMAX * 2)) - GP142_XMAX; flower_y[flower_n] = (rand () % (GP142_YMAX * 2 / 3)) - GP142_YMAX; flower_radius[flower_n] = 2; flower_color[flower_n] = (rand () % (MAX_COLORS)); petal_radius[flower_n] = 8; petal_color[flower_n] = (rand () % (MAX_COLORS)); } /* set initial conditions for the boat */ boat_x = GP142_XMAX / 3 - 20; boat_y = HORIZON - 25; boat_len = 25; boat_mast = 40; /* set initial conditions for the butterflies */ for (bug_n = 0; bug_n < MAX_BUGS; bug_n++) { bug_x[bug_n] = flower_x[bug_n] + 20; bug_y[bug_n] = flower_y[bug_n] + 30; bug_size[bug_n] = MAX_BUG_SIZE/2; bug_color[bug_n] = (rand () % (MAX_COLORS)); } /* Draw initial landscape, buttons, and traffic */ draw_landscape(& season, &light, moonsun_x,moonsun_y, star_x, star_y, star_radius, star_color, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat_x, boat_y, boat_len, boat_mast, bug_x, bug_y, bug_size, bug_color, flake_x, flake_y); draw_buttons(); /* * Main event loop: * ---- ----- ----- * Wait for the next user action, decode it, and call an * appropriate function to handle it. Repeat until the * user selects quit. */ quit = FALSE; while (!quit) { /* get next event */ event = GP142_await_event(&mouse_x, &mouse_y, &key_pressed); /* perform appropriate action depending on kind of event */ switch (event) { case GP142_QUIT: /* Quit selected */ quit = TRUE; break; case GP142_KBD: /* Key pressed. Not used now. If the program should */ /* react to keyboard events, insert something appropriate */ /* here. Note that scanf CANNOT be used with GP142. */ break; case GP142_MOUSE: /* Mouse click. Determine if in a menu button */ /* or elsewhere and process accordingly. */ click_kind = classify_mouse_click(mouse_x, mouse_y); if (click_kind == BUTTON_CLICK) { handle_button(mouse_x, mouse_y, petal_color, flower_color, bug_color, &light, &season); } else { /* insert code here (and additional else-if statements) */ /* to react to mouse clicks elsewhere on the screen (if needed) */ } break; case GP142_PERIODIC: /* Timer interval event. Update everything that needs the change */ /* as time advances. Animation should go here! */ move_moonsun(&moonsun_x, &moonsun_y); blink_star(star_radius, star_color); move_bug(bug_x, bug_y, bug_size, bug_color); snowing(flake_x, flake_y); break; default: /* unknown event */ break; } /*end switch */ /* Redraw everything */ draw_landscape(&season, &light, moonsun_x, moonsun_y, star_x, star_y, star_radius, star_color, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat_x, boat_y, boat_len, boat_mast, bug_x, bug_y, bug_size, bug_color, flake_x, flake_y); draw_buttons(); } /* end event loop */ /* Termination: shut down graphics window and exit */ GP142_close(); return 0; } /* end main */ /***************************************************************************** INITIALIZATION PROCEDURES *****************************************************************************/ /* Initializes the moon parameters */ void init_moonsun(int *moonsun_x, int *moonsun_y) { *moonsun_x = GP142_XMAX - 50; *moonsun_y = GP142_YMAX - 35; } /***************************************************************************** BACKGROUND LANDSCAPE *****************************************************************************/ /* Change flower field colors */ void change_colors(int petal_color[MAX_FLOWERS], int flower_color[MAX_FLOWERS], int bug_color[MAX_BUGS]) { int flower_n; /* element variable for the flowers */ int bug_n; /* element variable for butterflies */ for (flower_n = 0; flower_n < MAX_FLOWERS; flower_n++) { petal_color[flower_n] = (petal_color[flower_n] + 1) % MAX_COLORS; flower_color[flower_n] = (flower_color[flower_n] + 1) % MAX_COLORS; } for (bug_n = 0; bug_n < MAX_BUGS; bug_n++) { bug_color[bug_n] = (bug_color[bug_n] + 1) % MAX_COLORS; } } /* Draw a single bug (butterfly) of a given size at given screen x and y coordinates */ void draw_bug(int bug_x[MAX_BUGS], int bug_y[MAX_BUGS], int bug_size[MAX_BUGS], int bug_color[MAX_BUGS]) { int bug_n; /* element variable for butterflies */ for (bug_n = 0; bug_n < MAX_BUGS; bug_n++) { GP142_triangleXY(bug_color[bug_n], bug_x[bug_n], bug_y[bug_n], bug_x[bug_n] - bug_size[bug_n], bug_y[bug_n] + bug_size[bug_n], bug_x[bug_n] - bug_size[bug_n], bug_y[bug_n] - bug_size[bug_n], FILL); GP142_triangleXY(bug_color[bug_n], bug_x[bug_n], bug_y[bug_n], bug_x[bug_n] + bug_size[bug_n], bug_y[bug_n] + bug_size[bug_n], bug_x[bug_n] + bug_size[bug_n], bug_y[bug_n] - bug_size[bug_n], FILL); GP142_lineXY(BLACK, bug_x[bug_n], bug_y[bug_n], bug_x[bug_n] - 3, bug_y[bug_n] + 7, 2); GP142_lineXY(BLACK, bug_x[bug_n], bug_y[bug_n], bug_x[bug_n] + 3, bug_y[bug_n] + 7, 2); } } /* Draw a boat at horizontal and vertical positions x and y and of the given length */ /* and mast height */ void draw_boat(int boat_x, int boat_y, int boat_len, int boat_mast) { GP142_rectangleXY(BLACK, boat_x - boat_len, boat_y, boat_x + boat_len, boat_y - 4, FILL); GP142_triangleXY(RED, boat_x, boat_y, boat_x, boat_y + boat_mast, boat_x + boat_mast, boat_y + 2 * boat_mast / 3, FILL); } /* Draw the background, including the moon at coordinates moon_x and moon_y and stars */ void draw_landscape(int * season, int * light, int moonsun_x, int moonsun_y, int star_x[MAX_STARS], int star_y[MAX_STARS], int star_radius[MAX_STARS], int star_color[MAX_STARS], int flower_x[MAX_FLOWERS], int flower_y[MAX_FLOWERS], int flower_radius[MAX_FLOWERS], int flower_color[MAX_FLOWERS], int petal_radius[MAX_FLOWERS], int petal_color[MAX_FLOWERS], int boat_x, int boat_y, int boat_len, int boat_mast, int bug_x[MAX_BUGS], int bug_y[MAX_BUGS], int bug_size[MAX_BUGS], int bug_color[MAX_BUGS], int flake_x[MAX_FLAKES], int flake_y[MAX_FLAKES]) { int text_offset = -GP142_XMAX + 15; /* horizontal offset of text */ int text_size = 12; /* size of text font */ int star_n; /* element variable for stars */ int flake_n; /* element variable for flakes */ int flower_n; /* element variable for flowers */ /* Draw the sky */ if (*light == NIGHT) GP142_rectangleXY(DUSTY_PLUM, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); else if (*season == WINTER && *light == DAY) GP142_rectangleXY(LT_GRAY, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); else GP142_rectangleXY(CYAN, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); /* Draw stars */ if (*light == NIGHT && *season != WINTER) { for (star_n = 0; star_n < MAX_STARS; star_n++) { GP142_triangleXY(star_color[star_n], star_x[star_n], star_y[star_n] + star_radius[star_n], star_x[star_n] + (int)(star_radius[star_n] * 0.87), star_y[star_n] - (int) (star_radius[star_n] / 2.0), star_x[star_n] - (int)(star_radius[star_n] * 0.87), star_y[star_n] - (int) (star_radius[star_n] / 2.0), FILL); GP142_triangleXY(star_color[star_n], star_x[star_n], star_y[star_n] - star_radius[star_n], star_x[star_n] - (int)(star_radius[star_n] * 0.87), star_y[star_n] + (int) (star_radius[star_n] / 2.0), star_x[star_n] + (int)(star_radius[star_n] * 0.87), star_y[star_n] + (int) (star_radius[star_n] / 2.0), FILL); } } /* Draw the moon (or sun) */ if (*light == NIGHT && *season != WINTER) { /* for the moon */ GP142_circleXY(WHITE, moonsun_x, moonsun_y, MOONSUN_RADIUS); GP142_ovalXY(DUSTY_PLUM, moonsun_x, moonsun_y - MOONSUN_RADIUS, moonsun_x + (int)(MOON_FULLNESS * MOONSUN_RADIUS), moonsun_y + MOONSUN_RADIUS, FILL); } if (*light == DAY && *season != WINTER) { /* for the sun */ GP142_circleXY(YELLOW, moonsun_x, moonsun_y, MOONSUN_RADIUS); } /* Draw a rainbow */ if (*season == SPRING && *light == DAY) { /* a spring day's rainbow */ GP142_ovalXY(RED, GP142_XMAX - (BOW_RADIUS / 2), (GP142_YMAX / 2) - BOW_RADIUS, GP142_XMAX + (BOW_RADIUS * 3 / 2), (GP142_YMAX / 2) + BOW_RADIUS, BAND_W); GP142_ovalXY(ORANGE, GP142_XMAX - ((BOW_RADIUS / 2) - BAND_W), (GP142_YMAX / 2) - (BOW_RADIUS - BAND_W), GP142_XMAX + ((BOW_RADIUS * 3 / 2) - BAND_W), (GP142_YMAX / 2) + (BOW_RADIUS - BAND_W), BAND_W); GP142_ovalXY(YELLOW, GP142_XMAX - ((BOW_RADIUS / 2) - (BAND_W * 2)), (GP142_YMAX / 2) - (BOW_RADIUS - (BAND_W * 2)), GP142_XMAX + ((BOW_RADIUS * 3 / 2) - (BAND_W * 2)), (GP142_YMAX / 2) + (BOW_RADIUS - (BAND_W * 2)), BAND_W); GP142_ovalXY(GREEN, GP142_XMAX - ((BOW_RADIUS / 2) - (BAND_W * 3)), (GP142_YMAX / 2) - (BOW_RADIUS - (BAND_W * 3)), GP142_XMAX + ((BOW_RADIUS * 3 / 2) - (BAND_W * 3)), (GP142_YMAX / 2) + (BOW_RADIUS - (BAND_W * 3)), BAND_W); GP142_ovalXY(BLUE, GP142_XMAX - ((BOW_RADIUS / 2) - (BAND_W * 4)), (GP142_YMAX / 2) - (BOW_RADIUS - (BAND_W * 4)), GP142_XMAX + ((BOW_RADIUS * 3 / 2) - (BAND_W * 4)), (GP142_YMAX / 2) + (BOW_RADIUS - (BAND_W * 4)), BAND_W); GP142_ovalXY(PURPLE, GP142_XMAX - ((BOW_RADIUS / 2) - (BAND_W * 5)), (GP142_YMAX / 2) - (BOW_RADIUS - (BAND_W * 5)), GP142_XMAX + ((BOW_RADIUS * 3 / 2) - (BAND_W * 5)), (GP142_YMAX / 2) + (BOW_RADIUS - (BAND_W * 5)), BAND_W); } /* Draw mountains */ if (*season != WINTER) { /* no snow on mountains */ GP142_triangleXY(LT_GRAY, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 8, (5 * GP142_YMAX)/6, FILL); GP142_triangleXY(MED_GRAY, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 3, (3 * GP142_YMAX)/4, FILL); GP142_triangleXY(BROWN, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, GP142_XMAX / 4, (2 * GP142_YMAX)/3, FILL); GP142_triangleXY(OLIVE, -( 5 * GP142_XMAX/4), HORIZON, (GP142_XMAX)/3 , HORIZON, -(3 * GP142_XMAX)/4, (2 * GP142_YMAX)/3 , FILL); GP142_triangleXY(FOREST_GREEN, -GP142_XMAX / 3 , HORIZON, GP142_XMAX, HORIZON, GP142_XMAX, (2 * GP142_YMAX)/3 , FILL); } else { /*snow on mountains */ GP142_triangleXY(WHITE, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 8, (5 * GP142_YMAX)/6, FILL); GP142_triangleXY(LT_GRAY, /*outline of mountain */ -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 8, (5 * GP142_YMAX)/6, UNFILLED); GP142_triangleXY(WHITE, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 3, (3 * GP142_YMAX)/4, FILL); GP142_triangleXY(LT_GRAY, /*outline of mountain */ -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 3, (3 * GP142_YMAX)/4, UNFILLED); GP142_triangleXY(WHITE, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, GP142_XMAX / 4, (2 * GP142_YMAX)/3, FILL); GP142_triangleXY(LT_GRAY, /*outline of mountain */ -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, GP142_XMAX / 4, (2 * GP142_YMAX)/3, UNFILLED); GP142_triangleXY(WHITE, -( 5 * GP142_XMAX/4), HORIZON, (GP142_XMAX)/3 , HORIZON, -(3 * GP142_XMAX)/4, (2 * GP142_YMAX)/3 , FILL); GP142_triangleXY(LT_GRAY, /*outline of mountain */ -( 5 * GP142_XMAX/4), HORIZON, (GP142_XMAX)/3 , HORIZON, -(3 * GP142_XMAX)/4, (2 * GP142_YMAX)/3 , UNFILLED); GP142_triangleXY(WHITE, -GP142_XMAX / 3 , HORIZON, GP142_XMAX, HORIZON, GP142_XMAX, (2 * GP142_YMAX)/3 , FILL); GP142_triangleXY(LT_GRAY, /*outline of mountain */ -GP142_XMAX / 3 , HORIZON, GP142_XMAX, HORIZON, GP142_XMAX, (2 * GP142_YMAX)/3 , UNFILLED); } /* Draw meadow */ switch (*season) { case SPRING: /* new grass */ GP142_rectangleXY(SEA_GREEN, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); break; case SUMMER: /* lush grass */ GP142_rectangleXY(GREEN, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); break; case FALL: /* golden grass */ GP142_rectangleXY(GOLD, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); break; case WINTER: /* snow on the ground */ GP142_rectangleXY(WHITE, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); GP142_lineXY(LT_GRAY, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, 1); /* horizon */ break; default: GP142_animate(ANI_HALT); something_is_wrong(); break; } /* Draw lake */ if (*season != WINTER) { /* normal water */ GP142_ovalXY(BLUE, -GP142_XMAX - 100, HORIZON, GP142_XMAX / 3, HORIZON - 50, FILL); } else { /* "ice-blue" lake */ GP142_ovalXY(ICE_BLUE, -GP142_XMAX - 100, HORIZON, GP142_XMAX / 3, HORIZON - 50, FILL); } /* Draw flowers */ if (*season == SPRING) { /*flowers in spring */ for (flower_n = 0; flower_n < MAX_FLOWERS; flower_n++) { GP142_circleXY(petal_color[flower_n], flower_x[flower_n], flower_y[flower_n], petal_radius[flower_n]); GP142_circleXY(flower_color[flower_n], flower_x[flower_n], flower_y[flower_n], flower_radius[flower_n]); GP142_lineXY(FOREST_GREEN, flower_x[flower_n], flower_y[flower_n] - petal_radius[flower_n], flower_x[flower_n], flower_y[flower_n] - petal_radius[flower_n] - 15, 2); GP142_lineXY(FOREST_GREEN, flower_x[flower_n], flower_y[flower_n] - petal_radius[flower_n] - 10, flower_x[flower_n] + 5, flower_y[flower_n] - petal_radius[flower_n] - 3, 2); } } /* Draw tree */ switch (*season) { case SPRING: case SUMMER: /* normal tree */ GP142_rectangleXY(BROWN, -GP142_XMAX + 50, -GP142_YMAX + 50, -GP142_XMAX + 60, -GP142_YMAX + 100, FILL); GP142_circleXY(FOREST_GREEN, -GP142_XMAX + 55, -GP142_YMAX + 110, 30); break; case FALL: /* leaves changed to orange */ GP142_rectangleXY(BROWN, -GP142_XMAX + 50, -GP142_YMAX + 50, -GP142_XMAX + 60, -GP142_YMAX + 100, FILL); GP142_circleXY(ORANGE, -GP142_XMAX + 55, -GP142_YMAX + 110, 30); break; case WINTER: /* dormant tree with snow on top */ GP142_rectangleXY(MED_GRAY, -GP142_XMAX + 50, -GP142_YMAX + 50, -GP142_XMAX + 60, -GP142_YMAX + 100, FILL); GP142_circleXY(BROWN, -GP142_XMAX + 55, -GP142_YMAX + 110, 30); GP142_rectangleXY(WHITE, -GP142_XMAX + 25, -GP142_YMAX + 120, -GP142_XMAX + 85, -GP142_YMAX + 140, FILL); GP142_ovalXY(LT_GRAY, -GP142_XMAX + 25, -GP142_YMAX + 80, -GP142_XMAX + 85, -GP142_YMAX + 140, UNFILLED); break; default: GP142_animate(ANI_HALT); something_is_wrong(); break; } /* Draw boat */ if (*season != WINTER) { /* no boats on lakes in winter */ draw_boat(boat_x, boat_y, boat_len, boat_mast); } /* Draw butterfly */ if (*season != WINTER) { /* no butterflies in winter */ draw_bug(bug_x, bug_y, bug_size, bug_color); } /* Draw flakes */ if (*season == WINTER) { /* it ususally snows just during winter */ for (flake_n = 0; flake_n < MAX_FLAKES; flake_n++ ) { GP142_circleXY(WHITE, flake_x[flake_n], flake_y[flake_n], 2); GP142_ovalXY(LT_GRAY, flake_x[flake_n] - 2, flake_y[flake_n] - 2, flake_x[flake_n] + 2, flake_y[flake_n] + 2, UNFILLED); } } } /*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_BUTTONS; 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, "Day <--> Night"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Cycle Seasons"); } /* 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_BUTTONS * 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[MAX_FLOWERS], int flower_color[MAX_FLOWERS], int bug_color[MAX_BUGS], int *light, int *season) { int buttonNum; /* number of selected button */ /* 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, bug_color); break; case 1: /* switch between night and day */ if (*light == NIGHT) *light = DAY; else *light = NIGHT; break; case 2: /* cycle the seasons */ switch(*season) { case SUMMER: *season = FALL; break; case FALL: *season = WINTER; break; case WINTER: *season = SPRING; break; case SPRING: *season = SUMMER; break; default: GP142_animate(ANI_HALT); something_is_wrong(); break; } default: /*Bad news if this is ever reached! */ something_is_wrong(); break; } } /***************************************************************************** ANIMATED OBJECTS *****************************************************************************/ /* Make the stars blink */ void blink_star(int star_radius[MAX_STARS], int star_color[MAX_STARS]) { int star_n; /* element variable for stars */ for (star_n = 0; star_n < MAX_STARS; star_n++) { star_radius[star_n] = rand() % MAX_STAR_RADIUS + 1; star_color[star_n] = rand() % MAX_COLORS; } } /* Make the snow move */ void snowing(int flake_x[MAX_FLAKES], int flake_y[MAX_FLAKES]) { int flake_n; /*element variable for flakes */ for (flake_n = 0; flake_n < MAX_FLAKES; flake_n++) { flake_x[flake_n] = (rand () % (GP142_XMAX * 2)) - GP142_XMAX; flake_y[flake_n] = (rand () % (GP142_YMAX * 2)) - GP142_YMAX; } } /* Update moon coordinates moon_x, moon_y by one tick */ void move_moonsun(int *moonsun_x, int *moonsun_y) { /* Move the moon to the left. If it reaches the edge, move it */ /* to the other side and down a bit. */ (*moonsun_x) --; if (*moonsun_x < -GP142_XMAX -30) { *moonsun_x = - *moonsun_x; (*moonsun_y) --; } } /* Make the bug(s) move around and flutter */ void move_bug(int bug_x[MAX_BUGS], int bug_y[MAX_BUGS], int bug_size[MAX_BUGS], int bug_color[MAX_BUGS]) { int bug_n; /* element variable for butterflies */ for (bug_n = 0; bug_n < MAX_BUGS; bug_n++) { bug_x[bug_n] = bug_x[bug_n] + rand() % 3 - 1; bug_y[bug_n] = bug_y[bug_n] + rand() % 3 - 1; bug_size[bug_n] = MAX_BUG_SIZE/2 + rand() % MAX_BUG_SIZE/2; } draw_bug(bug_x, bug_y, bug_size, bug_color); } /***************************************************************************** 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!"); }