/*************************************************************/ /* Program: CSE 142 Spring 2000 Homework 4 */ /* Purpose: this homework modifies and extends */ /* a program that displays a simple animation of a lakeside */ /* scenery. Information about objects is stored in arrays */ /* Author: William Little, 4/29/00, Section AD(Ye) */ /*************************************************************/ #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_BUTTONS 4 /* 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 /* Index positions for objects in the scence*/ /* A single array will hold all important info for that object*/ /*moon*/ #define NUM_MOON_ARRAY_ELEMENTS 3 #define MOON_X 0 #define MOON_Y 1 #define MOON_COLOR 2 /* bug */ #define NUM_BUG_ARRAY_ELEMENTS 4 #define BUG_X 0 #define BUG_Y 1 #define BUG_COLOR 2 #define BUG_SIZE 3 /*boat*/ #define NUM_BOAT_ARRAY_ELEMENTS 5 #define BOAT_X 0 #define BOAT_Y 1 #define BOAT_LEN 2 #define BOAT_MAST 3 #define SAIL_COLOR 4 /*running man*/ #define NUM_MAN_ARRAY_ELEMENTS 2 #define MAN_X 0 #define MAN_Y 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_moon(int *moon_x, int *moon_y); /* Draw a single boat */ void draw_boat(int boat_x, int boat_y, int boat_len, int boat_mast, int sail_color); /* Draw a single bug (buttefly) */ void draw_bug(int bug_x, int bug_y, int bug_size, int bug_color); /* make something twinkle */ void blink(int *color); /* Change flower field colors */ void change_colors(int *petal_color, int *flower_color); /* 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 moon_color, 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 sail_color, int bug_x, int bug_y, int bug_size, int bug_color, int bug2_x, int bug2_y, int bug2_size, int bug2_color, int bug3_x, int bug3_y, int bug3_size, int bug3_color, int bug4_x, int bug4_y, int bug4_size, int bug4_color, int bug5_x, int bug5_y, int bug5_size, int bug5_color, int bug6_x, int bug6_y, int bug6_size, int bug6_color, int bug7_x, int bug7_y, int bug7_size, int bug7_color, int bug8_x, int bug8_y, int bug8_size, int bug8_color, int tree_color); /* Make stars blink */ void blink_star(int *star_radius, int *star_color); /* Move bug(s) */ void move_bug(int *bug_x, int *bug_y, int *bug_size, int *move_bug); /* Update moon coordinates moon_x, moon_y for one tick */ void move_moon(int *moon_x, int *moon_y); /* move boat if desired */ void move_boat(int *boat_x); /* 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 request*/ void handle_button(int x, int y, int *petal_color, int *flower_color, int *moving_boat, int *acid_trip, int *start_game, int *man_y); /* Display error message if internal error is detected. */ void something_is_wrong (void); /*GAME FUNCTIONS*/ /*man animation*/ void man1(int *man_x, int *man_y); void man2(int *man_x, int *man_y); void man3(int *man_x, int *man_y); void man4(int *man_x, int *man_y); void erase_man1(int *man_x, int *man_y); void erase_man2(int *man_x, int *man_y); void erase_man3(int *man_x, int *man_y); void erase_man4(int *man_x, int *man_y); /***************************************************************************** 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 moon[NUM_MOON_ARRAY_ELEMENTS]; /*the array that holds the moon info*/ int acid_trip = 1; /*1 will stop the blinking, -1 will start it*/ 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 and color of another star */ /* 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 tree */ int tree_color = FOREST_GREEN; /* Information about the boat */ int boat[NUM_BOAT_ARRAY_ELEMENTS]; int moving_boat = 1; /*1 will stop the boat, -1 will move the boat*/ /* Information about the bug swarm */ int bug[NUM_BUG_ARRAY_ELEMENTS]; int bug2[NUM_BUG_ARRAY_ELEMENTS]; int bug3[NUM_BUG_ARRAY_ELEMENTS]; int bug4[NUM_BUG_ARRAY_ELEMENTS]; int bug5[NUM_BUG_ARRAY_ELEMENTS]; int bug6[NUM_BUG_ARRAY_ELEMENTS]; int bug7[NUM_BUG_ARRAY_ELEMENTS]; int bug8[NUM_BUG_ARRAY_ELEMENTS]; /*info about the game*/ int start_game; int man[NUM_MAN_ARRAY_ELEMENTS]; int run_count = 1; /* 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 location and color of the moon */ init_moon(&moon[MOON_X], &moon[MOON_Y]); moon[MOON_COLOR] = WHITE; /* we can change it later :-) */ /* 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 initial conditions for the boat */ boat[BOAT_X] = GP142_XMAX / 3 - 20; boat[BOAT_Y] = HORIZON - 25; boat[BOAT_LEN] = 25; boat[BOAT_MAST] = 40; boat[SAIL_COLOR] = ICE_BLUE; /* set initial conditions for the butterflies */ bug[BUG_X] = flower_x - 100; /*store the info into an array*/ bug[BUG_Y] = flower_y + 30; bug[BUG_COLOR] = PURPLE; bug[BUG_SIZE] = MAX_BUG_SIZE - 2; bug2[BUG_X] = flower_x - 100; bug2[BUG_Y] = flower_y + 20; bug2[BUG_COLOR] = RED; bug2[BUG_SIZE] = MAX_BUG_SIZE - 4; bug3[BUG_X] = flower_x - 100; bug3[BUG_Y] = flower_y + 10; bug3[BUG_COLOR] = YELLOW; bug3[BUG_SIZE] = MAX_BUG_SIZE - 6; bug4[BUG_X] = flower_x - 100; bug4[BUG_Y] = flower_y; bug4[BUG_COLOR] = WHITE; bug4[BUG_SIZE] = MAX_BUG_SIZE - 8; bug5[BUG_X] = flower_x - 150; bug5[BUG_Y] = flower_y + 30; bug5[BUG_COLOR] = GREEN; bug5[BUG_SIZE] = MAX_BUG_SIZE - 2; bug6[BUG_X] = flower_x - 150; bug6[BUG_Y] = flower_y + 20; bug6[BUG_COLOR] = ORANGE; bug6[BUG_SIZE] = MAX_BUG_SIZE - 4; bug7[BUG_X] = flower_x - 150; bug7[BUG_Y] = flower_y + 10; bug7[BUG_COLOR] = PINK; bug7[BUG_SIZE] = MAX_BUG_SIZE - 6; bug8[BUG_X] = flower_x - 150; bug8[BUG_Y] = flower_y; bug8[BUG_COLOR] = BLUE; bug8[BUG_SIZE] = MAX_BUG_SIZE - 8; /* INITIAL INFO FOR GAME */ man[MAN_X] = -GP142_XMAX - 10; man[MAN_Y] = -GP142_YMAX + 60; /* Draw initial landscape, buttons, and traffic */ draw_landscape(moon[MOON_X], moon[MOON_Y], moon[MOON_COLOR], star_x, star_y, star_radius, star_color, star2_x, star2_y, star2_radius, star2_color, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat[BOAT_X], boat[BOAT_Y], boat[BOAT_LEN], boat[BOAT_MAST], boat[SAIL_COLOR], bug[BUG_X], bug[BUG_Y], bug[BUG_SIZE], bug[BUG_COLOR], bug2[BUG_X], bug2[BUG_Y], bug2[BUG_SIZE], bug2[BUG_COLOR], bug3[BUG_X], bug3[BUG_Y], bug3[BUG_SIZE], bug3[BUG_COLOR], bug4[BUG_X], bug4[BUG_Y], bug4[BUG_SIZE], bug4[BUG_COLOR], bug5[BUG_X], bug5[BUG_Y], bug5[BUG_SIZE], bug5[BUG_COLOR], bug6[BUG_X], bug6[BUG_Y], bug6[BUG_SIZE], bug6[BUG_COLOR], bug7[BUG_X], bug7[BUG_Y], bug7[BUG_SIZE], bug7[BUG_COLOR], bug8[BUG_X], bug8[BUG_Y], bug8[BUG_SIZE], bug8[BUG_COLOR], tree_color); draw_buttons(); /* * first 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; start_game = FALSE; while (!quit & !start_game) { /* 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, &moving_boat, &acid_trip, &start_game, &man[MAN_Y]); } 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_moon(&moon[MOON_X], &moon[MOON_Y]); blink_star(&star_radius, &star_color); blink_star(&star2_radius, &star2_color); /*make butterflies flutter*/ move_bug(&bug[BUG_X], &bug[BUG_Y], &bug[BUG_SIZE], &bug[BUG_COLOR]); move_bug(&bug2[BUG_X], &bug2[BUG_Y], &bug2[BUG_SIZE], &bug2[BUG_COLOR]); move_bug(&bug3[BUG_X], &bug3[BUG_Y], &bug3[BUG_SIZE], &bug3[BUG_COLOR]); move_bug(&bug4[BUG_X], &bug4[BUG_Y], &bug4[BUG_SIZE], &bug4[BUG_COLOR]); move_bug(&bug5[BUG_X], &bug5[BUG_Y], &bug5[BUG_SIZE], &bug5[BUG_COLOR]); move_bug(&bug6[BUG_X], &bug6[BUG_Y], &bug6[BUG_SIZE], &bug6[BUG_COLOR]); move_bug(&bug7[BUG_X], &bug7[BUG_Y], &bug7[BUG_SIZE], &bug7[BUG_COLOR]); move_bug(&bug8[BUG_X], &bug8[BUG_Y], &bug8[BUG_SIZE], &bug8[BUG_COLOR]); /*make boat move if simulate wind option is desired*/ if (moving_boat != 1) move_boat(&boat[BOAT_X]); /*make user experience an acid trip, by blinking objects*/ if (acid_trip != 1) { blink(&moon[MOON_COLOR]); blink(&boat[SAIL_COLOR]); blink(&bug[BUG_COLOR]); blink(&bug2[BUG_COLOR]); blink(&bug3[BUG_COLOR]); blink(&bug4[BUG_COLOR]); blink(&bug5[BUG_COLOR]); blink(&bug6[BUG_COLOR]); blink(&bug7[BUG_COLOR]); blink(&bug8[BUG_COLOR]); blink(&tree_color); blink(&flower_color); blink(&petal_color); } else /*restore original colors, except flower color*/ /*its hard to completely recover from an acid trip :-)*/ { moon[MOON_COLOR] = WHITE; boat[SAIL_COLOR] = ICE_BLUE; tree_color = FOREST_GREEN; bug[BUG_COLOR] = PURPLE; bug2[BUG_COLOR] = RED; bug3[BUG_COLOR] = YELLOW; bug4[BUG_COLOR] = WHITE; bug5[BUG_COLOR] = GREEN; bug6[BUG_COLOR] = ORANGE; bug7[BUG_COLOR] = PINK; bug8[BUG_COLOR] = BLUE; } break; default: /* unknown event */ break; } /*end switch */ /* Redraw everything */ draw_landscape(moon[MOON_X], moon[MOON_Y], moon[MOON_COLOR], star_x, star_y, star_radius, star_color, star2_x, star2_y, star2_radius, star2_color, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat[BOAT_X], boat[BOAT_Y], boat[BOAT_LEN], boat[BOAT_MAST], boat[SAIL_COLOR], bug[BUG_X], bug[BUG_Y], bug[BUG_SIZE], bug[BUG_COLOR], bug2[BUG_X], bug2[BUG_Y], bug2[BUG_SIZE], bug2[BUG_COLOR], bug3[BUG_X], bug3[BUG_Y], bug3[BUG_SIZE], bug3[BUG_COLOR], bug4[BUG_X], bug4[BUG_Y], bug4[BUG_SIZE], bug4[BUG_COLOR], bug5[BUG_X], bug5[BUG_Y], bug5[BUG_SIZE], bug5[BUG_COLOR], bug6[BUG_X], bug6[BUG_Y], bug6[BUG_SIZE], bug6[BUG_COLOR], bug7[BUG_X], bug7[BUG_Y], bug7[BUG_SIZE], bug7[BUG_COLOR], bug8[BUG_X], bug8[BUG_Y], bug8[BUG_SIZE], bug8[BUG_COLOR], tree_color); draw_buttons(); } /* end event loop */ /* EVENT LOOP FOR GAME*/ 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, &moving_boat, &acid_trip, &start_game, &man[MAN_Y]); } else { if (mouse_y > man[MAN_Y]) man[MAN_Y] = man[MAN_Y] + 5; else man[MAN_Y] = man[MAN_Y] - 5; } break; case GP142_PERIODIC: /* Timer interval event. Update everything that needs the change */ /* as time advances. Animation should go here! */ move_moon(&moon[MOON_X], &moon[MOON_Y]); blink_star(&star_radius, &star_color); blink_star(&star2_radius, &star2_color); /*make butterflies flutter*/ move_bug(&bug[BUG_X], &bug[BUG_Y], &bug[BUG_SIZE], &bug[BUG_COLOR]); move_bug(&bug2[BUG_X], &bug2[BUG_Y], &bug2[BUG_SIZE], &bug2[BUG_COLOR]); move_bug(&bug3[BUG_X], &bug3[BUG_Y], &bug3[BUG_SIZE], &bug3[BUG_COLOR]); move_bug(&bug4[BUG_X], &bug4[BUG_Y], &bug4[BUG_SIZE], &bug4[BUG_COLOR]); move_bug(&bug5[BUG_X], &bug5[BUG_Y], &bug5[BUG_SIZE], &bug5[BUG_COLOR]); move_bug(&bug6[BUG_X], &bug6[BUG_Y], &bug6[BUG_SIZE], &bug6[BUG_COLOR]); move_bug(&bug7[BUG_X], &bug7[BUG_Y], &bug7[BUG_SIZE], &bug7[BUG_COLOR]); move_bug(&bug8[BUG_X], &bug8[BUG_Y], &bug8[BUG_SIZE], &bug8[BUG_COLOR]); /*make boat move if simulate wind option is desired*/ if (moving_boat != 1) move_boat(&boat[BOAT_X]); /*make user experience an acid trip, by blinking objects*/ if (acid_trip != 1) { blink(&moon[MOON_COLOR]); blink(&boat[SAIL_COLOR]); blink(&bug[BUG_COLOR]); blink(&bug2[BUG_COLOR]); blink(&bug3[BUG_COLOR]); blink(&bug4[BUG_COLOR]); blink(&bug5[BUG_COLOR]); blink(&bug6[BUG_COLOR]); blink(&bug7[BUG_COLOR]); blink(&bug8[BUG_COLOR]); blink(&tree_color); blink(&flower_color); blink(&petal_color); } else /*restore original colors, except flower color*/ /*its hard to completely recover from an acid trip :-)*/ { moon[MOON_COLOR] = WHITE; boat[SAIL_COLOR] = ICE_BLUE; tree_color = FOREST_GREEN; bug[BUG_COLOR] = PURPLE; bug2[BUG_COLOR] = RED; bug3[BUG_COLOR] = YELLOW; bug4[BUG_COLOR] = WHITE; bug5[BUG_COLOR] = GREEN; bug6[BUG_COLOR] = ORANGE; bug7[BUG_COLOR] = PINK; bug8[BUG_COLOR] = BLUE; } /* GAME ANIMATION */ run_count = run_count ++; man[MAN_X] = man[MAN_X] + 5 ; if (man[MAN_X] > (GP142_XMAX + 20)) man[MAN_X] = -GP142_XMAX - 10; if ((man[MAN_X] < bug[BUG_X] + 6 ) && (man[MAN_X] > (bug[BUG_X] - 6 )) && ((man[MAN_Y] < bug[BUG_Y] + 25) && (man[MAN_Y] > bug[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug2[BUG_X] + 6 ) && (man[MAN_X] > (bug2[BUG_X] - 6 )) && ((man[MAN_Y] < bug2[BUG_Y] + 25) && (man[MAN_Y] > bug2[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug3[BUG_X] + 6 ) && (man[MAN_X] > (bug3[BUG_X] - 6 )) && ((man[MAN_Y] < bug3[BUG_Y] + 25) && (man[MAN_Y] > bug3[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug4[BUG_X] + 6 ) && (man[MAN_X] > (bug4[BUG_X] - 6 )) && ((man[MAN_Y] < bug4[BUG_Y] + 25) && (man[MAN_Y] > bug4[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug5[BUG_X] + 6 ) && (man[MAN_X] > (bug5[BUG_X] - 6 )) && ((man[MAN_Y] < bug5[BUG_Y] + 25) && (man[MAN_Y] > bug5[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug6[BUG_X] + 6 ) && (man[MAN_X] > (bug6[BUG_X] - 6 )) && ((man[MAN_Y] < bug6[BUG_Y] + 25) && (man[MAN_Y] > bug6[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug7[BUG_X] + 6 ) && (man[MAN_X] > (bug7[BUG_X] - 6 )) && ((man[MAN_Y] < bug7[BUG_Y] + 25) && (man[MAN_Y] > bug7[BUG_Y] - 25))) quit = TRUE; if ((man[MAN_X] < bug8[BUG_X] + 6 ) && (man[MAN_X] > (bug8[BUG_X] - 6 )) && ((man[MAN_Y] < bug8[BUG_Y] + 25) && (man[MAN_Y] > bug8[BUG_Y] - 25))) quit = TRUE; break; default: /* unknown event */ break; } /*end switch */ /* Redraw everything */ draw_landscape(moon[MOON_X], moon[MOON_Y], moon[MOON_COLOR], star_x, star_y, star_radius, star_color, star2_x, star2_y, star2_radius, star2_color, flower_x, flower_y, flower_radius, flower_color, petal_radius, petal_color, boat[BOAT_X], boat[BOAT_Y], boat[BOAT_LEN], boat[BOAT_MAST], boat[SAIL_COLOR], bug[BUG_X], bug[BUG_Y], bug[BUG_SIZE], bug[BUG_COLOR], bug2[BUG_X], bug2[BUG_Y], bug2[BUG_SIZE], bug2[BUG_COLOR], bug3[BUG_X], bug3[BUG_Y], bug3[BUG_SIZE], bug3[BUG_COLOR], bug4[BUG_X], bug4[BUG_Y], bug4[BUG_SIZE], bug4[BUG_COLOR], bug5[BUG_X], bug5[BUG_Y], bug5[BUG_SIZE], bug5[BUG_COLOR], bug6[BUG_X], bug6[BUG_Y], bug6[BUG_SIZE], bug6[BUG_COLOR], bug7[BUG_X], bug7[BUG_Y], bug7[BUG_SIZE], bug7[BUG_COLOR], bug8[BUG_X], bug8[BUG_Y], bug8[BUG_SIZE], bug8[BUG_COLOR], tree_color); /*animate the running man*/ if (run_count < 1) man1(&man[MAN_X], &man[MAN_Y]); else if (run_count < 1) erase_man1(&man[MAN_X], &man[MAN_Y]); else if (run_count < 2) man2(&man[MAN_X], &man[MAN_Y]); else if (run_count < 2) erase_man2(&man[MAN_X], &man[MAN_Y]); else if (run_count < 3) man4(&man[MAN_X], &man[MAN_Y]); else if (run_count < 3) erase_man4(&man[MAN_X], &man[MAN_Y]); else if (run_count < 4) man3(&man[MAN_X], &man[MAN_Y]); else if (run_count < 4) erase_man3(&man[MAN_X], &man[MAN_Y]); else if (run_count < 5) man1(&man[MAN_X], &man[MAN_Y]); else if (run_count < 5) erase_man1(&man[MAN_X], &man[MAN_Y]); else if (run_count < 6) man2(&man[MAN_X], &man[MAN_Y]); else if (run_count < 6) erase_man2(&man[MAN_X], &man[MAN_Y]); else if (run_count < 7) man4(&man[MAN_X], &man[MAN_Y]); else if (run_count < 7) erase_man4(&man[MAN_X], &man[MAN_Y]); else if (run_count < 8) man3(&man[MAN_X], &man[MAN_Y]); else if (run_count < 8) erase_man2(&man[MAN_X], &man[MAN_Y]); else { man1(&man[MAN_X], &man[MAN_Y]); run_count = 0; } draw_buttons(); } /* 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; } /* Initialize other objects and their parameters here - tree, bug, etc. */ /* ... */ /***************************************************************************** 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; } /* 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, int bug_color) { GP142_triangleXY(bug_color, bug_x, bug_y, bug_x - bug_size, bug_y + bug_size, bug_x - bug_size, bug_y - bug_size, FILL); GP142_triangleXY(bug_color, 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); } /* 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, int sail_color) { /*blink(&sail_color); blinking sail? :-) */ GP142_rectangleXY(BLACK, boat_x - boat_len, boat_y, boat_x + boat_len, boat_y - 4, FILL); GP142_triangleXY(sail_color, 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 moon_x, int moon_y, int moon_color, 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 sail_color, int bug_x, int bug_y, int bug_size, int bug_color, int bug2_x, int bug2_y, int bug2_size, int bug2_color, int bug3_x, int bug3_y, int bug3_size, int bug3_color, int bug4_x, int bug4_y, int bug4_size, int bug4_color, int bug5_x, int bug5_y, int bug5_size, int bug5_color, int bug6_x, int bug6_y, int bug6_size, int bug6_color, int bug7_x, int bug7_y, int bug7_size, int bug7_color, int bug8_x, int bug8_y, int bug8_size, int bug8_color, int tree_color) { int text_offset = -GP142_XMAX + 15; /* horizontal offset of text */ int text_size = 12; /* size of text font */ /* Draw the sky */ GP142_rectangleXY(DUSTY_PLUM, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); /* Draw the moon */ GP142_circleXY(moon_color, moon_x, moon_y, MOON_RADIUS); GP142_ovalXY(DUSTY_PLUM, moon_x, moon_y - MOON_RADIUS, moon_x + (int)(MOON_FULLNESS * MOON_RADIUS), moon_y + MOON_RADIUS, FILL); /* Draw stars */ GP142_triangleXY(star_color, star_x, star_y + star_radius, star_x + (int)(star_radius * 0.87), star_y - (int) (star_radius / 2.0), star_x - (int)(star_radius * 0.87), star_y - (int) (star_radius / 2.0), FILL); GP142_triangleXY(star_color, star_x, star_y - star_radius, star_x - (int)(star_radius * 0.87), star_y + (int) (star_radius / 2.0), star_x + (int)(star_radius * 0.87), star_y + (int) (star_radius / 2.0), FILL); GP142_triangleXY(star2_color, star2_x, star2_y + star2_radius, star2_x + (int)(star2_radius * 0.87), star2_y - (int) (star2_radius / 2.0), star2_x - (int)(star2_radius * 0.87), star2_y - (int) (star2_radius / 2.0), FILL); GP142_triangleXY(star2_color, star2_x, star2_y - star2_radius, star2_x - (int)(star2_radius * 0.87), star2_y + (int) (star2_radius / 2.0), star2_x + (int)(star2_radius * 0.87), star2_y + (int) (star2_radius / 2.0), FILL); /* Draw 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); /* Draw meadow */ GP142_rectangleXY(SEA_GREEN, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, HORIZON, FILL); /* Draw lake */ GP142_ovalXY(BLUE, -GP142_XMAX - 100, HORIZON, GP142_XMAX / 3, HORIZON - 50, FILL); /* 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); /* Draw tree */ GP142_rectangleXY(BROWN, -GP142_XMAX + 50, -GP142_YMAX + 50, -GP142_XMAX + 60, -GP142_YMAX + 100, FILL); GP142_circleXY(tree_color, -GP142_XMAX + 55, -GP142_YMAX + 110, 30); /* Draw boat */ draw_boat(boat_x, boat_y, boat_len, boat_mast, sail_color); /* Draw butteflies */ draw_bug(bug_x, bug_y, bug_size, bug_color); draw_bug(bug2_x, bug2_y, bug2_size, bug2_color); draw_bug(bug3_x, bug3_y, bug3_size, bug3_color); draw_bug(bug4_x, bug4_y, bug4_size, bug4_color); draw_bug(bug5_x, bug5_y, bug5_size, bug5_color); draw_bug(bug6_x, bug6_y, bug6_size, bug6_color); draw_bug(bug7_x, bug7_y, bug7_size, bug7_color); draw_bug(bug8_x, bug8_y, bug8_size, bug8_color); } /*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, "Flower Color"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Acid Trip"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Simulate Wind"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Start Game"); GP142_printfXY(BLACK, text_offset, -GP142_YMAX + 240 , font_size, "Left-click mouse to move the runner up or down"); GP142_printfXY(BLACK, text_offset, -GP142_YMAX + 220, font_size, "Mr. Runner doesn't like butterflies."); GP142_printfXY(BLACK, text_offset, -GP142_YMAX + 200, font_size, "Program will quit if he runs into one!"); } /* 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, int *flower_color, int *moving_boat, int *acid_trip, int *start_game, int *man_y) { 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; /*MOVE MAN*/ if ((*start_game) == TRUE) { if (y > *man_y) *man_y = *man_y + 5; else *man_y = *man_y - 5; } switch(buttonNum) { case 0: /* change flower field colors */ change_colors(petal_color, flower_color); break; case 1: /* make moon blink if desired*/ *acid_trip = *acid_trip * -1; break; case 2: /*turn on or off the wind to make boat move or stop*/ *moving_boat = (*moving_boat) * -1; break; case 3: /*start game*/ *start_game = TRUE; break; default: /*Bad news if this is ever reached! */ GP142_animate(ANI_HALT); something_is_wrong(); break; } } /***************************************************************************** ANIMATED OBJECTS *****************************************************************************/ /* 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) { /* 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, int *bug_color) { *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, *bug_color); } /*move the boat if desired*/ void move_boat(int *boat_x) { (*boat_x) = *boat_x - 5; } /*change the color of an object*/ void blink(int *color) { *color = rand() % MAX_COLORS; } /***************************************************************************** GAME FUNCTIONS *****************************************************************************/ /*man animation*/ void man1(int *man_x, int *man_y) { /*head*/ GP142_circleXY(BLACK, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(BLACK, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(BLACK, *man_x, *man_y, *man_x + 7, *man_y - 3, 2); GP142_lineXY(BLACK, *man_x + 7, *man_y - 3, *man_x + 10, *man_y + 2, 2); GP142_lineXY(BLACK, *man_x, *man_y, *man_x - 7, *man_y - 3, 2); GP142_lineXY(BLACK, *man_x - 7, *man_y - 3, *man_x - 4, *man_y - 8, 2); /*legs*/ GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x - 13, *man_y - 21, 2); GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x + 7, *man_y - 15, 2); GP142_lineXY(BLACK, *man_x + 7, *man_y - 15,*man_x + 4, *man_y - 18, 2); } void man2(int *man_x, int *man_y) { /*head*/ GP142_circleXY(BLACK, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(BLACK, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(BLACK, *man_x, *man_y, *man_x + 4, *man_y - 5, 2); GP142_lineXY(BLACK, *man_x + 4, *man_y - 5, *man_x + 8, *man_y - 3, 2); GP142_lineXY(BLACK, *man_x, *man_y, *man_x - 4, *man_y - 5, 2); GP142_lineXY(BLACK, *man_x - 4, *man_y - 5, *man_x + 2, *man_y - 7, 2); /*legs*/ GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x + 3, *man_y - 21, 2); GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x - 2, *man_y - 15, 2); GP142_lineXY(BLACK, *man_x - 2, *man_y - 15, *man_x - 9, *man_y - 15, 2); } void man3(int *man_x, int *man_y) { /*head*/ GP142_circleXY(BLACK, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(BLACK, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(BLACK, *man_x, *man_y, *man_x + 2, *man_y - 5, 2); GP142_lineXY(BLACK, *man_x + 2, *man_y - 5, *man_x + 4, *man_y - 3, 2); GP142_lineXY(BLACK, *man_x, *man_y, *man_x - 4, *man_y - 5, 2); GP142_lineXY(BLACK, *man_x - 4, *man_y - 5, *man_x + 2, *man_y - 7, 2); /*legs*/ GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x - 3, *man_y - 21, 2); GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x + 4, *man_y - 15, 2); GP142_lineXY(BLACK, *man_x + 4, *man_y - 15, *man_x + 2, *man_y - 19, 2); } void man4(int *man_x, int *man_y) { /*head*/ GP142_circleXY(BLACK, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(BLACK, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(BLACK, *man_x, *man_y, *man_x + 2, *man_y - 5, 2); GP142_lineXY(BLACK, *man_x + 2, *man_y - 5, *man_x + 4, *man_y - 3, 2); GP142_lineXY(BLACK, *man_x, *man_y, *man_x - 2, *man_y - 5, 2); GP142_lineXY(BLACK, *man_x - 2, *man_y - 5, *man_x + 2, *man_y - 7, 2); /*legs*/ GP142_lineXY(BLACK, *man_x, *man_y - 10, *man_x, *man_y - 21, 2); } void erase_man1(int *man_x, int *man_y) { /*head*/ GP142_circleXY(SEA_GREEN, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x + 7, *man_y - 3, 2); GP142_lineXY(SEA_GREEN, *man_x + 7, *man_y - 3, *man_x + 10, *man_y + 2, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x - 7, *man_y - 3, 2); GP142_lineXY(SEA_GREEN, *man_x - 7, *man_y - 3, *man_x - 4, *man_y - 8, 2); /*legs*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x - 13, *man_y - 21, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x + 7, *man_y - 15, 2); GP142_lineXY(SEA_GREEN, *man_x + 7, *man_y - 15,*man_x + 4, *man_y - 18, 2); } void erase_man2(int *man_x, int *man_y) { /*head*/ GP142_circleXY(SEA_GREEN, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x + 4, *man_y - 5, 2); GP142_lineXY(SEA_GREEN, *man_x + 4, *man_y - 5, *man_x + 8, *man_y - 3, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x - 4, *man_y - 5, 2); GP142_lineXY(SEA_GREEN, *man_x - 4, *man_y - 5, *man_x + 2, *man_y - 7, 2); /*legs*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x + 3, *man_y - 21, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x - 2, *man_y - 15, 2); GP142_lineXY(SEA_GREEN, *man_x - 2, *man_y - 15, *man_x - 9, *man_y - 15, 2); } void erase_man3(int *man_x, int *man_y) { /*head*/ GP142_circleXY(SEA_GREEN, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x + 2, *man_y - 5, 2); GP142_lineXY(SEA_GREEN, *man_x + 2, *man_y - 5, *man_x + 4, *man_y - 3, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x - 4, *man_y - 5, 2); GP142_lineXY(SEA_GREEN, *man_x - 4, *man_y - 5, *man_x + 2, *man_y - 7, 2); /*legs*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x - 3, *man_y - 21, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x + 4, *man_y - 15, 2); GP142_lineXY(SEA_GREEN, *man_x + 4, *man_y - 15, *man_x + 2, *man_y - 19, 2); } void erase_man4(int *man_x, int *man_y) { /*head*/ GP142_circleXY(SEA_GREEN, *man_x, *man_y + 10, 5); /*torso*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y + 5, *man_x, *man_y - 10, 2); /*arms*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x + 2, *man_y - 5, 2); GP142_lineXY(SEA_GREEN, *man_x + 2, *man_y - 5, *man_x + 4, *man_y - 3, 2); GP142_lineXY(SEA_GREEN, *man_x, *man_y, *man_x - 2, *man_y - 5, 2); GP142_lineXY(SEA_GREEN, *man_x - 2, *man_y - 5, *man_x + 2, *man_y - 7, 2); /*legs*/ GP142_lineXY(SEA_GREEN, *man_x, *man_y - 10, *man_x, *man_y - 21, 2); } /***************************************************************************** OTHER FUNCTIONS *****************************************************************************/ /* 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!"); }