/* Mark S. Lee * CSE142, Spring 2000 * Secion BC * 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 /* * 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 7 /* 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)) /* Boat flip-points */ #define LEFT 1 #define RIGHT 2 #define UP 3 #define DOWN 4 /* Nuclear explosion */ #define EXPLODE 5 /* 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 /* Number of flowers */ #define NUM_FLOWERS 42 /* Number of Bugs */ #define NUM_BUGS 12 /* Number of Clouds */ #define NUM_CLOUDS 6 /***************************************************************************** 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 girl_x, int boy_x, int girl_y, int boy_y); /* Draw quote from girl */ void draw_quote(void); /* Draw a single bug (buttefly) */ void draw_bug( int bug_x[], int bug_y[], int bug_size[]); /* Change flower field colors */ void change_colors(int *petal_color, int *flower_color); /* Change tree tops */ /* 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 star2_x, int star2_y, int star2_radius, int star2_color, const int flower_x[], const 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 girl_x, int boy_x, int girl_y, int boy_y, int bug_x[], int bug_y[], int bug_size[]); /* 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[]); /* Update moon coordinates moon_x, moon_y for one tick */ void move_moon(int *moon_x, int *moon_y); /* Update clouds coordinates cloud_x, cloud_y for two ticks */ void move_cloud(int cloud_num, int cloud_x[], int cloud_y[]); /* Update boat coordinates boat_x, boat_y for two ticks */ void move_boat(int *boat_x, int *boat_y, int *boat_direction, int *girl_x, int *boy_x, int *girl_y, int *boy_y, int *girl_direction, int *boy_direction, int kiss); /* Update nuke coordinates nuke_x, nuke_y for 3 ticks */ void move_nuke(int *nuke_x, int *nuke_y, int *nuke_direction, int *nuke1_x, int *nuke1_y, int *nuke1_direction, int *nuke1_impact, int *radius, int go, int blast); /* 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, int *flower_color, int *nuke_x, int *nuke_y, int *nuke_direction, int *nuke1_x, int *nuke1_y, int *nuke1_direction, int *nuke1_impact, int *radius, int *go, int *blast, int *cloud_num, int *girl_x, int *boy_x, int *girl_y, int *boy_y, int *girl_direction, int *boy_direction, int *kiss, int *flame_x, int *flame_y, int *set_flame); /* Display error message if internal error is detected. */ void something_is_wrong (void); /* Draw Clouds */ void draw_cloud(int cloud_num, int cloud_x[], int cloud_y[]); /* Draw Nuclear Silos and Missle */ void draw_silo(void); void draw_nuke(int nuke_x, int nuke_y); void draw_nuke1(int nuke1_x, int nuke1_y, int radius); /* Draw Mural */ void draw_mural(void); /* Draw Flames */ void draw_flame(int *flame_x, int *flame_y, int set_flame); /***************************************************************************** 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) { int go = FALSE; /* initial default */ int kiss = FALSE; /* initial default */ int blast = FALSE; /* initial default */ int set_flame = FALSE; /* initial default */ /* 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_x, moon_y; /* screen x and y coordinates */ 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 clouds */ int cloud_x[NUM_CLOUDS] = {GP142_XMAX - 23, GP142_XMAX - 23, GP142_XMAX - 23, GP142_XMAX - 23, GP142_XMAX - 23, GP142_XMAX - 23}; int cloud_y[NUM_CLOUDS] = {GP142_YMAX - 45, GP142_YMAX - 40, GP142_YMAX - 50, GP142_YMAX - 35, GP142_YMAX - 55, GP142_YMAX - 60}; int cloud_num = 1; /* Information about the flowers */ int flower_x[NUM_FLOWERS] = {GP142_XMAX / 3, GP142_XMAX / 3 + 10, GP142_XMAX / 3 - 17, GP142_XMAX / 3 + 25, GP142_XMAX / 3 - 9, GP142_XMAX / 3 + 49, GP142_XMAX / 3 - 24, GP142_XMAX / 3 + 10, GP142_XMAX / 3 + 20, GP142_XMAX / 3 - 27, GP142_XMAX / 3 + 37, GP142_XMAX / 3 - 3, GP142_XMAX / 3 + 60, GP142_XMAX / 3 - 21, GP142_XMAX / 3 - 25, GP142_XMAX / 3 + 6, GP142_XMAX / 3 - 49, GP142_XMAX / 3 + 63, GP142_XMAX / 3 + 70, GP142_XMAX / 3 + 76, GP142_XMAX / 3 + 12, GP142_XMAX / 3 + 89, GP142_XMAX / 3 + 66, GP142_XMAX / 3 + 100, GP142_XMAX / 3 + 106, GP142_XMAX / 3 + 112, GP142_XMAX / 3 + 120, GP142_XMAX / 3 - 33, GP142_XMAX / 3 - 28, GP142_XMAX / 3 + 140, GP142_XMAX / 3 + 148, GP142_XMAX / 3 + 155, GP142_XMAX / 3 + 163, GP142_XMAX / 3 + 170, GP142_XMAX / 3 + 70, GP142_XMAX / 3 + 76, GP142_XMAX / 3 - 52, GP142_XMAX / 3 + 89, GP142_XMAX / 3 + 96, GP142_XMAX / 3 + 100, GP142_XMAX / 3 + 106, GP142_XMAX / 3-10}; int flower_y[NUM_FLOWERS] = {-GP142_YMAX + 40, -GP142_YMAX + 42, -GP142_YMAX + 42, -GP142_YMAX +44, -GP142_YMAX +39, -GP142_YMAX +45, -GP142_YMAX +47, -GP142_YMAX +68, -GP142_YMAX +72, -GP142_YMAX +73, -GP142_YMAX +79, -GP142_YMAX +70, -GP142_YMAX +67, -GP142_YMAX +66, -GP142_YMAX +51, -GP142_YMAX +45, -GP142_YMAX +61, -GP142_YMAX +40, -GP142_YMAX +43, -GP142_YMAX +42, -GP142_YMAX +44, -GP142_YMAX +39, -GP142_YMAX +45, -GP142_YMAX +47, -GP142_YMAX +38, -GP142_YMAX +72, -GP142_YMAX +73, -GP142_YMAX +59, -GP142_YMAX +70, -GP142_YMAX +47, -GP142_YMAX +50, -GP142_YMAX +72, -GP142_YMAX +84, -GP142_YMAX +61, -GP142_YMAX +73, -GP142_YMAX +61, -GP142_YMAX +60, -GP142_YMAX +67, -GP142_YMAX +62, -GP142_YMAX +72, -GP142_YMAX +74, -GP142_YMAX +61}; int flower_radius, petal_radius; /* flower and petal radii */ int flower_color, petal_color; /* flower and petal colors */ /* Information about the tree */ /* Fill in here! */ /* Information about the boat */ int boat_x, boat_y; /* screen x and y coordinates */ int boat_len; /* length of the boat and height of the mast */ int boat_direction; /* direction of the boat left and right */ int girl_x, boy_x; /* x coordinates of the couple */ int girl_y, boy_y; /* y coordinates ofthe couple */ int girl_direction; /*direction of girl left and right */ int boy_direction; /* direction of the boy right and left */ /* Information about the bug(s) */ int bug_x[NUM_BUGS] = {GP142_XMAX / 3 + 20, GP142_XMAX / 3 + 25, GP142_XMAX / 3 + 28, GP142_XMAX / 3 + 32, GP142_XMAX / 3 + 35, GP142_XMAX / 3 + 15, GP142_XMAX / 3 + 12, GP142_XMAX / 3 + 9, GP142_XMAX / 3 + 5, GP142_XMAX / 3, GP142_XMAX / 3 + 18, GP142_XMAX / 3 + 20}; int bug_y[NUM_BUGS] = {-GP142_YMAX +40 + 30, -GP142_YMAX +40 + 33, -GP142_YMAX +40 + 37, -GP142_YMAX +40 + 45, -GP142_YMAX +40 + 27, -GP142_YMAX +40 + 33, -GP142_YMAX +40 + 37, -GP142_YMAX +40 + 30, -GP142_YMAX +40 + 30, -GP142_YMAX +40 + 30, -GP142_YMAX +40 + 26, -GP142_YMAX +40 + 40}; int bug_size[NUM_BUGS] = {MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2, MAX_BUG_SIZE/2}; /* Information about Nuclear Missle going up */ int nuke_x = GP142_XMAX - 198; int nuke_y = GP142_YMAX - 148; int nuke_direction; /* Information about Nuclear Missle going down */ int nuke1_x = 0; int nuke1_y = GP142_YMAX + 150; int radius = 500; int nuke1_direction; int nuke1_impact; /* Information about the flames */ int flame_x = -GP142_XMAX + 158; int flame_y = -GP142_YMAX + 30; /* 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 of the moon */ init_moon(&moon_x, &moon_y); /* 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_x = GP142_XMAX / 3 - 20; boat_y = HORIZON - 25; boat_len = 19; girl_x = GP142_XMAX /3 - 10; boy_x = GP142_XMAX / 3 -30; girl_y = HORIZON -11; boy_y = HORIZON -11; /* Draw initial landscape, buttons, and traffic */ draw_landscape(moon_x,moon_y, 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_x, boat_y, boat_len, girl_x, boy_x, girl_y, boy_y, bug_x, bug_y, bug_size); draw_cloud(cloud_num, cloud_x, cloud_y); draw_buttons(); draw_nuke(nuke_x, nuke_y); draw_silo(); draw_mural(); draw_nuke1(nuke1_x, nuke1_y, radius); /* * 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. */ boat_direction = LEFT; nuke_direction = UP; girl_direction = LEFT; boy_direction = RIGHT; 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, &nuke_x, &nuke_y, &nuke_direction, &nuke1_x, &nuke1_y, &nuke1_direction, &nuke1_impact, &radius, &go, &blast, &cloud_num, &girl_x, &boy_x, &girl_y, &boy_y, &girl_direction, &boy_direction, &kiss, &flame_x, &flame_y, &set_flame); } 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_x, &moon_y); move_cloud(cloud_num, cloud_x, cloud_y); move_boat(&boat_x, &boat_y, &boat_direction, &girl_x, &boy_x, &girl_y, &boy_y, &girl_direction, &boy_direction, kiss); blink_star(&star_radius, &star_color); blink_star(&star2_radius, &star2_color); move_bug(bug_x, bug_y, bug_size); move_nuke(&nuke_x, &nuke_y, &nuke_direction, &nuke1_x, &nuke1_y, &nuke1_direction, &nuke1_impact, &radius, go, blast); break; default: /* unknown event */ break; } /*end switch */ /* Redraw everything */ draw_landscape(moon_x, moon_y, 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_x, boat_y, boat_len, girl_x, boy_x, girl_y, boy_y, bug_x, bug_y, bug_size); draw_cloud(cloud_num, cloud_x, cloud_y); draw_buttons(); draw_nuke(nuke_x, nuke_y); draw_silo(); draw_mural(); draw_flame(&flame_x, &flame_y, set_flame); draw_nuke1(nuke1_x, nuke1_y, radius); } /* end event loop */ /* Termination: shut down graphics window and exit */ GP142_close(); return 0; } /* end main */ /***************************************************************************** INITIALIZATION PROCEDURES *****************************************************************************/ /* initializes the cloud parameters */ /*void init_cloud (int *cloud_x, int *cloud_y){ *cloud_x = GP142_XMAX - 23; *cloud_y = GP142_YMAX - 45; } /* 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 k = 0; for(k = NUM_BUGS - 1; k > 0; k--) { GP142_triangleXY(MAGENTA, bug_x[k], bug_y[k], bug_x[k] - bug_size[k], bug_y[k] + bug_size[k], bug_x[k] - bug_size[k], bug_y[k] - bug_size[k], FILL); GP142_triangleXY(MAGENTA, bug_x[k], bug_y[k], bug_x[k] + bug_size[k], bug_y[k] + bug_size[k], bug_x[k] + bug_size[k], bug_y[k] - bug_size[k], FILL); GP142_lineXY(BLACK, bug_x[k], bug_y[k], bug_x[k] - 3, bug_y[k] + 7, 2); GP142_lineXY(BLACK, bug_x[k], bug_y[k], bug_x[k] + 3, bug_y[k] + 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 girl_x, int boy_x, int girl_y, int boy_y) { GP142_rectangleXY(PURPLE, boat_x - boat_len, boat_y + 13, boat_x + boat_len, boat_y - 4, FILL); GP142_triangleXY(PURPLE, boat_x + boat_len, boat_y - 4, boat_x + boat_len, boat_y + 13, boat_x + boat_len + 15, boat_y + 13, FILL); GP142_triangleXY(PURPLE, boat_x - boat_len - 15, boat_y + 13, boat_x - boat_len, boat_y + 13, boat_x - boat_len, boat_y - 4, FILL); /* girl sitting in the boat */ GP142_rectangleXY(PINK, girl_x, girl_y, girl_x + 5, girl_y + 12, FILL); GP142_circleXY(CHALK, girl_x + 2, girl_y + 15, 5); GP142_pixelXY(BLACK, girl_x, girl_y + 15); GP142_rectangleXY(PINK, girl_x, girl_y + 6, girl_x - 5, girl_y + 9, FILL); GP142_triangleXY(YELLOW, girl_x - 1, girl_y + 19, girl_x + 7, girl_y + 17, girl_x + 9, girl_y + 31, FILL); GP142_lineXY(WHITE, girl_x + 9, girl_y + 31, girl_x + 14, girl_y + 4, 2); GP142_circleXY(PINK, girl_x, girl_y + 6, 2); /*boy sitting in the boat */ GP142_rectangleXY(CYAN, boy_x, boy_y, boy_x - 5, boy_y + 12, FILL); GP142_circleXY(CHALK, boy_x - 2, boy_y + 15, 5); GP142_pixelXY(BLACK, boy_x, boy_y + 15); GP142_rectangleXY(CYAN, boy_x, boy_y + 6, boy_x + 5, boy_y + 9, FILL); GP142_triangleXY(GOLD, boy_x + 2, boy_y + 20, boy_x, boy_y + 22, boy_x - 8, boy_y + 16, FILL); GP142_triangleXY(GOLD, boy_x - 8, boy_y + 16, boy_x, boy_y + 22, boy_x - 10, boy_y + 18, FILL); GP142_triangleXY(GOLD, boy_x - 8, boy_y + 16, boy_x - 12, boy_y + 21, boy_x - 6, boy_y + 19, FILL); GP142_triangleXY(GOLD, boy_x - 6, boy_y + 19, boy_x - 7, boy_y + 24, boy_x - 3, boy_y + 21, FILL); GP142_triangleXY(GOLD, boy_x - 3, boy_y + 21, boy_x - 1, boy_y + 26, boy_x, boy_y + 22, FILL); GP142_circleXY(WHITE, boy_x - 1, boy_y + 26, 1); GP142_circleXY(WHITE, boy_x - 7, boy_y + 24, 1); GP142_circleXY(WHITE, boy_x - 12, boy_y + 21, 1); } /* Draw qoute from girl */ void draw_quote(void) { int quote_x = -GP142_XMAX; int quote_y = HORIZON + 4; GP142_triangleXY(WHITE, quote_x, quote_y, quote_x + 12, quote_y + 10, quote_x + 19, quote_y + 7, FILL); GP142_ovalXY(WHITE, quote_x + 7, quote_y + 3, quote_x + 110, quote_y + 28, FILL); GP142_printfXY(BLACK, quote_x + 14, quote_y + 7, 12, "YOU BASTARD!"); } /* Draw clouds */ void draw_cloud(int cloud_num, int cloud_x[], int cloud_y[]) { int k; for(k = 0; k < cloud_num; k++) { GP142_ovalXY(WHITE, cloud_x[k], cloud_y[k], cloud_x[k] + 28, cloud_y[k] - 10, FILL); GP142_ovalXY(WHITE, cloud_x[k] + 20, cloud_y[k] - 6, cloud_x[k] + 63, cloud_y[k] + 13, FILL); GP142_ovalXY(WHITE, cloud_x[k] + 13, cloud_y[k] - 2, cloud_x[k] + 83, cloud_y[k] - 20, 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 star_x, int star_y, int star_radius, int star_color, int star2_x, int star2_y, int star2_radius, int star2_color, const int flower_x[], const 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 girl_x, int boy_x, int girl_y, int boy_y, int bug_x[], int bug_y[], int bug_size[]) { int text_offset = -GP142_XMAX + 15; /* horizontal offset of text */ int text_size = 12; /* size of text font */ int k; /* Draw the sky */ GP142_rectangleXY(DUSTY_PLUM, -GP142_XMAX, -GP142_YMAX, GP142_XMAX, GP142_YMAX, FILL); /* Draw the moon */ GP142_circleXY(WHITE, 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 the clouds */ /*GP142_ovalXY(WHITE, cloud_x, cloud_y, cloud_x + 28, cloud_y - 10, FILL); GP142_ovalXY(WHITE, cloud_x + 20, cloud_y - 6, cloud_x + 63, cloud_y + 13, FILL); GP142_ovalXY(WHITE, cloud_x + 13, cloud_y - 2, cloud_x + 83, cloud_y - 20, 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(OLIVE, -GP142_XMAX, HORIZON, GP142_XMAX, HORIZON, GP142_XMAX / 4, (2 * GP142_YMAX)/3, FILL); GP142_triangleXY(NAVY_BLUE, -( 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 */ for(k = NUM_FLOWERS - 1; k > 0; k--) { GP142_circleXY(petal_color, flower_x[k], flower_y[k], petal_radius); GP142_circleXY(flower_color, flower_x[k], flower_y[k], flower_radius); GP142_lineXY(FOREST_GREEN, flower_x[k], flower_y[k] - petal_radius, flower_x[k], flower_y[k] - petal_radius - 15, 2); GP142_lineXY(FOREST_GREEN, flower_x[k], flower_y[k] - petal_radius - 10, flower_x[k] + 5, flower_y[k] - petal_radius - 3, 2); } /* Draw 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); /* Draw boat */ draw_boat(boat_x, boat_y, boat_len, girl_x, boy_x, girl_y, boy_y); if (boat_x < -GP142_XMAX -30) { draw_quote(); } /* Draw buttefly */ draw_bug(bug_x, bug_y, bug_size); } /*end draw_landscape */ /* Draw Nuclear Silo */ void draw_silo(void) { int silo_x = GP142_XMAX - 200; int silo_y = GP142_YMAX - 150; GP142_rectangleXY(BLUE, silo_x, silo_y, silo_x + 14, silo_y + 20, FILL); GP142_circleXY(YELLOW, silo_x + 7, silo_y + 10, 5); GP142_triangleXY(RED, silo_x + 7, silo_y + 9, silo_x + 2, silo_y + 9, silo_x + (int)(5.5), silo_y + 6, FILL); GP142_triangleXY(RED, silo_x + 7, silo_y + 9, silo_x + 12, silo_y + 9, silo_x + (int)(9.5), silo_y + 6, FILL); GP142_triangleXY(RED, silo_x + 7, silo_y + 10, silo_x + (int)(4.5), silo_y + 14, silo_x + (int)(9.5), silo_y + 14, FILL); GP142_circleXY(YELLOW, silo_x + 7, silo_y + 10, 2); GP142_circleXY(RED, silo_x + 7, silo_y + 10, 1); } /* Draw Nuclear Missle */ void draw_nuke(int nuke_x, int nuke_y) { GP142_rectangleXY(MED_GRAY, nuke_x, nuke_y, nuke_x + 10, nuke_y + 14, FILL); GP142_triangleXY(MED_GRAY, nuke_x + 10, nuke_y + 14, nuke_x, nuke_y + 14, nuke_x + 6, nuke_y + 19, FILL); if (nuke_y > GP142_YMAX - 100 && nuke_y < GP142_YMAX) { GP142_printfXY(RED, -50, 0, 15, "Nuclear Launch Detected"); } } /* Draw that one mural on the in Seig Hall when you walk up the stairs to the IPL */ void draw_mural(void) { int fireplace_x = -GP142_XMAX + 150, fireplace_y = -GP142_YMAX + 20; int cylinder_x = -GP142_XMAX + 230, cylinder_y = -GP142_YMAX + 60; int umbrella_x = -GP142_XMAX + 190, umbrella_y = -GP142_YMAX + 100; int bcircle_x = GP142_XMAX - 50, bcircle_y = GP142_YMAX - 270; int machine_x = GP142_XMAX - 60, machine_y = -GP142_YMAX + 150; int gong_x = GP142_XMAX - 110, gong_y = -GP142_YMAX + 160; /* Draw Fireplace */ GP142_rectangleXY(WHITE, fireplace_x, fireplace_y, fireplace_x + 30, fireplace_y + 40, FILL); GP142_rectangleXY(LT_GRAY, fireplace_x + 30, fireplace_y, fireplace_x + 80, fireplace_y + 40, FILL); GP142_lineXY(BLACK, fireplace_x + 30, fireplace_y + 40, fireplace_x + 30, fireplace_y,1); GP142_lineXY(BLACK, fireplace_x + 30, fireplace_y + 10, fireplace_x + 80, fireplace_y + 10,1); GP142_lineXY(BLACK, fireplace_x + 30, fireplace_y + 20, fireplace_x + 80, fireplace_y + 20,1); GP142_lineXY(BLACK, fireplace_x + 30, fireplace_y + 30, fireplace_x + 80, fireplace_y + 30,1); GP142_lineXY(BLACK, fireplace_x + 42, fireplace_y + 40, fireplace_x + 42, fireplace_y,1); GP142_lineXY(BLACK, fireplace_x + 57, fireplace_y + 40, fireplace_x + 57, fireplace_y,1); GP142_lineXY(BLACK, fireplace_x + 72, fireplace_y + 40, fireplace_x + 72, fireplace_y,1); GP142_rectangleXY(BLACK, fireplace_x + 5, fireplace_y + 5, fireplace_x + 25, fireplace_y + 35, FILL); GP142_triangleXY(BLACK, fireplace_x + 25, fireplace_y + 35, fireplace_x + 5, fireplace_y + 35, fireplace_x + 15, fireplace_y + 37, FILL); /* Draw Cylinder */ GP142_ovalXY(PEACH, cylinder_x - 10, cylinder_y, cylinder_x + 10, cylinder_y + 40, FILL); GP142_ovalXY(PEACH, cylinder_x - 90, cylinder_y, cylinder_x - 70, cylinder_y + 40, FILL); GP142_rectangleXY(PEACH, cylinder_x, cylinder_y, cylinder_x - 80, cylinder_y + 40, FILL); GP142_ovalXY(BLACK, cylinder_x - 10, cylinder_y, cylinder_x + 10, cylinder_y + 40, 1); GP142_ovalXY(BLACK, cylinder_x - 5, cylinder_y + 10, cylinder_x + 5, cylinder_y + 30, 1); /* Draw Umbrella */ GP142_lineXY(MED_GRAY, umbrella_x, umbrella_y, umbrella_x - 20, umbrella_y + 20, 3); GP142_triangleXY(YELLOW, umbrella_x - 30, umbrella_y + 30, umbrella_x - 40, umbrella_y + 8, umbrella_x - 30, umbrella_y + 13, FILL); GP142_triangleXY(TURQUOISE, umbrella_x - 30, umbrella_y + 30, umbrella_x - 30, umbrella_y + 13, umbrella_x - 15, umbrella_y + 23, FILL); GP142_triangleXY(YELLOW, umbrella_x - 30, umbrella_y + 30, umbrella_x - 15, umbrella_y + 23, umbrella_x - 7, umbrella_y + 33, FILL); /* Draw Circle */ GP142_circleXY(BLUE, bcircle_x, bcircle_y, 13); /* Draw Pipes */ GP142_lineXY(BROWN, bcircle_x, bcircle_y, umbrella_x + 30, umbrella_y, 4); GP142_lineXY(BROWN, bcircle_x, bcircle_y, bcircle_x - 25, bcircle_y - 30, 4); GP142_lineXY(BROWN, bcircle_x, bcircle_y, bcircle_x + 20, bcircle_y - 30, 4); GP142_circleXY(BLACK, bcircle_x, bcircle_y, 4); /* Draw Gong */ GP142_lineXY(BLACK, gong_x - 13, gong_y + 24, gong_x - 13, gong_y - 25, 2); GP142_lineXY(BLACK, gong_x + 13, gong_y + 33, gong_x + 13, gong_y - 15, 2); GP142_ovalXY(GOLD, gong_x - 10, gong_y - 20, gong_x + 10, gong_y + 20, FILL); GP142_lineXY(BLACK, gong_x - 5, gong_y + 10, gong_x - 10, gong_y + 25, 2); GP142_lineXY(BLACK, gong_x + 5, gong_y + 12, gong_x + 10, gong_y + 30, 2); GP142_lineXY(BLACK, gong_x - 13, gong_y + 24, gong_x + 13, gong_y + 33, 2); /* Draw Machine */ GP142_lineXY(MED_GRAY, machine_x, machine_y + 2, machine_x - 10, machine_y - 10, 3); GP142_lineXY(MED_GRAY, machine_x - 10, machine_y - 10, machine_x - 10, machine_y - 15, 3); GP142_lineXY(MED_GRAY, machine_x + 10, machine_y + 5, machine_x + 20, machine_y - 10, 3); GP142_lineXY(MED_GRAY, machine_x + 20, machine_y - 10, machine_x + 20, machine_y - 15, 3); GP142_ovalXY(RED, machine_x, machine_y + 50, machine_x - 30, machine_y, FILL); GP142_ovalXY(RED, machine_x + 45, machine_y + 50, machine_x + 20, machine_y, FILL); GP142_rectangleXY(RED, machine_x - 15, machine_y, machine_x + 33, machine_y + 50, FILL); GP142_rectangleXY(LT_GRAY, machine_x + 8, machine_y + 50, machine_x + 13, machine_y + 65, FILL); GP142_triangleXY(FOREST_GREEN, machine_x + 8, machine_y + 55, machine_x + 10, machine_y + 62, machine_x + 8, machine_y + 60, FILL); GP142_circleXY(BLACK, machine_x - 10, machine_y + 10, 4); GP142_lineXY(CHALK, machine_x - 10, machine_y + 10, machine_x - 28, machine_y, 3); GP142_lineXY(BLACK, machine_x - 55, machine_y + 5, machine_x - 45, machine_y + 15, 4); GP142_lineXY(CHALK, machine_x - 28, machine_y, machine_x - 50, machine_y + 10, 3); GP142_circleXY(BLACK, machine_x - 45, machine_y + 15, 4); GP142_lineXY(LT_GRAY, machine_x - 10, machine_y + 2, machine_x - 20, machine_y - 10, 3); GP142_lineXY(LT_GRAY, machine_x - 20, machine_y - 10, machine_x - 20, machine_y - 20, 3); GP142_lineXY(LT_GRAY, machine_x + 20, machine_y + 5, machine_x + 30, machine_y - 10, 3); GP142_lineXY(LT_GRAY, machine_x + 30, machine_y - 10, machine_x + 30, machine_y - 20, 3); } void draw_flame(int *flame_x, int *flame_y, int set_flame) { int machine_x = GP142_XMAX - 60, machine_y = -GP142_YMAX + 150; if(set_flame == TRUE){ /* flames flickering in the fireplace */ GP142_triangleXY(ORANGE, *flame_x, *flame_y, *flame_x + 5, *flame_y, *flame_x + 1 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); GP142_triangleXY(YELLOW, *flame_x + 2, *flame_y, *flame_x + 7, *flame_y, *flame_x + 3 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); GP142_triangleXY(ORANGE, *flame_x + 4, *flame_y, *flame_x + 9, *flame_y, *flame_x + 5 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); GP142_triangleXY(YELLOW, *flame_x + 6, *flame_y, *flame_x + 11, *flame_y, *flame_x + 7 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); GP142_triangleXY(ORANGE, *flame_x + 8, *flame_y, *flame_x + 13, *flame_y, *flame_x + 9 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); GP142_triangleXY(YELLOW, *flame_x + 10, *flame_y, *flame_x + 13, *flame_y, *flame_x + 11 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); GP142_triangleXY(ORANGE, *flame_x + 12, *flame_y, *flame_x + 15, *flame_y, *flame_x + 13 + (rand() % 3), *flame_y + 23 + (rand() % 5), FILL); /* hand hitting the gong */ GP142_lineXY(BLACK, machine_x - 55+ (rand() % 3), machine_y + 5+ (rand() % 3), machine_x - 45+ (rand() % 3), machine_y + 15+ (rand() % 3), 4); GP142_lineXY(CHALK, machine_x - 28, machine_y, machine_x - 50 + (rand() % 3), machine_y + 10 + (rand() % 3), 3); GP142_circleXY(BLACK, machine_x - 45 + (rand() % 3), machine_y + 15+ (rand() % 3), 4); } } void draw_nuke1(int nuke1_x, int nuke1_y, int radius) { GP142_triangleXY(MED_GRAY, nuke1_x, nuke1_y, nuke1_x + 15, nuke1_y + 15, nuke1_x - 15, nuke1_y + 15, FILL); GP142_rectangleXY(MED_GRAY, nuke1_x + 15, nuke1_y + 15, nuke1_x - 15, nuke1_y + 45, FILL); if(nuke1_y < HORIZON - 50) { GP142_circleXY(LT_GRAY, nuke1_x, HORIZON - 50, radius); } } /***************************************************************************** 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, "Start Fire"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Stop Fire"); i -= BUTTON_HEIGHT; GP142_printfXY(BLACK, text_offset, i, font_size, "Add Clouds"); i -= BUTTON_HEIGHT; GP142_printfXY(YELLOW, text_offset, i, font_size, "Nuke 'em!!"); i -= BUTTON_HEIGHT; GP142_printfXY(RED, text_offset, i+5, font_size - 2, "Romance\nEnhancer"); i -= BUTTON_HEIGHT; GP142_printfXY(RED, text_offset, i, font_size, "Stop Kisses"); } /* 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 *nuke_x, int *nuke_y, int *nuke_direction, int *nuke1_x, int *nuke1_y, int *nuke1_direction, int *nuke1_impact, int *radius, int *go, int *blast, int *cloud_num, int *girl_x, int *boy_x, int *girl_y, int *boy_y, int *girl_direction, int *boy_direction, int *kiss, int *flame_x, int *flame_y, int *set_flame) { 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); break; case 1: /* set fire */ *set_flame = TRUE; break; case 2: /* turn off fire */ *set_flame = FALSE; break; case 3: /* add clouds */ if(*cloud_num < NUM_CLOUDS) (*cloud_num)++; break; case 4: /* move coordinates of nuclear missle */ *go = TRUE; *blast = TRUE; break; case 5: /* move coordinates of couple */ *kiss = TRUE; break; case 6: /* stop kissing */ *kiss = FALSE; 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) --; } } /* Update cloud coordinates cloud_x, cloud_y by one tick */ void move_cloud(int cloud_num, int cloud_x[], int cloud_y[]) { /* Move the clouds to the left. If it reaches the edge, move it */ /* to the other side and down a bit*/ int k; for(k = 0; k < cloud_num; k++) { (cloud_x[k]) -= 4; if (cloud_x[k] < -GP142_XMAX - 80) { cloud_x[k] = -cloud_x[k]; (cloud_y[k]) --; } } } /* Move the boat to the left. If it reaches the edge, flip the */ /* boat and move to the right. */ void move_boat(int *boat_x, int *boat_y, int *boat_direction, int *girl_x, int *boy_x, int *girl_y, int *boy_y, int *girl_direction, int *boy_direction, int kiss) { if(kiss) { if (*girl_direction == LEFT){ (*girl_x) -= (int)(1.4); if (*girl_x - 5 < *boat_x) { *girl_direction = RIGHT; } }else { /* Move girl to the right */ (*girl_x) += (int)(1.4); if (*girl_x - 5 > *boat_x) { *girl_direction = LEFT; } } if (*boy_direction == RIGHT){ (*boy_x) += (int)(1.4); if (*boy_x + 5 > *boat_x) { *boy_direction = LEFT; } }else{ /* Move boy to the left */ (*boy_x) -= (int)(1.4); if (*boy_x + 5 < *boat_x) { *boy_direction = RIGHT; } } } if (*boat_direction == LEFT) { (*boat_x) -= 3; (*girl_x) -= 3; (*boy_x) -= 3; if (*boat_x && *girl_x && * boy_x < -GP142_XMAX -60) { *boat_direction = RIGHT; } }else{ /* move the boat to the right */ (*boat_x) += 3; (*girl_x) += 3; (*boy_x) += 3; if (*boat_x && *girl_x && *boy_x > GP142_XMAX -260) { *boat_direction = LEFT; } } } /* Make the bug(s) move around and flutter */ void move_bug(int bug_x[], int bug_y[], int bug_size[]) { int k = 0; for(k = NUM_BUGS - 1; k > 0; k--) { bug_x[k] = bug_x[k] + rand() % 3 - 1; bug_y[k] = bug_y[k] + rand() % 3 - 1; bug_size[k] = MAX_BUG_SIZE/2 + rand() % MAX_BUG_SIZE/2; draw_bug(bug_x, bug_y, bug_size); } } /* Make nuclear missle move up and down until impact */ void move_nuke(int *nuke_x, int *nuke_y, int *nuke_direction, int *nuke1_x, int *nuke1_y, int *nuke1_direction, int *nuke1_impact, int *radius, int go, int blast) { int font_size = 12; if(go && *nuke1_y < HORIZON - 50 ){ *nuke1_impact = EXPLODE; if (*nuke1_impact == EXPLODE) { *radius = *radius++; } } else if(go) { if (*nuke_direction == UP) { (*nuke_y) += (int)(2.5); } if (*nuke_y > GP142_YMAX) { (*nuke1_y) -= 7; *nuke1_direction = DOWN; } } } /***************************************************************************** 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!"); }