/* Jeremy Barnes Section AF * CSE142, Spring 2000 * Homework 4 * Idyllic landscape animation */ #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 /* 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 NUMB_BUTTONS 7 /*the number of iterations it takes to reach the time of the explosion */ #define EXPLOSION 140 /* Mouse click in some area */ #define BUTTON_CLICK 1 #define MEADOW_CLICK 2 #define SKY_CLICK 3 /* Mouse click elsewhere */ #define OTHER_CLICK 0 /*Constants for the time of day */ #define DAY 1 #define NIGHT 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 MOON_RADIUS 20 #define MOON_FULLNESS 2.5 #define MAX_STAR_RADIUS 4 #define MAX_BUG_SIZE 10 #define MAX_STARS 50 #define MAX_VILLAGERS 15 /***************************************************************************** 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_moon(int *moon_x, int *moon_y); /*Initializes a position for a star */ void init_star(int star_x[], int star_y[], int star_radius[], int star_color[], int * num_stars); /*initalizes the position of the mountain */ void init_mountain(int * mountain_x, int * mountain_y); /*Initializes a position for a villager */ void init_villager(int villager_x[], int villager_y[], int * num_villagers); /* initializes the flower */ void init_flower(int * flower_x, int * flower_y, int *flower_radius, int * flower_color, int * petal_radius, int * petal_color); /*initializes the bug */ void init_bug(int * bug_x, int * bug_y, int * bug_size); /* Change flower field colors */ void change_colors(int *petal_color, int *flower_color); /*draws a single star */ void draw_star(int star_x[], int star_y[], int star_radius[], int star_color[], int num_stars); /*draws the huts */ void draw_huts(void); /*draws the explosion */ void draw_explosion(int clock); /* Draw a single bug (buttefly) */ void draw_bug(int bug_x, int bug_y, int bug_size); /*draws, light gray, gray and brown mountains */ void draw_mountains(int mountain_x, int mountain_y); /* 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 star_x[], int star_y[], int star_radius[], int star_color[], int num_stars, int flower_x, int flower_y, int flower_radius, int flower_color, int petal_radius, int petal_color, int bug_x, int bug_y, int bug_size, int mountain_x, int mountain_y, int villager_x[], int villager_y[], int num_villagers, int lava_lake_y, int time, int clock); /* Make stars blink */ void blink_star(int star_radius[], int star_color[], int num_stars); /* Move bug(s) */ void move_bug(int *bug_x, int *bug_y, int *bug_size); /* Update moon coordinates moon_x, moon_y for one tick */ void move_moon(int *moon_x, int *moon_y); /* Move mountain */ void move_mountain(int *mountain_x, int *mountain_y); /*Move villagers */ void move_villager(int villager_x[], int villager_y[], int num_villagers, int clock); /*moves the lava lake */ void move_lava_lake(int * lava_lake_y); /* 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 * flower_x, int * flower_y, int * flower_radius, int *flower_color, int *petal_radius, int *petal_color, int *mountain_x, int * mountain_y, int *time, int star_x[], int star_y[], int star_radius[], int star_color[], int * num_stars, int villager_x[], int villager_y[], int * num_villagers, int * moon_x, int * moon_y, int * lava_lake_y, int *bug_x, int *bug_y, int *bug_size, int * clock); /* 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.) */ int time = NIGHT; /* user to control the time of day */ int clock = 0; /*regulates timing in animation */ /* Information about the moon and stars: */ int moon_x, moon_y; /* screen x and y coordinates */ int star_x[MAX_STARS], star_y[MAX_STARS]; /* screen x and y coordinate */ int star_radius[MAX_STARS], star_color[MAX_STARS]; /* radius and color of a star */ int num_stars = 0; /*actual number of stars */ /* 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 */ /* Information about the bug(s) */ int bug_x, bug_y, bug_size; /* screen x and y coordinates and size of the bug */ /*Information for the mountain*/ int mountain_x, mountain_y; /*information about the villagers */ int villager_x[MAX_VILLAGERS]; int villager_y[MAX_VILLAGERS]; int num_villagers = 0; /*actual number of villagers */ /*information about the lava lake */ int lava_lake_y; /* 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(); /* set initial location of the moon */ init_moon(&moon_x, &moon_y); /* set initial flower parameters */ init_flower(&flower_x, &flower_y, &flower_radius, &flower_color, &petal_radius, &petal_color); /*set initial conditions of the mountain*/ init_mountain(&mountain_x, &mountain_y); /*inital starting point of the lava lake */ lava_lake_y = HORIZON; /* set initial conditions for the buttefly */ init_bug(&bug_x, &bug_y, &bug_size); /* Draw initial landscape, buttons, and traffic */ draw_landscape(moon_x,moon_y, star_x, star_y, star_radius, star_color, num_stars, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, bug_x, bug_y, bug_size, mountain_x, mountain_y, villager_x, villager_y, num_villagers, lava_lake_y, time, clock); 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 btuton */ /* or elsewhere and process accordingly. */ click_kind = classify_mouse_click(mouse_x, mouse_y); if (click_kind == BUTTON_CLICK) { /*Processes the button click */ handle_button(mouse_x, mouse_y, &flower_x, &flower_y, &flower_radius, &flower_color, &petal_radius, &petal_color, &mountain_x, &mountain_y, &time, star_x, star_y, star_radius, star_color, &num_stars, villager_x, villager_y, &num_villagers, &moon_x, &moon_y, &lava_lake_y, &bug_x, &bug_y, &bug_size, &clock); } if (click_kind == MEADOW_CLICK) { if(num_villagers < MAX_VILLAGERS) { villager_x[num_villagers] = mouse_x; villager_y[num_villagers] = mouse_y; num_villagers = num_villagers + 1; } } if (click_kind == SKY_CLICK) { if(num_stars < MAX_STARS) { star_x[num_stars] = mouse_x; star_y[num_stars] = mouse_y; star_radius[num_stars] = rand() % MAX_STAR_RADIUS + 1; star_color[num_stars] = rand() % MAX_COLORS; num_stars = num_stars + 1; } } break; case GP142_PERIODIC: /* Timer interval event. Update everything that needs the change */ /* as time advances. Animation should go here! */ move_moon(&moon_x, &moon_y); blink_star(star_radius, star_color, num_stars); move_bug(&bug_x, &bug_y, &bug_size); if ((clock > 10) && (clock < 25)) { move_mountain(&mountain_x, &mountain_y); move_villager(villager_x, villager_y, num_villagers, clock); } if ((clock > 50) && (clock < 75)) { move_mountain(&mountain_x, &mountain_y); move_villager(villager_x, villager_y, num_villagers, clock); } if ((clock > 105) && (clock <= EXPLOSION)) { move_mountain(&mountain_x, &mountain_y); move_villager(villager_x, villager_y, num_villagers, clock); } if (clock == EXPLOSION) init_mountain(&mountain_x, &mountain_y); if (clock > EXPLOSION) move_villager(villager_x, villager_y, num_villagers, clock); if (clock > EXPLOSION + 10) move_lava_lake(&lava_lake_y); clock++; break; default: /* unknown event */ break; } /*end switch */ /* Redraw everything */ draw_landscape(moon_x, moon_y, star_x, star_y, star_radius, star_color, num_stars, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, bug_x, bug_y, bug_size, mountain_x, mountain_y, villager_x, villager_y, num_villagers, lava_lake_y, time, clock); 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_moon(int *moon_x, int *moon_y) { *moon_x = GP142_XMAX - 50; *moon_y = GP142_YMAX - 35; } void init_mountain(int * mountain_x, int * mountain_y){ *mountain_x = GP142_XMAX-80; *mountain_y = GP142_YMAX; } /*Initializes the positions of stars */ void init_star(int star_x[], int star_y[], int star_radius[], int star_color[], int * num_stars){ if (*num_stars < MAX_STARS) { if ((*num_stars % 2) == 0) { star_x[*num_stars] = rand() % 300; }else{ star_x[*num_stars] = -(rand() % 300);} star_y[*num_stars] = rand() % 150 + 100; star_radius[*num_stars] = rand() % MAX_STAR_RADIUS + 1; star_color[*num_stars] = rand() % MAX_COLORS; *num_stars = *num_stars + 1; } } /*initializes a position of a villager */ void init_villager(int villager_x[], int villager_y[], int * num_villagers) { if (*num_villagers < MAX_VILLAGERS) { if ((*num_villagers % 2) == 0) { villager_x[*num_villagers] = (rand() % 290); } else { villager_x[*num_villagers] = -(rand() % 300); } villager_y[*num_villagers] = -(rand() % 190 + 50); *num_villagers = *num_villagers + 1; } } /*initializes the bugs position */ void init_bug(int * bug_x, int * bug_y, int * bug_size) { *bug_x = GP142_XMAX/3 + 20; *bug_y = -GP142_YMAX + 70; *bug_size = MAX_BUG_SIZE/2; } /*initializes the flower */ void init_flower(int * flower_x, int * flower_y, int *flower_radius, int * flower_color, int * petal_radius, int * petal_color) { *flower_x = GP142_XMAX / 3; *flower_y = -GP142_YMAX + 40; *flower_radius = 2; *flower_color = YELLOW; *petal_radius = 8; *petal_color = RED; } /***************************************************************************** BACKGROUND LANDSCAPE *****************************************************************************/ /* Change flower field colors */ void change_colors(int *petal_color, int *flower_color) { *petal_color = (*petal_color + 1) % MAX_COLORS; *flower_color = (*flower_color + 1) % MAX_COLORS; } void draw_mountains(int mountain_x, int mountain_y){ /* Draw mountains */ GP142_triangleXY(LT_GRAY, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 8, GP142_YMAX - 60, FILL); GP142_triangleXY(MED_GRAY, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, -GP142_XMAX / 3, GP142_YMAX - 80, FILL); /*animated mountain */ GP142_triangleXY(BROWN, -mountain_x, (-2 * (mountain_y / 10)), mountain_x, (-2 * (mountain_y / 10)), mountain_x / 4, mountain_y - 50, FILL); } /*draws a star */ void draw_star(int star_x[], int star_y[], int star_radius[], int star_color[], int num_stars){ int i; for (i = 0; i < num_stars; i++){ GP142_triangleXY(star_color[i], star_x[i], star_y[i] + star_radius[i], star_x[i] + (int)(star_radius[i] * 0.87), star_y[i] - (int) (star_radius[i] / 2.0), star_x[i] - (int)(star_radius[i] * 0.87), star_y[i] - (int) (star_radius[i] / 2.0), FILL); GP142_triangleXY(star_color[i], star_x[i], star_y[i] - star_radius[i], star_x[i] - (int)(star_radius[i] * 0.87), star_y[i] + (int) (star_radius[i] / 2.0), star_x[i] + (int)(star_radius[i] * 0.87), star_y[i] + (int) (star_radius[i] / 2.0), FILL); } } /*draws the huts */ void draw_huts(void){ GP142_rectangleXY(YELLOW, GP142_XMAX - 110, -(GP142_YMAX - 180), GP142_XMAX - 70, -(GP142_YMAX - 210), FILL); GP142_triangleXY(YELLOW, GP142_XMAX - 115, -(GP142_YMAX - 210), GP142_XMAX - 65, -(GP142_YMAX - 210), GP142_XMAX - 90, -(GP142_YMAX - 230), FILL); GP142_lineXY(BLACK, GP142_XMAX - 115, -(GP142_YMAX - 210), GP142_XMAX - 65, -(GP142_YMAX - 210), 1); GP142_rectangleXY(BLACK, GP142_XMAX - 95, -(GP142_YMAX - 180), GP142_XMAX - 85, -(GP142_YMAX - 200), FILL); /*other hut */ GP142_rectangleXY(YELLOW, -(GP142_XMAX - 110), -(GP142_YMAX - 185), -(GP142_XMAX - 70), -(GP142_YMAX - 215), FILL); GP142_triangleXY(YELLOW, -(GP142_XMAX - 115), -(GP142_YMAX - 215), -(GP142_XMAX - 65), -(GP142_YMAX - 215), -(GP142_XMAX - 90), -(GP142_YMAX - 235), FILL); GP142_lineXY(BLACK, -(GP142_XMAX - 115), -(GP142_YMAX - 215), -(GP142_XMAX - 65), -(GP142_YMAX - 215), 1); GP142_rectangleXY(BLACK, -(GP142_XMAX - 95), -(GP142_YMAX - 185), -(GP142_XMAX - 85), -(GP142_YMAX - 205), FILL); } /* Draw a single bug (butterfly) of a given size at given screen x and y coordinates */ void draw_bug(int bug_x, int bug_y, int bug_size) { GP142_triangleXY(ORANGE, bug_x, bug_y, bug_x - bug_size, bug_y + bug_size, bug_x - bug_size, bug_y - bug_size, FILL); GP142_triangleXY(ORANGE, bug_x, bug_y, bug_x + bug_size, bug_y + bug_size, bug_x + bug_size, bug_y - bug_size, FILL); GP142_lineXY(BLACK, bug_x, bug_y, bug_x - 3, bug_y + 7, 2); GP142_lineXY(BLACK, bug_x, bug_y, bug_x + 3, bug_y + 7, 2); } /*draws the explosion */ void draw_explosion(int clock) { GP142_triangleXY(RED, 45, 180, 60, 180, 53, 205, FILL); GP142_triangleXY(RED, 30, 170, 45, 180, 36, 195, FILL); GP142_triangleXY(RED, 60, 180, 75, 170, 70, 195, FILL); if (clock == 141){ GP142_circleXY(rand() % MAX_COLORS, 35, 165, 20); GP142_circleXY(rand() % MAX_COLORS, 60, 160, 20); GP142_circleXY(rand() % MAX_COLORS, 35, 190, 20); GP142_circleXY(rand() % MAX_COLORS, 85, 190, 20); GP142_circleXY(rand() % MAX_COLORS, 85, 165, 20); } if (clock == 142){ GP142_circleXY(rand() % MAX_COLORS, -35, 100, 40); GP142_circleXY(rand() % MAX_COLORS, 60, 90, 40); GP142_circleXY(rand() % MAX_COLORS, -35, 165, 40); GP142_circleXY(rand() % MAX_COLORS, 155, 165, 40); GP142_circleXY(rand() % MAX_COLORS, 155, 100, 40); } if (clock == 143) { GP142_circleXY(rand() % MAX_COLORS, -175, 100, 70); GP142_circleXY(rand() % MAX_COLORS, 60, -50, 70); GP142_circleXY(rand() % MAX_COLORS, -175, -30, 70); GP142_circleXY(rand() % MAX_COLORS, 250, 165, 70); GP142_circleXY(rand() % MAX_COLORS, 250, -30, 70); } } /* ******************************* * * * Draw Landscape Function * * * *******************************/ void draw_landscape(int moon_x, int moon_y, int star_x[], int star_y[], int star_radius[], int star_color[], int num_stars, int flower_x, int flower_y, int flower_radius, int flower_color, int petal_radius, int petal_color, int bug_x, int bug_y, int bug_size, int mountain_x, int mountain_y, int villager_x[], int villager_y[], int num_villagers, int lava_lake_y, int time, int clock) { int text_offset = -GP142_XMAX + 15; /* horizontal offset of text */ int text_size = 12; /* size of text font */ int i; /*Draw the sky during the day */ if (time == DAY) { GP142_rectangleXY(ICE_BLUE, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); if (clock > EXPLOSION){ draw_mountains(mountain_x, mountain_y); /*draw masking triangles that covers the top top of the mountain*/ GP142_triangleXY(ICE_BLUE, 15, 165, 95, 165, 60, 205, FILL); GP142_triangleXY(BLACK, 17, 165, 77, 165, 65, 135, FILL); GP142_triangleXY(ICE_BLUE, 41, 166, 70, 166, 60, 155, FILL); } /* Draw the sun */ GP142_circleXY(ORANGE, moon_x, moon_y, MOON_RADIUS); } /*End draw sky during the day */ /* Draws the landscape at night */ if (time == NIGHT) { /*draws the sky */ GP142_rectangleXY(DUSTY_PLUM, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); /* Draw stars */ draw_star(star_x, star_y, star_radius, star_color, num_stars); if (clock > EXPLOSION){ draw_mountains(mountain_x, mountain_y); /*draw masking triangles for the night that covers the top of the mountain*/ GP142_triangleXY(DUSTY_PLUM, 15, 165, 95, 165, 60, 205, FILL); GP142_triangleXY(BLACK, 17, 165, 77, 165, 65, 135, FILL); GP142_triangleXY(DUSTY_PLUM, 41, 166, 70, 166, 60, 155, FILL); } /* Draws the moon */ GP142_circleXY(WHITE, moon_x, moon_y, MOON_RADIUS); } /* end draw night sky */ if (clock <= EXPLOSION){ draw_mountains(mountain_x, mountain_y); } /*draws the lava on the mountain */ if (clock >= 142) GP142_lineXY(RED, 65, 135, 45, 95, 5); if (clock >= 143){ GP142_lineXY(RED, 45, 95, 80, 0, 6); GP142_lineXY(RED, 45, 95, 20, 0, 6); } /*draw closest mountains */ 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); /* Draw meadow */ if (time == NIGHT) GP142_rectangleXY(SEA_GREEN, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); if (time == DAY) GP142_rectangleXY(GREEN, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); /*draws huts */ if (clock < EXPLOSION + 14) draw_huts(); /* Draw flower */ GP142_circleXY(petal_color, flower_x, flower_y, petal_radius); GP142_circleXY(flower_color, flower_x, flower_y, flower_radius); GP142_lineXY(FOREST_GREEN, flower_x, flower_y - petal_radius, flower_x, flower_y - petal_radius - 15, 2); GP142_lineXY(FOREST_GREEN, flower_x, flower_y - petal_radius - 10, flower_x + 5, flower_y - petal_radius - 3, 2); /*Draws villager */ for (i = 0; i < num_villagers; i++) { GP142_circleXY(BLACK, villager_x[i], villager_y[i], 4); GP142_lineXY(BLACK, (villager_x[i] - 10), (villager_y[i] - 5), (villager_x[i] + 10), (villager_y[i] - 5), 2); GP142_lineXY(BLACK, (villager_x[i] - 5), (villager_y[i] - 5), (villager_x[i] + 8), (villager_y[i] - 15), 2); GP142_lineXY(BLACK, (villager_x[i] + 5), (villager_y[i] - 5), (villager_x[i] - 8), (villager_y[i] - 15), 2); } /*draws lava lake */ if (clock > EXPLOSION + 10) GP142_rectangleXY(RED, -GP142_XMAX, HORIZON, GP142_XMAX, lava_lake_y, FILL); /* Draw buttefly */ draw_bug(bug_x, bug_y, bug_size); /*draws the explosion */ if (clock >= EXPLOSION && clock < EXPLOSION + 5) draw_explosion(clock); } /*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 < NUMB_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, "Run Animation"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Stop Animation"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Restart"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Day Or Night"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Change Colors"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Add Stars"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Add Villagers"); } /* 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 - NUMB_BUTTONS * BUTTON_HEIGHT))) return BUTTON_CLICK; if ((mouse_x > -GP142_XMAX) && (mouse_y < -50)) return MEADOW_CLICK; if ((mouse_x > -GP142_XMAX + 105) && (mouse_y > 80)) return SKY_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 * flower_x, int * flower_y, int * flower_radius, int *flower_color, int *petal_radius, int *petal_color, int *mountain_x, int * mountain_y, int *time, int star_x[], int star_y[], int star_radius[], int star_color[], int * num_stars, int villager_x[], int villager_y[], int * num_villagers, int * moon_x, int * moon_y, int * lava_lake_y, int *bug_x, int *bug_y, int *bug_size, int * clock) { 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: GP142_animate(ANI_RUN); break; case 1: GP142_animate(ANI_HALT); break; case 2: /*re-initilizes everything */ GP142_animate(ANI_HALT); *lava_lake_y = HORIZON; *clock = 0; *num_stars = 0; *num_villagers = 0; GP142_clear(); initialize_random_numbers(); init_moon(moon_x, moon_y); init_flower(flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color); init_mountain(mountain_x, mountain_y); init_bug(bug_x, bug_y, bug_size); break; case 3: if(*time == DAY) *time = NIGHT; else *time = DAY; break; case 4: /* change flower field colors */ change_colors(petal_color, flower_color); break; case 5: /*adds a new star */ init_star(star_x, star_y, star_radius, star_color, num_stars); break; case 6: /*adds a new villagers */ init_villager(villager_x, villager_y, num_villagers); break; default: /*Bad news if this is ever reached! */ GP142_animate(ANI_HALT); something_is_wrong(); break; } } /*End handle buttons /***************************************************************************** ANIMATED OBJECTS *****************************************************************************/ /*moves the lava lake */ void move_lava_lake(int * lava_lake_y) { *lava_lake_y = *lava_lake_y - 2; } /* Make the stars blink */ void blink_star(int star_radius[], int star_color[], int num_stars){ int i; for (i = 0; i < num_stars; i++){ star_radius[i] = rand() % MAX_STAR_RADIUS + 1; star_color[i] = rand() % MAX_COLORS; } } /* Update moon coordinates moon_x, moon_y by one tick */ void move_moon(int *moon_x, int *moon_y) { /* Move the moon to the left. If it reaches the edge, move it */ /* to the other side and down a bit. */ (*moon_x) --; if (*moon_x < -GP142_XMAX -30) { *moon_x = - *moon_x; (*moon_y) --; } } /* Make the bug(s) move around and flutter */ void move_bug(int *bug_x, int *bug_y, int *bug_size) { *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); } /*Make mountain shake */ void move_mountain(int *mountain_x, int *mountain_y) { if(*mountain_x >= 220) *mountain_x = *mountain_x - rand() % 20 + 7; if(*mountain_x < 220) *mountain_x = *mountain_x + rand() % 20 + 7; } /*move villagers */ void move_villager(int villager_x[], int villager_y[], int num_villagers, int clock) { int i; for (i = 0; i < num_villagers; i++) { if (clock <= EXPLOSION) { if (clock % 2 == 0) { villager_x[i] += (rand() % 4 + 1); villager_y[i] += (rand() % 2 + 1); } else{ villager_x[i] -= (rand() % 3 + 1); villager_y[i] -= (rand() % 2 + 1); } }else { villager_x[i] -= (rand() % 3 + 1); villager_y[i] -= (rand() % 2 + 1); } } } /***************************************************************************** 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!"); }