/************************************************************************************************************** * * * NAME: Joel Adriance * * * Sect: 142 BF * * Asgn: HW4 vs 1.1 * * * *Purpose: This program is a game in which the player tries to shoot down randomly generated helicopter * * and bombers. In this version, only the bombers do any damage. The set_up is that that th player * * is given a randomly generated city to protect. Bombers drop bombs on random buildings and destroy * * them, but the player of course tries to shoot down the bombers before this happens. If all the * * buildings are destroyed, the game is over. The object, for now, is to survive as long as possible.* * It is fun because the game keeps track of the level, the number of kills, and the total points. * * The player is awarded points for shooting down any enemy aircraft, but has points deducted each * * time a missile is fired. Some options of the game include randomly generated mountains, buildings * * an stars. It can also produce windows in the buildings and make it day or night. The user can also* * select the color of their units and the enemies units. Furthermore, the user can skip to level 5 * * 10, or 15, and can select a difiiculty setting. The difficulty lies only in the number of building* * the player has to defend. On a hard setting, the player only gets a few buildings, so they must * * work harder to keep them all from being destroyed. On easy, however, the player receives a very * * large city, with many buildings that can be destroyed before they actually lose the game. Finally,* * the game has a help menu, a high scores, and and interesting introductory screen...amd a name.... * * it is called "URBAN DEFENDER." * * * *Details: This program makes generous use of the random number generator. It ranomly starts enemy units,* * controls city construction, and generates random pieces of the destruction of enemy craft and * * buildings. It should be noted that turning the windows on can slow the game to a crawl and is * * not suggested.In future versions, the player will get new trucks for having enough points, * * and will be able to move them into other desired locations. * * * *Changes: This version (1.1) now includes four trucks instead of two, and a conditional in the draw_bomber * funtion that prevents freezing when the game is ended. * * *************************************************************************************************************** /********************** Important Libraries **********************/ #include /*standard input and output*/ #include /*math functions such as pow, sqrt, sin, and cos are used in this program*/ #include /*needed to use the system clock to generate random numbers*/ #include "gp142.h" /*the graphics drawing protocols*/ /******************************* Constants used in the program *******************************/ /*These constants deal with the city, and landscape*/ #define MOUNTAIN_MAX 20 /*Maximum number of mountains to generate*/ #define HORIZON -100 /*The y-value of the horizon line*/ #define ROAD_HEIGHT -202 /*The uppermost y value of the road*/ #define ROAD_BASE -220 /*The bottom of the road*/ #define BUILDING_BASE -230 /*The y_coordinate of the bottom of all the buildings*/ #define ROAD_THICKNESS 7 /*The height of the underside of the road*/ #define GUARD_RAIL_HEIGHT 6 /*The hieght of the rails on the side of the road*/ #define COLUMN_WIDTH 15 /*The width of the columns that support the road*/ #define COLUMN_SPACE 60 /*The spacing between columns*/ #define STRIPE_LENGTH 10 /*Road strip length*/ #define STRIPE_SPACE 5 /*The spacing between stripes*/ #define LANE_WIDTH 3 /*The widthe of one road lane (there are 6)*/ #define STAR_MAX 200 /*The maximum number of starts to generate*/ #define TRUCK_LEVEL -208 /*The y value that all the trucks lie on */ #define BUILDING_MAX 300 /*The Maximum number of buildings that can exist*/ #define CITY_DEFAULT 100 /*The default size of the city*/ #define FLOOR -170 /*The bottom of the land, where it touches the body of water*/ #define WINDOW_WIDTH 2 /*The width of a window*/ #define WINDOW_HEIGHT 4 /*The height of a window*/ #define WINDOW_SPACE 4 /*The spacing between windows*/ /*Object consants*/ #define CHUNK_MAX 40 /*The maximum number of random building chunks to show*/ #define BOMBER_MAX 40 /*The maximum number of bombers that can be on the screen*/ #define CHOPPER_MAX 40 /*The maximum number of chopopers that can be on the screen*/ #define FRAG_MAX 30 /*The maximum number of random ship pieces to show when it's destroyed*/ #define TRUCK_MAX 5 /*The maximum number of trucks that can be on the screen*/ #define POD_LENGTH 28.0 /*The length of the rocket Pod*/ #define POD_HEIGHT 5.0 /*The Height of the Rocket Pod*/ #define PISTON_C_LENGTH 9 /*The length of the trucks piston cylinder*/ #define PISTON_C_CROSS sqrt(85) /*The distance from corner to corner of the trucks piston cylinder*/ /*These are useful in calculating the missile paths and pod angle*/ #define INITIAL_ANGLE_MOUNT_TOP 6.016933258 /*The angle between the Corners of the moving mounts and horizon when it rests on the truck*/ #define INITIAL_ANGLE_MOUNT_BOTTOM 5.961434753 #define INITIAL_ANGLE_FRONT_UPPER 0.0798299857/*The angels between the corners of the pod and the horizon when at rest*/ #define INITIAL_ANGLE_REAR_UPPER 2.35619449 #define INITIAL_ANGLE_REAR_LOWER 3.926990817 #define INITIAL_ANGLE_FRONT_LOWER 6.203355321 #define DISTANCE_POD_REAR_LOWER sqrt(8) /*The distance to the pod corners from the pivot point*/ #define DISTANCE_POD_REAR_UPPER sqrt(8) #define DISTANCE_POD_FRONT_LOWER sqrt(629) #define DISTANCE_POD_FRONT_UPPER sqrt(629) #define DISTANCE_MOUNT_TOP sqrt(130) /*The distance to the Mount corners from the pivot point*/ #define DISTANCE_MOUNT_BOTTOM sqrt(160) #define MISSILE_LENGTH 20.0 /*The standard length of a missile*/ #define FIRE_LENGTH 3.0 /*The length of the fire trail on the missile*/ #define SMOKE1_LENGTH 10.0 /*The length of the first smoke trail on the missile*/ #define SMOKE2_LENGTH 20.0 /*The length of the second smoke trail on the missile*/ /*Detonation constants*/ #define MAX_EXPLODE_RADIUS 25 /*maximum radius of circular debrie that comes from a detonated missile*/ #define MAX_TRASH_DISTANCE 40 /*The maximum radius of the "lines" that come out of missile detonation*/ #define SPRAY_MAX 60 /*The maximum distance of the explosion from a bomb*/ /*Game area definition*/ #define XMAX 296 /*experimentally determined edges of the window*/ #define YMAX 246 #define GAME_AREA_XMAX 286 /*The dimensions of the actual playing area(i.e. not the menu etc)*/ #define GAME_AREA_YMAX 220 #define GAME_AREA_XMIN -286 #define GAME_AREA_YMIN -236 /*General Menu Constants*/ #define HIGH_MAX 10 /*The Maximum number of people in the high scores list*/ /*Main button dimensional constants*/ #define BUTTON_YMAX 252 /*The max and min y value of the main buttons*/ #define BUTTON_YMIN 224 #define MENU_BOTTOM 220 /*The bottom y coordinate of the menu*/ #define FILE_MENU_LENGTH 100 /*The length of pull down menus*/ #define OPTIONS_MENU_LENGTH 142 #define LEVELS_MENU_LENGTH 120 #define SCENERY_MENU_LENGTH 186 #define FILE_XMAX -157 /*posion of the sides of the File button*/ #define FILE_XMIN -238 #define OPTIONS_XMAX -58 /*position of the sides of the Options button*/ #define OPTIONS_XMIN -139 #define LEVELS_XMAX 40 /*position of the sides of the levels button*/ #define LEVELS_XMIN -40 #define SCENERY_XMAX 138 /*position of the sides of the scenery button*/ #define SCENERY_XMIN 59 #define HELP_XMAX 238 /*position of the sides of the help button*/ #define HELP_XMIN 157 /*menu mutton dimensional constants*/ #define NEW_GAME_YMAX 220 /*This list contains the maximum and minimum y value for each*/ #define NEW_GAME_YMIN 198 /*menu button (i.e. pull down). The x-values are known from the*/ #define QUIT_YMAX 198 /*button that opened each sub menu*/ #define QUIT_YMIN 176 #define FILE_RESUME_YMAX 176 #define FILE_RESUME_YMIN 154 #define DAY_YMAX 220 #define DAY_YMIN 198 #define NIGHT_YMAX 198 #define NIGHT_YMIN 176 #define CHANGE_TRUCKS_YMAX 176 #define CHANGE_TRUCKS_YMIN 154 #define CHANGE_ENEMY_YMAX 154 #define CHANGE_ENEMY_YMIN 132 #define RESTORE_YMAX 132 #define RESTORE_YMIN 110 #define WINDOWS_YMAX 110 #define WINDOWS_YMIN 88 #define SCENERY_RESUME_YMAX 88 #define SCENERY_RESUME_YMIN 66 #define EASY_YMAX 220 #define EASY_YMIN 198 #define MEDIUM_YMAX 198 #define MEDIUM_YMIN 176 #define HARD_YMAX 176 #define HARD_YMIN 154 #define HIGH_SCORES_YMAX 154 #define HIGH_SCORES_YMIN 132 #define OPTIONS_RESUME_YMAX 132 #define OPTIONS_RESUME_YMIN 110 #define LEVEL5_YMAX 220 #define LEVEL5_YMIN 198 #define LEVEL10_YMAX 198 #define LEVEL10_YMIN 176 #define LEVEL15_YMAX 176 #define LEVEL15_YMIN 154 #define LEVELS_RESUME_YMAX 154 #define LEVELS_RESUME_YMIN 132 /*Various condition constants*/ #define PI 3.141592654 /*used in calculations of trajectories etc*/ #define LEFT -1 /*The directional multipliers for all vehicles*/ #define RIGHT 1 #define FALSE 0 /*Used all over for conditional checking*/ #define TRUE 1 /****************** ******************* Function Prototypes ******************* ******************/ /******************************************************* prints an error message if an internal error is detected *******************************************************/ void something_is_wrong (void); /*************************************************************************************** If the player has enough kills, this advacnes to the next level and adds enemy aircraft ***************************************************************************************/ void handle_level (int *chopper_total, int *bomber_total, int *objective_kills, int *level, int *kills, int *level_window_counter); /******************************************************************************* Displays en of game message and checks to see if the player made the high scores *******************************************************************************/ void game_over (int high_scores[], int high_levels[], int *spots_filled, int *score, int *level, int *calulated_high_scores, int *top, int can_fire[]); /********************************************************************************** This function displays the high score list with scores and the corresponding levels **********************************************************************************/ void show_high_scores (int high_scores[], int high_levels[], int *spots_filled) ; /********************************************************************************** Uses a counter to slowing speel out the game name, "URBAN DEFENDER" in gren letters **********************************************************************************/ void intro_text (int *intro_timer, int big_missile_x[], int big_missile_y[], int big_missile_direction[], int *missiles_moved); /********************************************************************************* This function draws and moves the large missiles that are part of the intro screen *********************************************************************************/ void draw_intro_missiles (int big_missile_x[], int big_missile_y[], int big_big_missile_direction[], int *missiles_moved); /******************************************************************************** Displays the introductory text such as my name, the version, and a couple buttons ********************************************************************************/ void display_intro_menu (void); /********************************************* Converts and angle in radians to degrees (int) *********************************************/ int radians_to_degrees(double angle); /************************************************ Converts and angle in degrees to radians (double) ************************************************/ double degrees_to_radians (int degree_angle[], int truck); /****************************************************** Rounds a decimal (double) number to the nearest integer ******************************************************/ int rnd(double number); /************************************* Finds the absolute value of an integer *************************************/ /*int abs(int number);*/ /********************************************************************* Displays all scnery including buildings, mountains, stars and windows *********************************************************************/ void make_background(int building_x[], int building_y[], int building_height[], int building_width[], int star_x[], int star_y[], int building_color[], int *windows_on, int *stars_on, int building_destroyed[], int crumbling[], int *nighttime, int *city_size, int mount_x1[], int mount_y1[], int mount_x2[], int mount_y2[], int mount_x3[], int mount_y3[], int mount_color[]); /************************************************************* Displays_foreground_scenery, namely the road and it's elements *************************************************************/ void make_foreground (void); /******************************* Draws the introductory animation *******************************/ void show_intro (int *intro_radius, int *flash_count, int *animation); /*************************************************************************************************************** Deals appropriately with mouse clicks. If a button is clicked, the function calls another which controls the actions of buttons. If it is used during the game, a function is called which changes the actions of the sprites ***************************************************************************************************************/ void handle_mouse_click(int *mouse_x, int *mouse_y, int pod_pivot_x[], int pod_pivot_y[], int objective_angle[], int truck_direction[], int truck); /*********************************************** Does certain actions if certain keys are pressed ***********************************************/ void handle_key_pressed(char *key_pressed, int truck_direction[], int truck_center_x[], int truck_center_y[], int truck); /************************************************************************************************* This function draws the missle launching truck with the pod and the piston in the correct position *************************************************************************************************/ void draw_missle_truck(int truck_center_x[], int truck_center_y[], int pod_pivot_x[], int pod_pivot_y[], int PodTopRear_x[], int PodTopRear_y[], int PodBottomRear_x[], int PodBottomRear_y[], int PodTopFront_x[], int PodTopFront_y[], int PodBottomFront_x[], int PodBottomFront_y[], int MountTop_x[], int MountTop_y[], int MountBottom_x[], int MountBottom_y[], int CylinderTop_x[], int CylinderTop_y[], int CylinderBottom_x[], int CylinderBottom_y[], int truck_direction[], int truck, int playing_trucks, int degree_angle[], int *truck_color); /**************************** Draws the file pull down menu ****************************/ void draw_file_menu (void); /******************************* Draws the options pull down menu *******************************/ void draw_options_menu(int *level) ; /****************************** Draws the levels pull down menu ******************************/ void draw_levels_menu (int *level); /******************************* Draws the scenery pull down menu *******************************/ void draw_scenery_menu (void); /************************************************** Draws the help menu box in the center of the screen **************************************************/ void draw_help_menu (int *page); /*************************************************************************** Finds the corners of the pod in terms of an angle theta and the truck center ***************************************************************************/ void get_pod_coordinates (int degree_angle[], int truck_direction[], int truck, int truck_center_x[], int truck_center_y[], int pod_pivot_x[], int pod_pivot_y[], int PodTopRear_x[], int PodTopRear_y[], int PodBottomRear_x[], int PodBottomRear_y[], int PodTopFront_x[], int PodTopFront_y[], int PodBottomFront_x[],int PodBottomFront_y[], int MountTop_x[], int MountTop_y[], int MountBottom_x[], int MountBottom_y[], int CylinderTop_x[], int CylinderTop_y[], int CylinderBottom_x[],int CylinderBottom_y[]); /**************************************************************** Raises the inclined pod angle by 5 degrees each time it is called ****************************************************************/ void raise_pod_angle( int degree_angle[], int truck_direction[], int truck); /**************************************************************** Lowers the inclined pod angle by 5 degrees each time it is called ****************************************************************/ void lower_pod_angle( int degree_angle[], int truck_direction[], int truck); /***************************************************************************************** Finds the objective angle (the angle between the horizon and a line between the last mouse click position) and returns the value to whatever function it was called from *****************************************************************************************/ int find_objective_angle(int *mouse_x, int *mouse_y, int pod_pivot_x[], int pod_pivot_y[], int truck_direction[], int truck); /********************************** moves the launching pod to position **********************************/ void change_pod_direction(int target_x[], int target_y[], int pod_pivot_x[], int pod_pivot_y[], int objective_angle[], int degree_angle[], int truck_direction[], int truck); /******************************************** draws a standard button from center point x,y ********************************************/ void draw_button (int x, int y); /***************************************************************************************************************** Draws Missile based on its distance from the target, and a refernece poitn, and detonates if the target is reached *****************************************************************************************************************/ void draw_missile (int missile_x[], int missile_y[], int fire_x[], int fire_y[], int smoke1_x[], int smoke1_y[], int smoke2_x[], int smoke2_y[], int end_x[], int end_y[], int pod_pivot_x[], int pod_pivot_y[], int target_x[], int target_y[], int missile_angle[], int distance [], int truck, double count [], int target_selected[], int target_reached[], int can_explode[], int explode_radius[], int trash_distance[], int shoot_debrie[]); /************* moves a missle *************/ void move_missile (int missile_x[], int missile_y[], int fire_x[], int fire_y[], int smoke1_x[], int smoke1_y[], int smoke2_x[], int smoke2_y[], int end_x[], int end_y[], int pod_pivot_x[], int pod_pivot_y[], int target_x[], int target_y[], int missile_angle[], int distance [], int truck, double count[], int truck_direction[]); /************************************************************************ Draw the explosion of the missle at the target that was selected when the missile reaches its target ************************************************************************/ void draw_missile_explosion (int target_x[], int target_y[], int explode_radius[], int truck, int can_explode[], int trash_distance[], int shoot_debrie[], int objective_angle[], int truck_direction[], int can_collide[], int target_selected[], int *score); /********************************************************* Draws Menu buttons as well as the score and kills displays *********************************************************/ void draw_menu (int *score, int *kills, int *objective_kills); /*************************************************************************************************** When this is called, a random city is generated by randomly generating building hieghts, widths, and x_ positions for a number of buildings determined by an array ***************************************************************************************************/ void get_skyline (int building_height[], int building_width[], int building_x[], int building_y[], int building_color[], int building_destroyed[], int crumble_timer[], int *city_size); /************************************************************************************************************** This function controls the drawing of choppers, the placement of the chopper, and the movement of the choppers. **************************************************************************************************************/ void draw_chopper(int chopper_x[], int chopper_y[], int chopper_direction[], int blades[], int chopper_drop[], int *chopper_total, int *enemy_color); /*************************************************************** Places draws and moves bomber and bombs if they are dropped..... ***************************************************************/ void draw_bomber(int bomber_x[], int bomber_y[], int bomb_x[], int bomb_y[], int bomber_direction[], int bomber_speed[], int bomb_target[], int detonated[], int drop_time[], int bomb_dropped[], int can_bomb[], int bomber_leaving[], int building_x[], int falling[], int spray_distnace[], int building[], int building_destroyed[], int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int *bomber_total, int *enemy_color, int *city_size, int *calculated_high_scores); /**************************** Makes bomb explosion graphics ****************************/ void explode_bomb (int bomb_target[], int number, int detonated[], int drop_time[], int spray_distance[]); /************************************************************8 Detects Collisions and resets necessary values ****************************************************/ void collision_detect(int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int target_x[], int target_y[], int chopper_x[], int chopper_y[], int bomber_x[], int bomber_y[], int target_reached[],int can_collide[], int exploding[], int just_got_hit[], int truck, int *score, int *kills, int *chopper_total, int *bomber_total); /*********************************************** Handles scattering ship pieces by calling the move_ship_frags and draw_ship_fragments functions ************************************************/ void scatter_ship_pieces (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int truck, int frag_color[FRAG_MAX][TRUCK_MAX], int destroy_timer[], int exploding[]); /************************************************************ Handles the scattering og building pieces ************************************************************/ void scatter_building_chunks (int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int frag_move_x[CHUNK_MAX][BUILDING_MAX], int frag_move_y[CHUNK_MAX][BUILDING_MAX], int tower, int frag_color[CHUNK_MAX][BUILDING_MAX], int crumble_timerr[], int crumbling[]); /****************************** destroys and resets a hit ship *******************************/ void explode_ship (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX],int target_x[], int target_y[], int ship_x[], int exploding[], int ship, int truck, int just_got_hit[]); /****************************** Draw the ship debrie fragments *****************************/ void draw_ship_frags (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int truck, int frag_color[FRAG_MAX][TRUCK_MAX]) ; /************************************************** Draws the city chunks when a building is desttroyed ***************************************************/ void draw_city_chunks (int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int tower, int chunk_color[CHUNK_MAX][BUILDING_MAX]); /********************* Move the ship fragemts **********************/ void move_ship_frags (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int destroy_timer[], int truck); /************************************************* Move the city chunks when a building is destroyed *************************************************/ void move_city_chunks(int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int crumble_timerr[], int tower); /**************************************************** If a new ship is exploding, generate fragments for it ****************************************************/ void generate_ship_frags (int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int frag_color[FRAG_MAX][TRUCK_MAX], int *enemy_color); /*************************************************** Gnerate random fragments for building destruction ***************************************************/ void generate_city_chunks (int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int chunk_color[CHUNK_MAX][BUILDING_MAX], int *city_size); /********************************************************** This functions generates a random mountain range of MOUNTAIN_MAX mountains **********************************************************/ void generate_mountains (int mount_x1[], int mount_y1[], int mount_x2[], int mount_y2[], int mount_x3[], int mount_y3[], int mount_color[]); /*********************************************************************** This function reinitializes all the values necessary for playing the game and starts the player on level one with no score ***********************************************************************/ void start_new_game (int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int frag_color[FRAG_MAX][TRUCK_MAX], int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int chunk_color[CHUNK_MAX][BUILDING_MAX], int chopper_x[], int chopper_y[], int blades[], int bomber_x[], int bomber_y[], int bomb_x[], int bomb_y[], int bomber_direction[], int bomber_speed[], int bomb_target[], int detonated[], int drop_time[], int bomb_dropped[], int can_bomb[], int bomber_leaving[], int falling[], int spray_distance[], int building[], int building_destroyed[], int star_x[], int star_y[], int truck_center_x[], int truck_center_y[], int pod_pivot_x[], int pod_pivot_y[], int truck_direction[], int playing_trucks, int degree_angle[], int objective_angle[], int missile_angle[], int can_fire[], int target_reached[], int target_selected[], int destroy_timer[], int can_collide[], int explode_radius[], int distance[], int *score, int *level, int bomb_target_hit[], int building_height[], int building_width[], int building_x[], int building_y[], int building_color[], int crumble_timer[], int *kills, int *chopper_total, int *bomber_total, int *truck_color, int *enemy_color, int *city_size , int mount_x1[], int mount_y1[], int mount_x2[], int mount_y2[], int mount_x3[], int mount_y3[], int mount_color[]); /*Main program*/ int main (void) { /*************************************************** Variable declarations ***************************************************/ int /*mountain generation arrays*/ mount_x1[MOUNTAIN_MAX], mount_y1[MOUNTAIN_MAX], /*random mountain coordinates*/ mount_x2[MOUNTAIN_MAX], mount_y2[MOUNTAIN_MAX], mount_x3[MOUNTAIN_MAX], mount_y3[MOUNTAIN_MAX], mount_color[MOUNTAIN_MAX], /*random mountain color*/ /*these arrays help in the generation of ship explosion particles. The arrays containing the various x and y values actually contain random x and y coordinates which are evalutated in reference to the fragement center, which is set as the target when a ship explodes. The frag_move variables contain random values for changes in x an y, i.e. the velocities.They are parallel arrays so each truck can have an explosion at its target.*/ fragment_center_x[FRAG_MAX][TRUCK_MAX], fragment_center_y[FRAG_MAX][TRUCK_MAX], fragment_x1[FRAG_MAX][TRUCK_MAX], fragment_y1[FRAG_MAX][TRUCK_MAX], fragment_x2[FRAG_MAX][TRUCK_MAX], fragment_y2[FRAG_MAX][TRUCK_MAX], fragment_x3[FRAG_MAX][TRUCK_MAX], fragment_y3[FRAG_MAX][TRUCK_MAX], frag_move_x[FRAG_MAX][TRUCK_MAX], frag_move_y[FRAG_MAX][TRUCK_MAX], frag_color[FRAG_MAX][TRUCK_MAX], destroy_timer[TRUCK_MAX], /*Keeps track of the time the particles have been flying*/ /*These are vary similar to the fragment arrays, but are used to generate fragments for buildings that have been hit by bombs. The chunk center is again the target, and the x and y values are positions of triangle corners relative to the center. The color is also randomly generated. The crumble timer keeps track of how long the particles have been in the air and crumbling is either TRUE or FALSE. They are all parallel arrays so each building that is destroyed can have its own particles*/ chunk_center_x[CHUNK_MAX][BUILDING_MAX], chunk_center_y[CHUNK_MAX][BUILDING_MAX], chunk_x1[CHUNK_MAX][BUILDING_MAX], chunk_y1[CHUNK_MAX][BUILDING_MAX], chunk_x2[CHUNK_MAX][BUILDING_MAX], chunk_y2[CHUNK_MAX][BUILDING_MAX], chunk_x3[CHUNK_MAX][BUILDING_MAX], chunk_y3[CHUNK_MAX][BUILDING_MAX], chunk_move_x[CHUNK_MAX][BUILDING_MAX], chunk_move_y[CHUNK_MAX][BUILDING_MAX], chunk_color[CHUNK_MAX][BUILDING_MAX], crumble_timer[BUILDING_MAX], crumbling[BUILDING_MAX], /*These varialbes and arrays contain various pieces of information about the trucks and the users actions with the trucks. The various x and y coordinates are positions relative to an arbitrary center of the truck. Other arrays control the selection and acquisition of targets as well as parts of their detonation*/ pod_pivot_x[TRUCK_MAX], pod_pivot_y[TRUCK_MAX], /*corners of the pod, the mounts, and cylinder*/ PodTopRear_x[TRUCK_MAX], PodTopRear_y[TRUCK_MAX], PodBottomRear_x[TRUCK_MAX], PodBottomRear_y[TRUCK_MAX], PodTopFront_x[TRUCK_MAX], PodTopFront_y[TRUCK_MAX], PodBottomFront_x[TRUCK_MAX], PodBottomFront_y[TRUCK_MAX], MountTop_x[TRUCK_MAX], MountTop_y[TRUCK_MAX], MountBottom_x[TRUCK_MAX], MountBottom_y[TRUCK_MAX], CylinderTop_x[TRUCK_MAX], CylinderTop_y[TRUCK_MAX], CylinderBottom_x[TRUCK_MAX], CylinderBottom_y[TRUCK_MAX], truck_color = FOREST_GREEN, /*The current truck color*/ just_got_hit[TRUCK_MAX], /*This is true when a missile strikes an aircraft*/ target_selected[TRUCK_MAX], /*Has the user designated a valid target?*/ target_x[TRUCK_MAX], /*contains x coordinate of last valid target click*/ target_y[TRUCK_MAX], /*contains y coordinate of last valid target click*/ can_collide[TRUCK_MAX], /*basically checks to see if the missile has detonated*/ chosen_truck = 0, /*This is the number of truck the user currently has selected*/ playing_trucks = 4, /*the number of trucks in the game...may be changeable later*/ objective_angle[TRUCK_MAX], /*The current angle from the horizontal to the target*/ truck_center_x[TRUCK_MAX], truck_center_y[TRUCK_MAX], truck_direction[TRUCK_MAX], /*a multiplier that accounts for drawing of trucks facing either way*/ truck, /*a loop variable for the number of trucks*/ degree_angle[TRUCK_MAX], /*The angle of the truck missile pod*/ /*These arrays control the missiles. Each truck can have one missile on the screen at a time. Many of the arrays simply keep track of what the missile or its explosion is doing, while the rest describe the actual location of the missile on the screen*/ shoot_debrie[TRUCK_MAX], /*Can the missile spray lines out of explosion point?*/ trash_distance[TRUCK_MAX], /*How far have the explosion lines travelled?*/ can_explode[TRUCK_MAX], /*Can the missile spray out colored particles in a circle?*/ distance[TRUCK_MAX], /*The distance the missile has travelled*/ explode_radius[TRUCK_MAX], /*The radius of the particle explosion*/ target_reached[TRUCK_MAX], /*Has the missile reached its target?*/ missile_angle[TRUCK_MAX], /*The angle of the missile*/ missile_x[TRUCK_MAX], /*x coord of bottom of missile*/ missile_y[TRUCK_MAX], /*y coord of bottom of missile*/ fire_x[TRUCK_MAX], /*position of the fire trail relative to the missile bottom*/ fire_y[TRUCK_MAX], smoke1_x[TRUCK_MAX], /*position of first smoke trail from the missile bottom*/ smoke1_y[TRUCK_MAX], smoke2_x[TRUCK_MAX], /*position of the second smoke trail from the missile bottom*/ smoke2_y[TRUCK_MAX], end_x[TRUCK_MAX], /*position of the tip of the missile*/ end_y[TRUCK_MAX], can_fire[TRUCK_MAX], /*can the truck fire a missile?*/ /*These arrays store the bomber cordinates, speed, direction, and various values that are checked to control the bombing actions. Among these arrays are also the bomb center coordinates and the designated target coordinates*/ bomber_x[BOMBER_MAX], /*bomber x and y coordinates*/ bomber_y[BOMBER_MAX], bomber_speed[BOMBER_MAX], /*The speed of the bomber (always positive*/ bomber_direction[BOMBER_MAX], /*the direction of the bomber (-1, or 1)*/ bomber_leaving[BOMBER_MAX], /*is the bomber on its second pass?*/ spray_distance[BOMBER_MAX], /*The distance of exploded building chunks from target*/ bomb_x[BOMBER_MAX], /*bomb coordinates*/ bomb_y[BOMBER_MAX], bomb_target[BOMBER_MAX], /*The semi randomly choosen target for the bombing*/ bomb_target_hit[BOMBER_MAX], /*Has the bomb reached its target?*/ falling[BOMBER_MAX], /*Is the bomb in the air?*/ detonated[BOMBER_MAX], /*Has the bomb initiated exploding?*/ drop_time[BOMBER_MAX], /*time the bomb has been in the air*/ bomb_dropped[BOMBER_MAX], /*has a bomb been dropped?*/ can_bomb[BOMBER_MAX], /*Cacn the bomber drop a bomb? (true from turn_around to frop*/ /*These arrays control the movement and position of the helicopters*/ chopper_x[CHOPPER_MAX], /*chopper x and y coordinates*/ chopper_y[CHOPPER_MAX], chopper_direction[CHOPPER_MAX], /*multiplier for drawing choppper facing left or right*/ chopper_drop[CHOPPER_MAX], /*the random x coord where the chopper descends*/ exploding[CHOPPER_MAX], /*True when the chopper is blowing, false otherwise*/ blades[CHOPPER_MAX], /*are the blades long or short to start?*/ /*Various scenery details*/ tower, /*The building array element number */ stars_on = TRUE, /*display the stars ?*/ star_x[STAR_MAX], /*random star x and y coordinates*/ star_y[STAR_MAX], windows_on = FALSE, /*draw windows on the buildings?*/ building_height[BUILDING_MAX], /*random building height*/ building_width[BUILDING_MAX], /*random building_hieght*/ building_color[BUILDING_MAX], building[BOMBER_MAX], /*The number of the building that is being bombed*/ building_x[BUILDING_MAX], /*The x and y coordinates of the base of a building*/ building_y[BUILDING_MAX], building_destroyed[BUILDING_MAX], /*has the building been bombed?*/ city_size = CITY_DEFAULT, /*the size of the city (changes with difficulty)*/ nighttime = FALSE, /*Is it night?*/ /*Menu variables*/ file_open = FALSE, /*is the file menu open?*/ options_open = FALSE, /*is the options menu open ?*/ levels_open = FALSE, /*is the levels menu open ?*/ scenery_open = FALSE, /*is the scenery menu open ?*/ help_open = FALSE, /*is the help menu open ?*/ page = 1, /*The page that the gelp menu is on*/ high_scores_open = FALSE, /*is the high_score list open?*/ high_scores[HIGH_MAX], /*High score and level stored values*/ high_levels[HIGH_MAX], spots_filled = 0, /*number of high score spots that are filled*/ level_window_counter = 10, /*The time the "next level" window is up*/ top = 0, /*if > 1, the player made the high scores*/ /*Variables controlling the openning screen and animation*/ big_missile_x[2], /*big missiles center point and direction variables*/ big_missile_y[2], big_missile_direction[2], missiles_moved, /*Used to check whether the beginning animation has finsihed*/ level, /*The current level the player is on*/ intro_timer = 0, /*A counter used to time intor animation*/ flash_count = 0, /*the amount of time the screen flashes when the missile hits screen*/ intro_radius = 0, /*The radius mulitplier of the missile parts as it approaches*/ animation = TRUE, /*whether or not the introductory animation id to be shown*/ display_openning = TRUE, /*When false, the intro missile has hit screen and detonated*/ /*miscellaneous variables*/ calculated_high_scores = FALSE, /*Has the high score list been calculated?*/ died = FALSE, /*is the player dead?*/ number = 0, /*an integer used for various loops*/ dead_count, /*This keeps track of how many buildings are destroyed*/ enemy_color = FOREST_GREEN, /*Unit colors*/ chopper_total, /*Enemy totals on screen*/ bomber_total, kills, /*player kills*/ objective_kills, /*kiills needed to advance to next level*/ quit, /*Has the player selected "quit"?*/ event, /*the nature of the input from the player*/ mouse_x, mouse_y, /*x,y coordinates of mouse click*/ score ; /*current score*/ double count[TRUCK_MAX] = {0.0, 0.0, 0.0, 0.0, 0.0}; /*a time variable used to move the missile*/ char key_pressed; /*keyboard input from the player*/ /*Open blank GP142 graphics window*/ GP142_open(); GP142_show_text(0); GP142_logging(LOG_OFF); /*Initialize random number generator to produce a different sequence of numbers each time the program runs*/ srand( (unsigned)time( NULL ) ); /*initialize all high scores to zero. This has to be at beginning so the scores will be saved as long as the player doesn't quite the game*/ for (number = 0; number < HIGH_MAX; number ++){ high_scores[number] = 0; high_levels[number] = 0; } /*initialization of openning animation objects*/ missiles_moved = FALSE; big_missile_x[0] = 480; big_missile_y[0] = 60; big_missile_direction[0] = LEFT; big_missile_x[1] = -480; big_missile_y[1] = -40; big_missile_direction[1] = RIGHT; /*Clean black background*/ GP142_rectangleXY(BLACK, GP142_XMAX, GP142_YMAX, -GP142_XMAX, -GP142_YMAX, 0); /*animation on*/ GP142_animate(ANI_RUN); quit = FALSE; /*This loop shows the introduction screen and allows the user to start a new game or wuit*/ while (display_openning == TRUE) { /*awaits input from the mouse, keyboard, or periodic*/ event = GP142_await_event(&mouse_x, &mouse_y, &key_pressed); /*Evaluate event*/ switch (event) { case GP142_QUIT: quit = TRUE; case GP142_KBD: case GP142_MOUSE: /*The user selects the "NEW GAME" button*/ if (mouse_x < 50 && mouse_x > -50 && mouse_y < -100 && mouse_y > -120 && missiles_moved == TRUE) { start_new_game ( fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, frag_color, chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, chopper_x, chopper_y, blades, bomber_x, bomber_y, bomb_x, bomb_y, bomber_direction, bomber_speed, bomb_target, detonated, drop_time, bomb_dropped, can_bomb, bomber_leaving, falling, spray_distance, building, building_destroyed, star_x, star_y, truck_center_x, truck_center_y, pod_pivot_x, pod_pivot_y, truck_direction, playing_trucks, degree_angle, objective_angle, missile_angle, can_fire, target_reached, target_selected, destroy_timer, can_collide, explode_radius, distance, &score, &level, bomb_target_hit, building_height, building_width, building_x, building_y, building_color, crumble_timer, &kills, &chopper_total, &bomber_total, &truck_color, &enemy_color, &city_size, mount_x1, mount_y1, mount_x2, mount_y2, mount_x3, mount_y3, mount_color); display_openning = FALSE; } /*The user selects the "QUIT" button*/ if (mouse_x < 50 && mouse_x > -50 && mouse_y < -130 && mouse_y > -150 && missiles_moved == TRUE) { quit = TRUE; display_openning = FALSE; } break; case GP142_PERIODIC: /*This draws out the introduction animation int a way that the bullseye is behind the missile, etc*/ GP142_rectangleXY(BLACK, GP142_XMAX, GP142_YMAX, -GP142_XMAX, -GP142_YMAX, 0); /*missiles met in center*/ if (missiles_moved == TRUE) display_intro_menu (); if (animation == TRUE) show_intro(&intro_radius, &flash_count, &animation); else { intro_text(&intro_timer, big_missile_x, big_missile_y, big_missile_direction, &missiles_moved); intro_timer = intro_timer + 1; } break; default: break; } } /*This second while and event loop are the loops for the actual game that is palyed, the other is just for intro*/ GP142_animate(ANI_RUN); /*Main event loop*/ while (!quit) { /*get event*/ event = GP142_await_event(&mouse_x, &mouse_y, &key_pressed); /*Evaluate event*/ switch (event) { case GP142_QUIT: /*User selects quit from menu*/ quit = TRUE; break; case GP142_KBD: /*The player selects the truck he/she wants to fire with*/ switch (key_pressed) { case '1': chosen_truck = 0; break; case '2': chosen_truck = 2; break; case '3': chosen_truck = 3; break; case '4': chosen_truck = 1;; break; default: break; } break; case GP142_MOUSE: /**************************************************************** This large sction of code checks to see if any menus are active based upon where the mouse was clicked and what other menus were open at the time. If a menu is selected. Other menus are closed and game play is halted. if a resume button is clicked, all windows are closed and the player resumes playing the game ****************************************************************/ /*Sets conditions for the file menu to open if clicked on*/ if (mouse_x < FILE_XMAX && mouse_x > FILE_XMIN && mouse_y < BUTTON_YMAX && mouse_y > BUTTON_YMIN) { file_open = TRUE; options_open = FALSE; levels_open = FALSE; scenery_open = FALSE; help_open = FALSE; } /*quits if the user presses this button*/ if (mouse_x < FILE_XMAX && mouse_x > FILE_XMIN && mouse_y < QUIT_YMAX && mouse_y > QUIT_YMIN && file_open == TRUE) quit = TRUE; /*New game*/ if (mouse_x < FILE_XMAX && mouse_x > FILE_XMIN && mouse_y < NEW_GAME_YMAX && mouse_y > NEW_GAME_YMIN && file_open == TRUE) { file_open = FALSE; GP142_animate(ANI_RUN); start_new_game ( fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, frag_color, chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, chopper_x, chopper_y, blades, bomber_x, bomber_y, bomb_x, bomb_y, bomber_direction, bomber_speed, bomb_target, detonated, drop_time, bomb_dropped, can_bomb, bomber_leaving, falling, spray_distance, building, building_destroyed, star_x, star_y, truck_center_x, truck_center_y, pod_pivot_x, pod_pivot_y, truck_direction, playing_trucks, degree_angle, objective_angle, missile_angle, can_fire, target_reached, target_selected, destroy_timer, can_collide, explode_radius, distance, &score, &level, bomb_target_hit, building_height, building_width, building_x, building_y, building_color, crumble_timer, &kills, &chopper_total, &bomber_total, &truck_color, &enemy_color, &city_size, mount_x1, mount_y1, mount_x2, mount_y2, mount_x3, mount_y3, mount_color); } /*The player clicked the fiel_resume button*/ if (mouse_x < FILE_XMAX && mouse_x > FILE_XMIN && mouse_y < FILE_RESUME_YMAX && mouse_y > FILE_RESUME_YMIN && file_open == TRUE){ file_open = FALSE; GP142_animate(ANI_RUN); } /*The player opened the options menu*/ if (mouse_x < OPTIONS_XMAX && mouse_x > OPTIONS_XMIN && mouse_y < BUTTON_YMAX && mouse_y > BUTTON_YMIN) { options_open = TRUE; file_open = FALSE; levels_open = FALSE; scenery_open = FALSE; help_open = FALSE; } /*Sets the game to easy when the player clicks the easy buttone*/ if (mouse_x < OPTIONS_XMAX && mouse_x > OPTIONS_XMIN && mouse_y < EASY_YMAX && mouse_y > EASY_YMIN && options_open == TRUE && level == 1) { options_open = FALSE; city_size = 100; generate_city_chunks ( chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, &city_size); get_skyline (building_height, building_width, building_x, building_y, building_color, building_destroyed, crumble_timer, &city_size); GP142_animate(ANI_RUN); } /*Sets the game to medium when the player clicks the medium buttone*/ if (mouse_x < OPTIONS_XMAX && mouse_x > OPTIONS_XMIN && mouse_y < MEDIUM_YMAX && mouse_y > MEDIUM_YMIN && options_open == TRUE && level == 1) { options_open = FALSE; city_size = 50; generate_city_chunks ( chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, &city_size); get_skyline (building_height, building_width, building_x, building_y, building_color, building_destroyed, crumble_timer, &city_size); GP142_animate(ANI_RUN); } /*sets game to hard when hard button is clicked*/ if (mouse_x < OPTIONS_XMAX && mouse_x > OPTIONS_XMIN && mouse_y < HARD_YMAX && mouse_y > HARD_YMIN && options_open == TRUE && level == 1) { options_open = FALSE; city_size = 20; generate_city_chunks ( chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, &city_size); get_skyline (building_height, building_width, building_x, building_y, building_color, building_destroyed, crumble_timer, &city_size); GP142_animate(ANI_RUN); } /*opens high scores menu if it is clicked*/ if (mouse_x < OPTIONS_XMAX && mouse_x > OPTIONS_XMIN && mouse_y < HIGH_SCORES_YMAX && mouse_y > HIGH_SCORES_YMIN && options_open == TRUE) { options_open = FALSE; high_scores_open = TRUE; GP142_animate(ANI_HALT); } /*close high scores is clicked*/ if (mouse_x > -10 && mouse_x < 40 && mouse_y > - 94 && mouse_y < -76 && high_scores_open == TRUE) { high_scores_open = FALSE; GP142_animate(ANI_RUN); options_open = TRUE; } /*options menu is opend*/ if (mouse_x < OPTIONS_XMAX && mouse_x > OPTIONS_XMIN && mouse_y < OPTIONS_RESUME_YMAX && mouse_y > OPTIONS_RESUME_YMIN && options_open == TRUE) { options_open = FALSE; GP142_animate(ANI_RUN); } /*Sets conditions for the levels menu to open if clicked on*/ if (mouse_x < LEVELS_XMAX && mouse_x > LEVELS_XMIN && mouse_y < BUTTON_YMAX && mouse_y > BUTTON_YMIN) { levels_open = TRUE; file_open = FALSE; options_open = FALSE; scenery_open = FALSE; help_open = FALSE; } /*skip to level 5*/ if (mouse_x < LEVELS_XMAX && mouse_x > LEVELS_XMIN && mouse_y < LEVEL5_YMAX && mouse_y > LEVEL5_YMIN && levels_open == TRUE && level < 5) { level = 5; levels_open = FALSE; level_window_counter = 0; GP142_animate(ANI_RUN); } /*skip to level 10*/ if (mouse_x < LEVELS_XMAX && mouse_x > LEVELS_XMIN && mouse_y < LEVEL10_YMAX && mouse_y > LEVEL10_YMIN && levels_open == TRUE && level < 10) { level = 10; levels_open = FALSE; level_window_counter = 0; GP142_animate(ANI_RUN); } /*skip to level 15*/ if (mouse_x < LEVELS_XMAX && mouse_x > LEVELS_XMIN && mouse_y < LEVEL15_YMAX && mouse_y > LEVEL15_YMIN && levels_open == TRUE && level < 15) { level = 15; levels_open = FALSE; level_window_counter = 0; GP142_animate(ANI_RUN); } /*close levels menu*/ if (mouse_x < LEVELS_XMAX && mouse_x > LEVELS_XMIN && mouse_y < LEVELS_RESUME_YMAX && mouse_y > LEVELS_RESUME_YMIN && levels_open == TRUE) { levels_open = FALSE; GP142_animate(ANI_RUN); } /*Sets conditions for the scenery menu to open if clicked on*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < BUTTON_YMAX && mouse_y > BUTTON_YMIN) { scenery_open = TRUE; levels_open = FALSE; file_open = FALSE; options_open = FALSE; help_open = FALSE; } /*set to nightime*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < NIGHT_YMAX && mouse_y > NIGHT_YMIN && scenery_open == TRUE) { nighttime = TRUE; } /*set to day*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < DAY_YMAX && mouse_y > DAY_YMIN && scenery_open == TRUE) { nighttime = FALSE; } /*change truck color*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < CHANGE_TRUCKS_YMAX && mouse_y > CHANGE_TRUCKS_YMIN && scenery_open == TRUE) { if (truck_color == 23) truck_color = 0; else truck_color = truck_color + 1; } /*change enemy color*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < CHANGE_ENEMY_YMAX && mouse_y > CHANGE_ENEMY_YMIN && scenery_open == TRUE) { if (enemy_color == 24) enemy_color = 0; else enemy_color = enemy_color + 1; generate_ship_frags( fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, frag_color, &enemy_color); } /*restore to default colors*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < RESTORE_YMAX && mouse_y > RESTORE_YMIN && scenery_open == TRUE) { enemy_color = FOREST_GREEN; truck_color = FOREST_GREEN; generate_ship_frags( fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, frag_color, &enemy_color); } /*windows on or off*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < WINDOWS_YMAX && mouse_y > WINDOWS_YMIN && scenery_open == TRUE) { if (windows_on == TRUE) windows_on = FALSE; else windows_on = TRUE; } /*close scenery menu*/ if (mouse_x < SCENERY_XMAX && mouse_x > SCENERY_XMIN && mouse_y < SCENERY_RESUME_YMAX && mouse_y > SCENERY_RESUME_YMIN && scenery_open == TRUE) { scenery_open = FALSE; GP142_animate(ANI_RUN); } /*Sets conditions for the help menu to open if clicked on*/ if (mouse_x < HELP_XMAX && mouse_x > HELP_XMIN && mouse_y < BUTTON_YMAX && mouse_y > BUTTON_YMIN) { help_open = TRUE; scenery_open = FALSE; levels_open = FALSE; file_open = FALSE; options_open = FALSE; page = 1; } /*next help menu page*/ if (mouse_x < -10 && mouse_x > -90 && mouse_y > -69 && mouse_y < -51 && help_open == TRUE && page == 1) { page = 2; } /*close help menu*/ if (mouse_x > 10 && mouse_x < 90 && mouse_y > -69 && mouse_y < -51 && help_open == TRUE) { help_open = FALSE; GP142_animate(ANI_RUN); } /*end of game menu*/ if (mouse_x > 10 && mouse_x < 90 && mouse_y > -69 && mouse_y < -51 && died == TRUE) { died = FALSE; quit = TRUE; } /*new game from end of game menu*/ if (mouse_x > -90 && mouse_x < -10 && mouse_y > -86 && mouse_y < -50 && died == TRUE) { died = FALSE; calculated_high_scores = FALSE; top = 0; GP142_animate(ANI_RUN); start_new_game ( fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, frag_color, chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, chopper_x, chopper_y, blades, bomber_x, bomber_y, bomb_x, bomb_y, bomber_direction, bomber_speed, bomb_target, detonated, drop_time, bomb_dropped, can_bomb, bomber_leaving, falling, spray_distance, building, building_destroyed, star_x, star_y, truck_center_x, truck_center_y, pod_pivot_x, pod_pivot_y, truck_direction, playing_trucks, degree_angle, objective_angle, missile_angle, can_fire, target_reached, target_selected, destroy_timer, can_collide, explode_radius, distance, &score, &level, bomb_target_hit, building_height, building_width, building_x, building_y, building_color, crumble_timer, &kills, &chopper_total, &bomber_total, &truck_color, &enemy_color, &city_size, mount_x1, mount_y1, mount_x2, mount_y2, mount_x3, mount_y3, mount_color); } /*This area handles mouse clickes that are in the valid playing are */ if (mouse_x < GAME_AREA_XMAX && mouse_x > GAME_AREA_XMIN && mouse_y < GAME_AREA_YMAX && mouse_y > GAME_AREA_YMIN) { /*can the truck fire (no other missiles in air), ihas its missile reached its last target?*/ if (can_fire[chosen_truck] == TRUE && target_reached[chosen_truck] == TRUE && can_collide[chosen_truck] == FALSE) { /*this find the objective angle of the truck missile pod if a click happened in the game area and the truck was able to fir*/ handle_mouse_click(&mouse_x, &mouse_y, pod_pivot_x, pod_pivot_y, objective_angle, truck_direction, chosen_truck ); /*Sets target of the selected truck to the mouse coordinates and the coordinates of the missile to inside the truck pod*/ target_x[chosen_truck] = mouse_x; target_y[chosen_truck] = mouse_y; target_selected[ chosen_truck] = TRUE; distance[chosen_truck] = 0; missile_x[chosen_truck] = pod_pivot_x[chosen_truck]; missile_y[chosen_truck] = pod_pivot_y[chosen_truck]; can_explode[chosen_truck] = TRUE; shoot_debrie[chosen_truck] = TRUE; } } break; /*These actions are carried out if the player did not press a key or click the mouse*/ case GP142_PERIODIC: for (truck = 0; truck < playing_trucks; truck ++) { /*This increases or decreases the angle of the pod with each loop, attempting to match the angle with the objective angle determined by the position of the last avlid mouse click*/ change_pod_direction (target_x, target_y, pod_pivot_x, pod_pivot_y, objective_angle, degree_angle, truck_direction, truck); /*checks for target acquisition by checking to see if the pod angle is equal to the objective angle tith an error of plus or minus 10. If tru and if the last missile is finished with its actions, the initial angle of the missile is set to the pods angle to keep it in the pod*/ if (degree_angle[truck] < objective_angle[truck] + 10 && degree_angle[truck] > objective_angle[truck] - 10 && objective_angle[truck] > 0 && objective_angle[truck] < 90 && objective_angle[truck] != 0) { if (target_selected[truck] == TRUE && target_reached[truck] == TRUE) { missile_angle[truck] = objective_angle[truck]; } } /*if the missile coordinates are changes to show it moving*/ if (missile_angle[truck] != 0) { move_missile ( missile_x, missile_y, fire_x, fire_y, smoke1_x, smoke1_y, smoke2_x, smoke2_y, end_x, end_y, pod_pivot_x, pod_pivot_y, target_x, target_y, missile_angle, distance , truck, count, truck_direction); count[truck] = count[truck] + 5; } } break; default: GP142_animate(ANI_HALT); something_is_wrong(); break; } /*Various drawing commands that control the game play*/ /*this draws the background including mountains, buildings, stars, and windows. It is first so it is in the back like it should be, otherwise it would overdraw everything else*/ make_background (building_x, building_y, building_height, building_width, star_x, star_y, building_color, &windows_on, &stars_on, building_destroyed, crumbling, &nighttime, &city_size, mount_x1, mount_y1, mount_x2, mount_y2, mount_x3, mount_y3, mount_color); /*Checks for level advancements and changes the level, and objective kills if the player has reached the next level*/ handle_level (&chopper_total, &bomber_total, &objective_kills, &level, &kills, &level_window_counter); /******************************* Drawing and movement of choppers *******************************/ draw_chopper(chopper_x, chopper_y, chopper_direction, blades, chopper_drop, &chopper_total, &enemy_color) ; /**************************************** Drawing and movement of bombers and bombs ****************************************/ draw_bomber( bomber_x, bomber_y, bomb_x, bomb_y, bomber_direction, bomber_speed, bomb_target, detonated, drop_time, bomb_dropped, can_bomb, bomber_leaving, building_x, falling, spray_distance, building, building_destroyed, chunk_center_x, chunk_center_y, &bomber_total, &enemy_color, &city_size, &calculated_high_scores); /*************************************** This section deals with the movement of the truck, the missiles and the resultant of a hit on an aircraft ****************************************/ for (truck = 0; truck < TRUCK_MAX; truck ++) { /*Draws exploding ship junk for shopper*/ scatter_ship_pieces (fragment_center_x, fragment_center_y, fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, truck, frag_color, destroy_timer, exploding); /*Draws exloping missile warhead*/ draw_missile_explosion (target_x, target_y, explode_radius, truck, can_explode, trash_distance, shoot_debrie, objective_angle, truck_direction, can_collide, target_selected, &score); /*Draws the missile at a location*/ draw_missile ( missile_x, missile_y, fire_x, fire_y, smoke1_x, smoke1_y, smoke2_x, smoke2_y, end_x, end_y, pod_pivot_x, pod_pivot_y, target_x, target_y, missile_angle, distance , truck, count, target_selected,target_reached, can_explode, explode_radius, trash_distance, shoot_debrie); /*Checks to see if any hits have been made*/ collision_detect(fragment_center_x, fragment_center_y, target_x, target_y, chopper_x, chopper_y, bomber_x, bomber_y, target_reached, can_collide, exploding, just_got_hit, truck, &score, &kills, &chopper_total, &bomber_total); } /*buildings blow up*/ for (tower = 0; tower < city_size; tower ++) { scatter_building_chunks ( chunk_center_x, chunk_center_y, chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, tower, chunk_color, crumble_timer, crumbling); } /*Draws the road and its components in front of the city and action*/ make_foreground (); /*Draws the missle trucks in there current location truck_center_x, truck_center_y, with their missile pod pointing towards the last designated target*/ for (truck = 0; truck < TRUCK_MAX; truck ++) { draw_missle_truck( truck_center_x, truck_center_y, pod_pivot_x, pod_pivot_y, PodTopRear_x, PodTopRear_y, PodBottomRear_x, PodBottomRear_y, PodTopFront_x, PodTopFront_y, PodBottomFront_x, PodBottomFront_y, MountTop_x, MountTop_y, MountBottom_x, MountBottom_y, CylinderBottom_x, CylinderBottom_y, CylinderTop_x, CylinderTop_y, truck_direction, truck, playing_trucks, degree_angle, &truck_color); } /**************************************** This code checks to sere whici menus are open, and draws them if they are open ****************************************/ if (file_open == TRUE) { draw_file_menu(); GP142_animate(ANI_HALT); } if (options_open == TRUE) { draw_options_menu(&level); GP142_animate(ANI_HALT); } if (levels_open == TRUE) { draw_levels_menu(&level); GP142_animate(ANI_HALT); } if (scenery_open == TRUE) { draw_scenery_menu(); GP142_animate(ANI_HALT); } if (help_open == TRUE) { draw_help_menu(&page); GP142_animate(ANI_HALT); } if (high_scores_open == TRUE) { show_high_scores (high_scores, high_levels, &spots_filled); GP142_animate(ANI_HALT);} /*Checks to see how many buildings are detroyed by using a for loop with a condition and a counter*/ dead_count = 0; for (number = 0; number < city_size; number ++ ){ if (building_destroyed[number] == TRUE) dead_count = dead_count + 1; } /*If all buildings are destroyed, died = TRUE and ultimitely the game is ended*/ if (dead_count >= city_size) died = TRUE; /*If the game is over, show game_over screen and check high scores*/ if (died == TRUE ) { game_over (high_scores, high_levels,&spots_filled, &score, &level, &calculated_high_scores, &top, can_fire); } /*Draw menus so they overlay all other objects on screen.*/ draw_menu(&score, &kills, &objective_kills); } /*Close window and end program*/ GP142_close(); return (0); } /************************************************************************* ************************************************************************** Functions ************************************************************************** *************************************************************************/ /**************************************************************** Raises the inclined pod angle by 5 degrees each time it is called ****************************************************************/ void raise_pod_angle( int degree_angle[], int truck_direction[], int truck) { /*increase the angle of the pod by 5 degrees*/ degree_angle[truck] = degree_angle[truck] + 5; return; } /**************************************************************** Lowers the inclined pod angle by 5 degrees each time it is called ****************************************************************/ void lower_pod_angle (int degree_angle[], int truck_direction[], int truck) { /*decreases the angle of the pod by 5 degrees*/ degree_angle[truck] = degree_angle[truck] - 5; return; } /*************************************************************************************************************** Deals appropriately with mouse clicks. If a button is clicked, the function calls another which controls the actions of buttons. If it is used during the game, a function is called which changes the actions of the sprites ***************************************************************************************************************/ void handle_mouse_click(int *mouse_x, int *mouse_y, int pod_pivot_x[], int pod_pivot_y[], int objective_angle[], int truck_direction [], int truck) { if (*mouse_x < GP142_XMAX && *mouse_x > -GP142_XMAX && *mouse_y < GP142_YMAX && *mouse_y > -GP142_YMAX) { /*if the mouse click was within the window, finds the objective angle of the truck*/ objective_angle[truck] = find_objective_angle(mouse_x, mouse_y, pod_pivot_x, pod_pivot_y, truck_direction, truck); } return; } /***************************************************************************************** Finds the objective angle (the angle between the horizon and a line between the last mouse click position) and returns the value to whatever function it was called from *****************************************************************************************/ int find_objective_angle(int *mouse_x, int *mouse_y, int pod_pivot_x[], int pod_pivot_y[], int truck_direction[], int truck){ int angle; /*the angle of the horizontal to the target click in degrees, based on the mouse click coords and the position of the trucks missile pod pivot, which is also the missile origin*/ angle = radians_to_degrees (atan(((double)(*mouse_y - pod_pivot_y[truck])) / ((double)(abs(*mouse_x - pod_pivot_x[truck] ))))); return (abs(angle)); } /************************************* Finds the absolute value of an integer *************************************/ /*int abs(int number) { if (number < 0) number = - number; return (number); } /************************************** moves the launching pod to position *************************************/ void change_pod_direction(int target_x[], int target_y[], int pod_pivot_x[], int pod_pivot_y[], int objective_angle[], int degree_angle[], int truck_direction[], int truck) { /*controls the movement of the pod. makes the angle 0 or 90 if the click is out of the trucks angulare range*/ if (truck_direction[truck] == LEFT && target_x[truck] > pod_pivot_x[truck]) objective_angle[truck] = 95; if (truck_direction[truck] == RIGHT && target_x[truck] < pod_pivot_x[truck]) objective_angle[truck] = 95; if (target_y[truck] < pod_pivot_y[truck]) objective_angle[truck] = -5; if (degree_angle[truck] < objective_angle[truck] - 5 && degree_angle[truck] <= 85) raise_pod_angle(degree_angle, truck_direction, truck); if (degree_angle[truck] > objective_angle[truck] + 5 && degree_angle[truck] >= 5) lower_pod_angle(degree_angle, truck_direction, truck); return; } /********************** Draws Missile *********************/ void draw_missile (int missile_x[], int missile_y[], int fire_x[], int fire_y[], int smoke1_x[], int smoke1_y[], int smoke2_x[], int smoke2_y[], int end_x[], int end_y[], int pod_pivot_x[], int pod_pivot_y[], int target_x[], int target_y[], int missile_angle[], int distance [], int truck, double count[], int target_selected[], int target_reached[], int can_explode[], int explode_radius[], int trash_distance[], int shoot_debrie []) { if (missile_angle[truck] != 0 && target_selected[truck] == TRUE) { /*This checks to see if the missle end has reached the target*/ if (distance[truck] < rnd(sqrt(pow(target_x[truck] - pod_pivot_x[truck], 2) + pow(target_y[truck] - pod_pivot_y[truck],2))) - MISSILE_LENGTH) { /*actual missle*/ GP142_lineXY(LT_GRAY, missile_x[truck], missile_y[truck], end_x[truck], end_y[truck], 1); /*smoke trail data*/ GP142_lineXY(WHITE, missile_x[truck], missile_y[truck], smoke2_x[truck], smoke2_y[truck], 1); GP142_lineXY(WHITE, missile_x[truck], missile_y[truck], smoke1_x[truck], smoke1_y[truck], 2); GP142_lineXY(GOLD, missile_x[truck], missile_y[truck], fire_x[truck], fire_y[truck], 2); target_reached[truck] = FALSE; } else { missile_angle[truck] = 0; distance[truck] = 0; can_explode[truck] = TRUE; shoot_debrie[truck] = TRUE; count[truck] = 0; target_selected[truck] = FALSE; target_reached[truck] = TRUE; explode_radius[truck] = 0; trash_distance[truck] = 0; } } return; } /**************************** move_missle ***************************/ void move_missile (int missile_x[], int missile_y[], int fire_x[], int fire_y[], int smoke1_x[], int smoke1_y[], int smoke2_x[], int smoke2_y[], int end_x[], int end_y[], int pod_pivot_x[], int pod_pivot_y[], int target_x[], int target_y[], int missile_angle[], int distance [], int truck, double count[],int truck_direction[]) { /*increases the distance between the missile and the truck*/ distance[truck] = distance[truck] + rnd(count[truck]); /*adds to the x and y coordinates of the missile, smoke and fir ends using trigonometry. The new posiotion is found by adding the oringinal coordinate to the cosine or sine of the angle it is travelling in times the distance*/ missile_x[truck] = pod_pivot_x[truck] + truck_direction[truck] * rnd((double)distance[truck] * cos(degrees_to_radians(missile_angle, truck))); missile_y[truck] = pod_pivot_y[truck] + rnd((double)distance[truck] * sin(degrees_to_radians(missile_angle, truck))); end_x[truck] = missile_x[truck] + truck_direction[truck] * rnd(MISSILE_LENGTH * cos(degrees_to_radians(missile_angle, truck))); end_y[truck] = missile_y[truck] + rnd(MISSILE_LENGTH * sin(degrees_to_radians(missile_angle, truck))); smoke2_x[truck] = missile_x[truck] - truck_direction[truck] * rnd(SMOKE2_LENGTH * cos(degrees_to_radians(missile_angle, truck))); smoke2_y[truck] = missile_y[truck] - rnd(SMOKE2_LENGTH * sin(degrees_to_radians(missile_angle, truck))); smoke1_x[truck] = missile_x[truck] - truck_direction[truck] * rnd(SMOKE1_LENGTH * cos(degrees_to_radians(missile_angle, truck))); smoke1_y[truck] = missile_y[truck] - rnd(SMOKE1_LENGTH * sin(degrees_to_radians(missile_angle, truck))); fire_x[truck] = missile_x[truck] - truck_direction[truck] * rnd(FIRE_LENGTH * cos(degrees_to_radians(missile_angle, truck))); fire_y[truck] = missile_y[truck] - rnd(FIRE_LENGTH * sin(degrees_to_radians(missile_angle, truck))); return; } /************************************************************************ Draw the explosion of the missle at the target that was selected when the missile reaches its target ************************************************************************/ void draw_missile_explosion (int target_x[], int target_y[], int explode_radius[], int truck, int can_explode[], int trash_distance[], int shoot_debrie[], int objective_angle[], int truck_direction[], int can_collide[], int target_selected[], int *score) { int color; double theta; /*draws 6 concentric circles of randomly colored particles that simulate an explosion*/ if (target_selected[truck] == FALSE && can_explode[truck] == TRUE) { if (explode_radius[truck] < MAX_EXPLODE_RADIUS) { /*particles occur every PI / 12 radians*/ for (theta = 0; theta <= 2 * PI; theta = theta + PI / 12) { switch (rand() % 3) { case 0: color = RED; break; case 1: color = YELLOW; break; case 2: color = ORANGE; break; default: break; } GP142_pixelXY(color, target_x[truck] + rnd(explode_radius[truck] * cos(theta)), target_y[truck] + rnd(explode_radius[truck] * sin(theta))); GP142_pixelXY(color, target_x[truck] + rnd(explode_radius[truck] / 2 * cos(theta)), target_y[truck] + rnd(explode_radius[truck] / 2 * sin(theta))); GP142_pixelXY(color, target_x[truck] + rnd(explode_radius[truck] / 3 * cos(theta)), target_y[truck] + rnd(explode_radius[truck] / 3* sin(theta))); GP142_pixelXY(color, target_x[truck] + rnd(explode_radius[truck] / 4 * cos(theta)), target_y[truck] + rnd(explode_radius[truck] / 4 * sin(theta))); GP142_pixelXY(color, target_x[truck] + rnd(explode_radius[truck] / 5 * cos(theta)), target_y[truck] + rnd(explode_radius[truck] / 5 * sin(theta))); GP142_pixelXY(color, target_x[truck] + rnd(explode_radius[truck] / 6 * cos(theta)), target_y[truck] + rnd(explode_radius[truck] / 6 * sin(theta))); } explode_radius[truck] = explode_radius[truck] + 2; /*increses distance from center each time to simulate expansion*/ } else { /*if the explosion reaches maximum size, reset the explode radius and tell the truck it can fire again*/ explode_radius[truck] = 0; can_explode[truck] = FALSE; } } /*This draws streaks that fly of in the direction of the objective angle, plus or minus PI / 16 and PI / 32 radians*/ if (target_selected[truck] == FALSE && shoot_debrie[truck] == TRUE) { if (trash_distance[truck] < MAX_TRASH_DISTANCE) { GP142_lineXY(WHITE, target_x[truck], target_y[truck], target_x[truck] + truck_direction[truck] * rnd(trash_distance[truck] / 1.5 * cos(degrees_to_radians(objective_angle, truck) + PI / 16)), target_y[truck] + rnd(trash_distance[truck] / 1.5 * sin(degrees_to_radians(objective_angle, truck) + PI / 16)), 1); GP142_lineXY(YELLOW, target_x[truck], target_y[truck], target_x[truck] + truck_direction[truck] * rnd(trash_distance[truck] / 1.5 * cos(degrees_to_radians(objective_angle, truck))), target_y[truck] + rnd(trash_distance[truck] / 1.5 * sin(degrees_to_radians(objective_angle, truck))), 1); GP142_lineXY(LT_GRAY, target_x[truck], target_y[truck], target_x[truck] + truck_direction[truck] * rnd(trash_distance[truck] / 1.5 * cos(degrees_to_radians(objective_angle, truck) - PI / 16)), target_y[truck] + rnd(trash_distance[truck] / 1.5 * sin(degrees_to_radians(objective_angle, truck) - PI / 16)), 1); GP142_lineXY(YELLOW, target_x[truck], target_y[truck], target_x[truck] + truck_direction[truck] * rnd(trash_distance[truck] * cos(degrees_to_radians(objective_angle, truck) + PI / 32)), target_y[truck] + rnd(trash_distance[truck] * sin(degrees_to_radians(objective_angle, truck) + PI / 32)), 1); GP142_lineXY(WHITE, target_x[truck], target_y[truck], target_x[truck] + truck_direction[truck] * rnd(trash_distance[truck] * cos(degrees_to_radians(objective_angle, truck) - PI / 32)), target_y[truck] + rnd(trash_distance[truck] * sin(degrees_to_radians(objective_angle, truck) - PI / 32)), 1); trash_distance[truck] = trash_distance[truck] + 3; can_collide[truck] = TRUE; } else{ /*resets counter and distances if the explosion is complete*/ *score = *score - 15; trash_distance[truck] = 0; shoot_debrie[truck] = FALSE; can_collide[truck] = FALSE; } } return; } /************************************************************* Generates an entirely new city by randomly generating heights positions and widths for buildings *************************************************************/ void get_skyline (int building_height[], int building_width[], int building_x[], int building_y[], int building_color[], int building_destroyed[], int crumble_timer[], int *city_size) { int number; /*randomly generates buildings of three colors*/ for (number = 0; number < *city_size; number ++) { switch (rand() % 3) { case 0: building_color[number] = LT_GRAY; break; case 1: building_color[number] = MED_GRAY; break; case 2: building_color[number] = WHITE; break; default: break; } crumble_timer[number] = 0; building_destroyed[number] = FALSE; building_height[number] = ((rand() % 200) + 50); building_width [number] = (rand() % 30) + 35; building_x[number] = (rand() % 600) - 300; building_y[number] = BUILDING_BASE; } return; } /************************************************************************************************************** This function controls the drawing of choppers, the placement of the chopper, and the movement of the choppers. **************************************************************************************************************/ void draw_chopper(int chopper_x[], int chopper_y[], int chopper_direction[], int blades[], int chopper_drop[], int *chopper_total, int *enemy_color) { int number; for (number = 0; number < *chopper_total; number ++) { /*Basic Outline*/ GP142_rectangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 13, chopper_y[number] + 1, chopper_x[number] - chopper_direction[number] * 23, chopper_y[number] + 13, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 12, chopper_x[number] + chopper_direction[number] * 13, chopper_y[number] + 1, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 24, chopper_y[number] + 6, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 4, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 22, chopper_y[number] + 4, chopper_x[number] - chopper_direction[number] * 17, chopper_y[number] + 2, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 20, chopper_y[number] + 8, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 6, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] - chopper_direction[number] * 23, chopper_y[number] + 13, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 6, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] - chopper_direction[number] * 22, chopper_y[number] + 17, chopper_x[number] - chopper_direction[number] * 29, chopper_y[number] + 13, 0); /*Window*/ GP142_rectangleXY(BLACK, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 12, chopper_x[number] + chopper_direction[number] * 13, chopper_y[number] + 8, 0); GP142_triangleXY(BLACK, chopper_x[number] + chopper_direction[number] * 20, chopper_y[number] + 8, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 12, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 8, 0); /*Details*/ GP142_triangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 24, chopper_y[number] + 6, chopper_x[number] + chopper_direction[number] * 20, chopper_y[number] + 8, chopper_x[number] + chopper_direction[number] * 20, chopper_y[number] + 6, 0); GP142_rectangleXY(*enemy_color, chopper_x[number] + chopper_direction[number] * 9, chopper_y[number] + 15, chopper_x[number] + chopper_direction[number] * 5, chopper_y[number] + 13, 0); GP142_triangleXY(*enemy_color, chopper_x[number] - chopper_direction[number] * 18, chopper_y[number] + 13, chopper_x[number] - chopper_direction[number] * 22, chopper_y[number] + 17, chopper_x[number] - chopper_direction[number] * 22, chopper_y[number] + 13, 0); GP142_triangleXY(*enemy_color, chopper_x[number] - chopper_direction[number] * 23, chopper_y[number] + 1, chopper_x[number] - chopper_direction[number] * 23, chopper_y[number] + 6, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 6, 0); /*Outlines*/ GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 19, chopper_y[number] + 1, chopper_x[number] - chopper_direction[number] * 23, chopper_y[number] + 1, 1); /*Nose*/ GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 22, chopper_y[number] + 2, chopper_x[number] + chopper_direction[number] * 19, chopper_y[number] + 1, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 24, chopper_y[number] + 4, chopper_x[number] + chopper_direction[number] * 22, chopper_y[number] + 2, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 24, chopper_y[number] + 6, chopper_x[number] + chopper_direction[number] * 24, chopper_y[number] + 4, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 20, chopper_y[number] + 8, chopper_x[number] + chopper_direction[number] * 24, chopper_y[number] + 6, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 17, chopper_y[number] + 12, chopper_x[number] + chopper_direction[number] * 13, chopper_y[number] + 13, 1); /*top*/ GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 13, chopper_y[number] + 13, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 13, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 10, chopper_y[number] + 13, chopper_x[number] + chopper_direction[number] * 9 , chopper_y[number] + 15, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 9, chopper_y[number] + 15, chopper_x[number] + chopper_direction[number] * 5, chopper_y[number] + 15, 1); GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 5, chopper_y[number] + 15, chopper_x[number] + chopper_direction[number] * 4, chopper_y[number] + 13, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 18, chopper_y[number] + 13, chopper_x[number] - chopper_direction[number] * 22, chopper_y[number] + 17, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 22, chopper_y[number] + 17, chopper_x[number] - chopper_direction[number] * 29, chopper_y[number] + 17, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 29, chopper_y[number] + 17, chopper_x[number] - chopper_direction[number] * 29, chopper_y[number] + 13, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 29, chopper_y[number] + 13, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 11, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 11, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 6, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 28, chopper_y[number] + 6, chopper_x[number] - chopper_direction[number] * 23, chopper_y[number] + 1, 1); /*Draw Moving blades*/ GP142_lineXY(BLACK, chopper_x[number] + chopper_direction[number] * 7, chopper_y[number] + 15, chopper_x[number] + chopper_direction[number] * 7, chopper_y[number] + 17, 2); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 25, chopper_y[number] + 17, chopper_x[number] - chopper_direction[number] * 25, chopper_y[number] + 19, 2); if (blades[number] == FALSE) { GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 13, chopper_y[number] + 17, chopper_x[number] + chopper_direction[number] * 27, chopper_y[number] + 17, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 10, chopper_y[number] + 19, chopper_x[number] - chopper_direction[number] * 40, chopper_y[number] + 19, 1); } if (blades[number] == TRUE) { GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 5, chopper_y[number] + 19, chopper_x[number] - chopper_direction[number] * 45, chopper_y[number] + 19, 1); GP142_lineXY(BLACK, chopper_x[number] - chopper_direction[number] * 8 , chopper_y[number] + 17, chopper_x[number] + chopper_direction[number] * 22 , chopper_y[number] + 17, 1); } if (blades[number] == TRUE) blades[number] = FALSE; else blades[number] = TRUE; /*This controlls the movement and initial position of the chopper. if it goes 40 pixels off the screen, a new random starting locatoin and random drop distance is calculated and used to reposition a destroyed or escaped chopper*/ if (chopper_x[number] > XMAX + 40 || chopper_x[number] < -XMAX - 40) { chopper_x[number] = ((rand () % 600) - 300); chopper_y[number] = 250; chopper_drop[number] = ((rand() % 250) - 100); if (rand() % 2 == 0) chopper_direction[number] = LEFT; else chopper_direction[number] = RIGHT; } if (chopper_y[number] > chopper_drop[number]) chopper_y[number] = chopper_y[number] - 8; else chopper_x[number] = chopper_x[number] + chopper_direction[number] * 5; } return; } /************************************************* Places draws and moves bomber and bombs if they are dropped..... *************************************************/ void draw_bomber(int bomber_x[], int bomber_y[], int bomb_x[], int bomb_y[], int bomber_direction[], int bomber_speed[], int bomb_target[], int detonated[], int drop_time[], int bomb_dropped[], int can_bomb[], int bomber_leaving[], int building_x[], int falling[], int spray_distance[], int building[], int building_destroyed[], int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int *bomber_total, int *enemy_color, int *city_size, int *calculated_high_scores) { int number, chunk; for (number = 0; number < *bomber_total; number ++) { /*Drawing of the Bomber at bomber_x, bomber_y*/ /*Main body*/ GP142_rectangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 16, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 1, 0); /*MainNose*/ GP142_rectangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 38, bomber_y[number] + 4, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 2, 0); GP142_rectangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 44, bomber_y[number] + 9, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 4, 0); GP142_rectangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 39, bomber_y[number] + 11, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 9, 0); GP142_rectangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 34, bomber_y[number] + 15, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 11, 0); GP142_triangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 43, bomber_y[number] + 4, bomber_x[number] + bomber_direction[number] * 38, bomber_y[number] + 4, bomber_x[number] + bomber_direction[number] * 38, bomber_y[number] + 2, 0); GP142_triangleXY(*enemy_color, bomber_x[number] + bomber_direction[number] * 43, bomber_y[number] + 9, bomber_x[number] + bomber_direction[number] * 39, bomber_y[number] + 11, bomber_x[number] + bomber_direction[number] * 39, bomber_y[number] + 9, 0); /*Main tail section*/ GP142_triangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 10, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 10, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 1, 0); GP142_rectangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 10, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 16, 0); GP142_rectangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 34, bomber_y[number] + 18, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 16, 0); GP142_rectangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 16, 0); GP142_triangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 34, bomber_y[number] + 18, bomber_x[number] - bomber_direction[number] * 34, bomber_y[number] + 16, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 16, 0); GP142_triangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 18, bomber_x[number] - bomber_direction[number] * 34, bomber_y[number] + 18, 0); GP142_triangleXY(*enemy_color, bomber_x[number] - bomber_direction[number] * 49, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 16, 0); /*Window*/ GP142_rectangleXY(BLACK, bomber_x[number] + bomber_direction[number] * 36, bomber_y[number] + 14, bomber_x[number] + bomber_direction[number] * 34, bomber_y[number] + 12, 0); GP142_triangleXY(BLACK, bomber_x[number] + bomber_direction[number] * 38, bomber_y[number] + 12, bomber_x[number] + bomber_direction[number] * 36, bomber_y[number] + 14, bomber_x[number] + bomber_direction[number] * 36, bomber_y[number] + 12, 0); /*Draw nose outlines*/ GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 1, bomber_x[number] + bomber_direction[number] * 38, bomber_y[number] + 2, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 38, bomber_y[number] + 2, bomber_x[number] + bomber_direction[number] * 43, bomber_y[number] + 4, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 43, bomber_y[number] + 4, bomber_x[number] + bomber_direction[number] * 44, bomber_y[number] + 6, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 44, bomber_y[number] + 6, bomber_x[number] + bomber_direction[number] * 44, bomber_y[number] + 8, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 44, bomber_y[number] + 8, bomber_x[number] + bomber_direction[number] * 43, bomber_y[number] + 9, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 43, bomber_y[number] + 9, bomber_x[number] + bomber_direction[number] * 39, bomber_y[number] + 11, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 36, bomber_y[number] + 14, bomber_x[number] + bomber_direction[number] * 34, bomber_y[number] + 15, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 34, bomber_y[number] + 15, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 16, 1); /*Draw mid-body and wing outline*/ GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 1, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 1, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 30, bomber_y[number] + 16, bomber_x[number] + bomber_direction[number] * 13, bomber_y[number] + 16, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 13, bomber_y[number] + 16, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 17, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 17, bomber_x[number] - bomber_direction[number] * 9, bomber_y[number] + 16, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 9, bomber_y[number] + 16, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 16, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 13, bomber_y[number] + 16, bomber_x[number] + bomber_direction[number] * 15, bomber_y[number] + 15, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 15, bomber_y[number] + 15, bomber_x[number] + bomber_direction[number] * 15, bomber_y[number] + 14, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 15, bomber_y[number] + 14, bomber_x[number] + bomber_direction[number] * 13, bomber_y[number] + 13, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 13, bomber_y[number] + 13, bomber_x[number] - bomber_direction[number] * 7 , bomber_y[number] + 9, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 7, bomber_y[number] + 9, bomber_x[number] - bomber_direction[number] * 15, bomber_y[number] + 9, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 15, bomber_y[number] + 9, bomber_x[number] - bomber_direction[number] * 10, bomber_y[number] + 16, 1); /*Draw enginew*/ GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 12, bomber_y[number] + 11, bomber_x[number] + bomber_direction[number] * 7, bomber_y[number] + 11, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 7, bomber_y[number] + 11, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 10, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 10, bomber_x[number] + bomber_direction[number] * 1, bomber_y[number] + 10, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 1, bomber_y[number] + 10, bomber_x[number], bomber_y[number] + 9, 1); GP142_lineXY(BLACK, bomber_x[number], bomber_y[number] + 9, bomber_x[number] - bomber_direction[number] * 3, bomber_y[number] + 9, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 3, bomber_y[number] + 9, bomber_x[number] - bomber_direction[number] * 5, bomber_y[number] + 8, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 5, bomber_y[number] + 8, bomber_x[number] - bomber_direction[number] * 5, bomber_y[number] + 7, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 5, bomber_y[number] + 7, bomber_x[number] - bomber_direction[number] * 3, bomber_y[number] + 6, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 3, bomber_y[number] + 6, bomber_x[number] , bomber_y[number] + 6, 1); GP142_lineXY(BLACK, bomber_x[number], bomber_y[number] + 6, bomber_x[number] + bomber_direction[number] * 1, bomber_y[number] + 5, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 1, bomber_y[number] + 5, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 5, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 5, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 7, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 6, bomber_y[number] + 7, bomber_x[number] + bomber_direction[number] * 7, bomber_y[number] + 6, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 7, bomber_y[number] + 6, bomber_x[number] + bomber_direction[number] * 12, bomber_y[number] + 6, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 12, bomber_y[number] + 6, bomber_x[number] + bomber_direction[number] * 12, bomber_y[number] + 11, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 7, bomber_y[number] + 11, bomber_x[number] + bomber_direction[number] * 7, bomber_y[number] + 6, 1); GP142_lineXY(BLACK, bomber_x[number] + bomber_direction[number] * 1, bomber_y[number] + 10, bomber_x[number] + bomber_direction[number] * 1, bomber_y[number] + 5, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 3, bomber_y[number] + 9, bomber_x[number] - bomber_direction[number] * 3, bomber_y[number] + 6, 1); /*Tail section_outline*/ GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 1, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 10, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 10, bomber_x[number] - bomber_direction[number] * 47, bomber_y[number] + 12, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 47, bomber_y[number] + 12, bomber_x[number] - bomber_direction[number] * 47, bomber_y[number] + 14, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 47, bomber_y[number] + 14, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 16, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 16, bomber_x[number] - bomber_direction[number] * 49, bomber_y[number] + 27, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 49, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 44, bomber_y[number] + 28, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 44, bomber_y[number] + 28, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 27, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 34, bomber_y[number] + 18, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 34, bomber_y[number] + 18, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 16, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 42, bomber_y[number] + 27, bomber_x[number] - bomber_direction[number] * 44, bomber_y[number] + 26, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 44, bomber_y[number] + 26, bomber_x[number] - bomber_direction[number] * 49, bomber_y[number] + 27, 1); GP142_lineXY(BLACK, bomber_x[number] - bomber_direction[number] * 25, bomber_y[number] + 1, bomber_x[number] - bomber_direction[number] * 46, bomber_y[number] + 10, 1); /*movement of bomber*/ if (bomber_x[number] > XMAX + 40 || bomber_x[number] < -XMAX - 40) { if (rand() % 2 == 0){ bomber_x[number] = XMAX; bomber_direction[number] = LEFT; } else { bomber_x[number] = -XMAX; bomber_direction[number] = RIGHT; bomber_leaving[number] = FALSE; } /*Randomly select a target that hasn't been destroyed yet*/ if (*calculated_high_scores == FALSE) { do { building[number] = rand () % *city_size ; }while(building_destroyed[building[number]] == TRUE); } bomb_target[number] = building_x[building[number]]; can_bomb[number] = FALSE; bomber_y[number] = rand() % 200; bomber_speed[number] = (rand() % 6) + 5; bomber_leaving[number] = FALSE; detonated[number] = FALSE; } /*this makes it so the bomber can only bomb when it is on its second pass of the city. This was done to allow the player more time to shoot it down*/ if (can_bomb[number] == FALSE && bomber_leaving[number] == FALSE) { if (bomber_x[number] > XMAX - 20 && bomber_direction[number] == RIGHT) { bomber_direction[number] = LEFT; can_bomb[number] = TRUE;} if (bomber_x[number] < -XMAX + 20 && bomber_direction[number] == LEFT) { bomber_direction[number] = RIGHT; can_bomb[number] = TRUE;} } /*Controls bombs*/ /*this conditional shecks to see when the bomber should drop the bomb to hit its randomly determined target*/ if (can_bomb[number] == TRUE && bomb_target[number] < bomber_x[number] + rnd(bomber_direction[number] * bomber_speed[number] * sqrt(bomber_y[number] - BUILDING_BASE)) + 10 && bomb_target[number] > bomber_x[number] + rnd(bomber_direction[number] * bomber_speed[number] * sqrt(bomber_y[number] - BUILDING_BASE)) - 10 ) { bomb_x[number] = bomber_x[number]; bomb_y[number] = bomber_y[number]; bomb_dropped[number] = TRUE; bomber_leaving[number] = TRUE; detonated[number] = FALSE; falling[number] = TRUE; drop_time[number] = 0; spray_distance[number] = 0; } /*moves the bomb, if it has been dropped, but is no yet detonated, allong the x direction with initial velocity equal to the bomber, and accelertates downward*/ if (detonated[number] == FALSE && bomb_dropped[number] == TRUE) { bomb_x[number] = bomb_x[number] + bomber_direction[number] * bomber_speed[number]; bomb_y[number] = bomb_y[number] - rnd(pow(drop_time[number]/2, 2)); drop_time[number] = drop_time[number] + 1; } /*Checks to see if the bomb has reached its target, but it depends on the direction the bomber was travelling in*/ if (bomber_direction[number] == LEFT) { if (bomb_x[number] < bomb_target[number] && bomb_y[number] < BUILDING_BASE + 100) { detonated[number] = TRUE; falling[number] = FALSE; bomb_y[number] = 500; for (chunk = 0; chunk < CHUNK_MAX; chunk ++) { chunk_center_x[chunk][building[number]] = bomb_target[number]; chunk_center_y[chunk][building[number]] = BUILDING_BASE; } } } else { if (bomb_x[number] > bomb_target[number] && bomb_y[number] < BUILDING_BASE + 100) { detonated[number] = TRUE; falling[number] = FALSE; bomb_y[number] = 500; for (chunk = 0; chunk < CHUNK_MAX; chunk ++) { chunk_center_x[chunk][building[number]] = bomb_target[number]; chunk_center_y[chunk][building[number]] = BUILDING_BASE; } } } /*Either draws falling bomb or draws the detonation sequence*/ if (detonated[number] == TRUE && bomber_leaving[number] == TRUE) { explode_bomb(bomb_target, number, detonated, drop_time, spray_distance); building_destroyed[building[number]] = TRUE; } else { if (falling[number] == TRUE){ GP142_lineXY(*enemy_color, bomb_x[number] - 3, bomb_y[number], bomb_x[number] + 3, bomb_y[number], 3); } } /*moves the actual bomber*/ bomber_x[number] = bomber_x[number] + bomber_direction[number] * bomber_speed[number]; } return; } /*********************************************************************** Makes bomb explosion graphics ***********************************************************************/ void explode_bomb (int bomb_target[], int number, int detonated[], int drop_time[], int spray_distance[]) { int color; /*This section of good makes to expanding flashing ovals in two direction. This simulates a bomb explosion and looks good accompanied by the fragments from the buildings*/ switch (rand() % 3) { case 0: color = RED; break; case 1: color = YELLOW; break; case 2: color = ORANGE; break; default: break; } if (spray_distance[number] < SPRAY_MAX) { GP142_ovalXY(color, bomb_target[number] - spray_distance[number], BUILDING_BASE + rnd(spray_distance[number] / 7), bomb_target[number] + spray_distance[number], BUILDING_BASE - rnd(spray_distance[number] / 7), 0); GP142_ovalXY(color, bomb_target[number] - rnd(spray_distance[number] / 2), BUILDING_BASE + rnd(spray_distance[number] ), bomb_target[number] + rnd(spray_distance[number] / 2), BUILDING_BASE - rnd(spray_distance[number] ), 0); spray_distance[number] = spray_distance[number] + 6; } else { spray_distance[number] = 0; detonated[number] = FALSE; drop_time[number] = 0; } return; } /************************************************************8 Detects Collisions and resets necessary values ****************************************************/ void collision_detect( int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int target_x[], int target_y[], int chopper_x[], int chopper_y[], int bomber_x[], int bomber_y[], int target_reached[], int can_collide[], int exploding[], int just_got_hit[], int truck, int *score, int *kills, int *chopper_total, int *bomber_total) { /*note: collisions are confirmed by checking to see if the center of the aircraft was within some domain and range of the target. The range and domain are unique to each craft, and based upon their dimensions*/ int ship = 0; if (can_collide[truck] == TRUE) { if (can_collide[truck] == TRUE && target_reached[truck] == TRUE) { /*checks to see if a chopper has been hit*/ for (ship = 0; ship < *chopper_total; ship ++) { if (chopper_x[ship] > target_x[truck] - 30 && chopper_x[ship] < target_x[truck] + 30 && chopper_y[ship] > target_y[truck] - 15 && chopper_y[ship] < target_y[truck] + 1) { explode_ship (fragment_center_x, fragment_center_y, target_x, target_y, chopper_x, exploding, ship, truck, just_got_hit); *score = *score + 75; *kills = *kills + 1; } } /*checks to see if a bomber has been hit*/ for (ship = 0; ship < *bomber_total; ship ++) { if (bomber_x[ship] > target_x[truck] - 40 && bomber_x[ship] < target_x[truck] + 40 && bomber_y[ship] > target_y[truck] - 20 && bomber_y[ship] < target_y[truck] + 1) { explode_ship (fragment_center_x, fragment_center_y, target_x, target_y, bomber_x, exploding, ship, truck, just_got_hit); *score = *score + 150; *kills = *kills + 1; } } } } return; } /****************************** destroys and resets a hit ship *******************************/ void explode_ship (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int target_x[], int target_y[], int ship_x[], int exploding[], int ship, int truck, int just_got_hit[]) { int frag; for (frag = 0; frag < FRAG_MAX; frag++) { /*initializes fragments at the center of the ship to set up the explosion*/ fragment_center_x[frag][truck] = target_x[truck]; fragment_center_y[frag][truck] = target_y[truck]; /*moves a destroyed ship offscreen to reenter*/ ship_x[ship] = 350; exploding[truck] = TRUE; just_got_hit[truck] = TRUE; } return; } /*********************************************** Handles scattering ship pieces by calling the move_ship_frags and draw_ship_fragments functions ************************************************/ void scatter_ship_pieces (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int truck, int frag_color[FRAG_MAX][TRUCK_MAX], int destroy_timer[], int exploding[]) { int frag_number; /*sprays ship fragmetns all over*/ if (exploding[truck] == TRUE && destroy_timer[truck] < 25) { draw_ship_frags ( fragment_center_x, fragment_center_y, fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, truck, frag_color); move_ship_frags ( fragment_center_x, fragment_center_y, frag_move_x, frag_move_y, destroy_timer, truck); } else { exploding[truck] = FALSE; destroy_timer[truck] = 0; for (frag_number = 0; frag_number < FRAG_MAX; frag_number ++) { fragment_center_x[frag_number][truck] = 500; fragment_center_y[frag_number][truck] = 500; } } return; } /************************************************************ Handles the scattering og building pieces ************************************************************/ void scatter_building_chunks (int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int tower, int chunk_color[CHUNK_MAX][BUILDING_MAX], int crumble_timer[], int crumbling[]) { /*sprays building chunks around if it has been hit and if less than 30 periods have based*/ if (crumbling[tower] == TRUE && crumble_timer[tower] < 30) { draw_city_chunks (chunk_center_x, chunk_center_y, chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, tower, chunk_color); move_city_chunks(chunk_center_x, chunk_center_y, chunk_move_x, chunk_move_y, crumble_timer, tower); } else { crumbling[tower] = FALSE; } return; } /****************************** Draw the ship debrie fragments *****************************/ void draw_ship_frags (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int truck, int frag_color[FRAG_MAX][TRUCK_MAX]) { int chunk; /*draws all ship fragments*/ for (chunk = 0; chunk < FRAG_MAX; chunk ++) { GP142_triangleXY(frag_color[chunk][truck], fragment_x1[chunk][truck] + fragment_center_x[chunk][truck], fragment_y1[chunk][truck] + fragment_center_y[chunk][truck], fragment_x2[chunk][truck] + fragment_center_x[chunk][truck], fragment_y2[chunk][truck] + fragment_center_y[chunk][truck], fragment_x3[chunk][truck] + fragment_center_x[chunk][truck], fragment_y3[chunk][truck] + fragment_center_y[chunk][truck], 3); } return; } /************************************************** Draws the city chunks when a building is desttroyed ***************************************************/ void draw_city_chunks (int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int tower, int chunk_color[CHUNK_MAX][BUILDING_MAX]) { int chunk; /*draws all city chunk pieces*/ for (chunk = 0; chunk < CHUNK_MAX; chunk ++) { GP142_triangleXY(chunk_color[chunk][tower], chunk_x1[chunk][tower] + chunk_center_x[chunk][tower], chunk_y1[chunk][tower] + chunk_center_y[chunk][tower], chunk_x2[chunk][tower] + chunk_center_x[chunk][tower], chunk_y2[chunk][tower] + chunk_center_y[chunk][tower], chunk_x3[chunk][tower] + chunk_center_x[chunk][tower], chunk_y3[chunk][tower] + chunk_center_y[chunk][tower], 3); } return; } /******************************* Move the ship fragemts **************************/ void move_ship_frags (int fragment_center_x[FRAG_MAX][TRUCK_MAX], int fragment_center_y[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int destroy_timer[], int truck) { int frag; for (frag = 0; frag < FRAG_MAX; frag ++) { fragment_center_x[frag][truck] = fragment_center_x[frag][truck] + frag_move_x[frag][truck]; fragment_center_y[frag][truck] = fragment_center_y[frag][truck] + frag_move_y[frag][truck] - rnd(pow(((double)destroy_timer[truck] / 8), 2)); } destroy_timer[truck] = destroy_timer[truck] + 1; return; } /************************************************* Move the city chunks when a building is destroyed *************************************************/ void move_city_chunks(int chunk_center_x[CHUNK_MAX][BUILDING_MAX], int chunk_center_y[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int crumble_timerr[], int tower) { int chunk; for (chunk = 0; chunk < CHUNK_MAX; chunk++) { chunk_center_x[chunk][tower] = chunk_center_x[chunk][tower] + chunk_move_x[chunk][tower]; chunk_center_y[chunk][tower] = chunk_center_y[chunk][tower] + chunk_move_y[chunk][tower] - rnd(pow(((double)crumble_timerr[tower] / 6), 2)); } crumble_timerr[tower] = crumble_timerr[tower] + 1; return; } /**************************************************** If a new ship is exploding, generate fragments for it ****************************************************/ void generate_ship_frags (int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int frag_color[FRAG_MAX][TRUCK_MAX], int *enemy_color) { int frag, truck; for (truck = 0; truck < TRUCK_MAX; truck ++) { for (frag = 0; frag < FRAG_MAX; frag ++) { if (rand() % 4 == 0) frag_color[frag][truck] = BLACK; else frag_color[frag][truck] = *enemy_color; fragment_x1[frag][truck] = (rand() % 4) - 2; fragment_y1[frag][truck] = (rand() % 4) - 2; fragment_x2[frag][truck] = (rand() % 4) - 2; fragment_y2[frag][truck] = (rand() % 4) - 2; fragment_x3[frag][truck] = (rand() % 4) - 2; fragment_y3[frag][truck] = (rand() % 4) - 2; frag_move_x[frag][truck] = rnd(((rand() % 20) - 10) / 2.0); frag_move_y[frag][truck] = rnd(((rand() % 20) - 10) / 2.0) ; } } return; } /*************************************************** Gnerate random fragments for building destruction ***************************************************/ void generate_city_chunks (int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int chunk_color[CHUNK_MAX][BUILDING_MAX], int *city_size) { int chunk, tower; for(tower = 0; tower < *city_size; tower ++) { /*makes fragments of colors like the building colors*/ for(chunk = 0; chunk < CHUNK_MAX; chunk ++) { switch (rand() % 4) { case 0: chunk_color[chunk][tower] = BLACK; break; case 1: chunk_color[chunk][tower] = LT_GRAY; break; case 2: chunk_color[chunk][tower] = MED_GRAY; break; case 3: chunk_color[chunk][tower] = WHITE; break; default: break; } /*randomly_gernerates corners of fragment triangles*/ chunk_x1[chunk][tower] = (rand() % 2) - 1; chunk_x1[chunk][tower] = (rand() % 4) - 2; chunk_x2[chunk][tower] = (rand() % 4) - 2; chunk_x3[chunk][tower] = (rand() % 4) - 2; chunk_y1[chunk][tower] = (rand() % 4) - 2; chunk_y2[chunk][tower] = (rand() % 4) - 2; chunk_y3[chunk][tower] = (rand() % 4) - 2; chunk_move_x[chunk][tower] = rand() % 8 - 4; chunk_move_y[chunk][tower] = rand() % 12; } } return; } /********************************************** Mathematical conversions and operations **********************************************/ /************************************************ Converts and angle in degrees to radians (double) ************************************************/ double degrees_to_radians(int degree_angle[], int truck) { double theta; theta = (double)degree_angle[truck] * PI / 180.0; return (theta); } /********************************************* Converts and angle in radians to degrees (int) *********************************************/ int radians_to_degrees(double angle) { int new_angle; new_angle = rnd(angle * 180 / PI); return (new_angle); } /****************************************************** Rounds a decimal (double) number to the nearest integer ******************************************************/ int rnd(double number) { if (number > 0) number = number + .5; else number = number - .5; return ((int)number); } /************************************** Functions that draw scenery **************************************/ /********************************************************************************* Uses randomly generated values for the location of buildings, and stars as well as the color of the buildings to display the city landscape. The arrays building_destroyed and crumbling are passed in to control the drawing of buildings that have been destroyed by bombs *********************************************************************************/ void make_background(int building_x[], int building_y[], int building_height[], int building_width[], int star_x[], int star_y[], int building_color[], int *windows_on, int *stars_on, int building_destroyed[], int crumbling[], int *nighttime, int *city_size, int mount_x1[], int mount_y1[], int mount_x2[], int mount_y2[], int mount_x3[], int mount_y3[], int mount_color[]) { int color, /*a variable that controls the color of the twinkling stars*/ count, /*used as a loop control value*/ row_y, /*The row that the window is in*/ column_x, /*The column that the window is in*/ tint, /*The color of the sky and water*/ window_color; /*The color of the windows. (black if day,yellow if night*/ /*Changes tint, to black and turns the windows and stars on if the night button was pressed*/ if (*nighttime == TRUE) { tint = BLACK; *stars_on = TRUE; window_color = YELLOW; } /*condiion of the landscape if it is daytime*/ else { tint = BLUE; *stars_on = FALSE; window_color = BLACK; } /*Background sky, and ground*/ GP142_rectangleXY(tint, GP142_XMAX, GP142_YMAX, -GP142_XMAX, -GP142_YMAX, 0); GP142_rectangleXY(BROWN, GP142_XMAX, HORIZON, -GP142_XMAX, BUILDING_BASE - 3, 0); GP142_rectangleXY(tint, GP142_XMAX, BUILDING_BASE - 3, -GP142_XMAX, -GP142_YMAX, 0); /*Displays the stars if stars_on is TRUE*/ if (*stars_on == TRUE) { for (count = 0; count < STAR_MAX; count ++) { switch (rand() % 3) { case 0: color = YELLOW; break; case 1: break; color = WHITE; case 2: color = ORANGE; break; default: break; } if (star_y[count] > HORIZON) GP142_pixelXY(color, star_x[count], star_y[count]); } } /*Draws the mountains according to their randomly generated coordinates and color*/ for (count = 0; count < MOUNTAIN_MAX; count ++) { GP142_triangleXY(mount_color[count], mount_x1[count], mount_y1[count], mount_x2[count], mount_y2[count], mount_x3[count], mount_y3[count], 0); } /*Draws the randomly generated city (aquired by calling get_skyline)*/ for (count = 0; count < *city_size ; count ++) { GP142_rectangleXY(building_color[count], building_x[count] - building_width[count]/2, building_height[count] + building_y[count], building_x[count] + building_width[count]/2, building_y[count], 0); GP142_rectangleXY(BLACK, building_x[count] - building_width[count]/2, building_height[count] + building_y[count], building_x[count] + building_width[count]/2, building_y[count], 1); crumbling[count] = FALSE; /*In case building has been bombed*/ if (building_destroyed[count] == TRUE && building_height[count] > 20) { building_x[count] = building_x[count] + (rand() % 3 - 1); building_height[count] = building_height[count] - 4; crumbling[count] = TRUE; /*if his is executed, the particles of the building will scatter*/ } /*Draws windows on the buildings if windows_on is true*/ if (*windows_on == TRUE) { for (row_y = building_height[count] + building_y[count] - WINDOW_SPACE; row_y > building_y[count] + WINDOW_HEIGHT; row_y = row_y - WINDOW_HEIGHT - WINDOW_SPACE) { for (column_x = (building_x[count] - building_width[count]/2) + WINDOW_SPACE; column_x < building_x[count] + building_width[count]/2 - WINDOW_SPACE; column_x = column_x + 2 * WINDOW_SPACE) { GP142_rectangleXY(window_color, column_x, row_y, column_x + WINDOW_WIDTH, row_y - WINDOW_HEIGHT, 0); } } } } return; } /******************************************* Displays the road and other foreground elements **********************************************/ void make_foreground (void) { int count; GP142_rectangleXY(MED_GRAY, GP142_XMAX, ROAD_HEIGHT, -GP142_XMAX, ROAD_BASE, 0); for(count = -GP142_XMAX; count <= GP142_XMAX - STRIPE_LENGTH; count = count + STRIPE_LENGTH + STRIPE_SPACE) GP142_lineXY(WHITE, count, ROAD_BASE + LANE_WIDTH , count + STRIPE_LENGTH, ROAD_BASE + LANE_WIDTH, 1); for(count = -GP142_XMAX; count <= GP142_XMAX - STRIPE_LENGTH; count = count + STRIPE_LENGTH + STRIPE_SPACE) GP142_lineXY(WHITE, count, ROAD_BASE + 2 * LANE_WIDTH, count + STRIPE_LENGTH, ROAD_BASE + 2 * LANE_WIDTH, 1); GP142_lineXY(YELLOW, -GP142_XMAX, ROAD_BASE + 3 * LANE_WIDTH, GP142_XMAX, ROAD_BASE + 3 * LANE_WIDTH, 1); for(count = -GP142_XMAX; count <= GP142_XMAX - STRIPE_LENGTH; count = count + STRIPE_LENGTH + STRIPE_SPACE) GP142_lineXY(WHITE, count, ROAD_BASE + 4 * LANE_WIDTH, count + STRIPE_LENGTH, ROAD_BASE + 4 * LANE_WIDTH, 1); for(count = -GP142_XMAX; count <= GP142_XMAX - STRIPE_LENGTH; count = count + STRIPE_LENGTH + STRIPE_SPACE) GP142_lineXY(WHITE, count, ROAD_BASE + 5 * LANE_WIDTH, count + STRIPE_LENGTH, ROAD_BASE + 5 * LANE_WIDTH, 1); GP142_lineXY(WHITE, -GP142_XMAX, ROAD_HEIGHT, GP142_XMAX, ROAD_HEIGHT, 1); GP142_lineXY(WHITE, -GP142_XMAX, ROAD_BASE, GP142_XMAX, ROAD_BASE, 1); /*Draws the road thickness*/ GP142_rectangleXY(LT_GRAY, -GP142_XMAX, ROAD_BASE - 1, GP142_XMAX, ROAD_BASE - ROAD_THICKNESS, 0); GP142_rectangleXY(BLACK, -GP142_XMAX, ROAD_BASE - 1, GP142_XMAX, ROAD_BASE - ROAD_THICKNESS, 1); /*Draws the road support columns*/ for (count = -GP142_XMAX; count < GP142_XMAX; count = count + COLUMN_WIDTH + COLUMN_SPACE ) { GP142_rectangleXY(LT_GRAY, count, ROAD_BASE - ROAD_THICKNESS, count + COLUMN_WIDTH, -GP142_YMAX, 0); GP142_rectangleXY(BLACK, count, ROAD_BASE - ROAD_THICKNESS, count + COLUMN_WIDTH, -GP142_YMAX, 1); } /*Draws the Freeway guard rails*/ GP142_rectangleXY(LT_GRAY, -GP142_XMAX, ROAD_HEIGHT + 1, GP142_XMAX, ROAD_HEIGHT + GUARD_RAIL_HEIGHT, 0); GP142_rectangleXY(BLACK, -GP142_XMAX, ROAD_HEIGHT + 1, GP142_XMAX, ROAD_HEIGHT + GUARD_RAIL_HEIGHT, 1); GP142_rectangleXY(LT_GRAY, -GP142_XMAX, ROAD_BASE - 1, GP142_XMAX, ROAD_BASE + GUARD_RAIL_HEIGHT, 0); GP142_rectangleXY(BLACK, -GP142_XMAX, ROAD_BASE - 1, GP142_XMAX, ROAD_BASE + GUARD_RAIL_HEIGHT, 1); return; } /************************************************************************************************* This function draws the missle launching truck with the pod and the piston in the correct position It has arrays for various parts of the truck such as it's center, and corners of moving parts.as parameters. Each truck has a totally diferrent set of information, that is why arrays are used. An additional term, truck_direction is used to account for the change in angles when the truck faces LEFT as opposed to RIGHT. *************************************************************************************************/ void draw_missle_truck(int truck_center_x[], int truck_center_y[], int pod_pivot_x[], int pod_pivot_y[], int PodTopRear_x[], int PodTopRear_y[], int PodBottomRear_x[], int PodBottomRear_y[], int PodTopFront_x[], int PodTopFront_y[], int PodBottomFront_x[], int PodBottomFront_y[], int MountTop_x[], int MountTop_y[], int MountBottom_x[], int MountBottom_y[], int CylinderBottom_x[], int CylinderBottom_y[], int CylinderTop_x[], int CylinderTop_y[], int truck_direction[], int truck, int playing_trucks, int degree_angle[], int *truck_color) { /*draw the movable launcing pod*/ for (truck = 0; truck < playing_trucks; truck ++) { /*need to get correct coordinates for pod, cylinder, and mount*/ get_pod_coordinates(degree_angle, truck_direction, truck, truck_center_x, truck_center_y, pod_pivot_x, pod_pivot_y, PodTopRear_x, PodTopRear_y, PodBottomRear_x, PodBottomRear_y, PodTopFront_x, PodTopFront_y, PodBottomFront_x, PodBottomFront_y, MountTop_x, MountTop_y, MountBottom_x, MountBottom_y, CylinderBottom_x, CylinderBottom_y, CylinderTop_x, CylinderTop_y); /*Two triangles make up the launching pod at all positions*/ GP142_triangleXY(*truck_color, PodTopRear_x[truck], PodTopRear_y[truck], PodBottomRear_x[truck], PodBottomRear_y[truck], PodTopFront_x[truck], PodTopFront_y[truck], 0); GP142_triangleXY(*truck_color, PodBottomFront_x[truck], PodBottomFront_y[truck], PodBottomRear_x[truck], PodBottomRear_y[truck], PodTopFront_x[truck], PodTopFront_y[truck], 0); GP142_lineXY(BLACK, PodBottomFront_x[truck], PodBottomFront_y[truck], PodTopFront_x[truck], PodTopFront_y[truck], 1); GP142_lineXY(BLACK, PodBottomRear_x[truck], PodBottomRear_y[truck], PodTopRear_x[truck], PodTopRear_y[truck], 1); GP142_lineXY(BLACK, PodBottomFront_x[truck], PodBottomFront_y[truck], PodBottomRear_x[truck], PodBottomRear_y[truck], 1); GP142_lineXY(BLACK, PodTopFront_x[truck], PodTopFront_y[truck], PodTopRear_x[truck], PodTopRear_y[truck], 1); /*draw the piston*/ GP142_lineXY(BLACK, MountTop_x[truck], MountTop_y[truck], CylinderTop_x[truck], CylinderTop_y[truck], 1); /*draw the piston cylinder*/ GP142_lineXY(*truck_color, CylinderTop_x[truck], CylinderTop_y[truck], CylinderBottom_x[truck], CylinderBottom_y[truck], 2); /*draw the moving piston mount*/ GP142_rectangleXY(BLACK, MountTop_x[truck], MountTop_y[truck], MountBottom_x[truck], MountBottom_y[truck], 0); /*The stationary truck body*/ /*background underneath*/ GP142_rectangleXY (BROWN, truck_center_x[truck] - truck_direction[truck] * 28, truck_center_y[truck] + 6, truck_center_x[truck] + truck_direction[truck] * 20, truck_center_y[truck] + 4, 0); /*draw the wheels*/ GP142_circleXY (BLACK, truck_center_x[truck] - truck_direction[truck] * 24, truck_center_y[truck] + 3, 3); /*Back Tires*/ GP142_circleXY (BLACK, truck_center_x[truck] - truck_direction[truck] * 16, truck_center_y[truck] + 3, 3); GP142_circleXY (BLACK, truck_center_x[truck] - truck_direction[truck] * 8, truck_center_y[truck] + 3, 3); GP142_circleXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 8, truck_center_y[truck] + 3, 3); /*Front Tires*/ GP142_circleXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 16, truck_center_y[truck] + 3, 3); GP142_circleXY (OLIVE, truck_center_x[truck] - truck_direction[truck] * 24, truck_center_y[truck] + 3, 1); /* Tires*/ GP142_circleXY (OLIVE, truck_center_x[truck] - truck_direction[truck] * 16, truck_center_y[truck] + 3, 1); GP142_circleXY (OLIVE, truck_center_x[truck] - truck_direction[truck] * 8, truck_center_y[truck] + 3, 1); GP142_circleXY (OLIVE, truck_center_x[truck] + truck_direction[truck] * 8, truck_center_y[truck] + 3, 1); /*Front Tires*/ GP142_circleXY (OLIVE, truck_center_x[truck] + truck_direction[truck] * 16, truck_center_y[truck] + 3, 1); /*Truck bed*/ GP142_rectangleXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 30, truck_center_y[truck] + 6, truck_center_x[truck] - truck_direction[truck] * 29, truck_center_y[truck] + 2, 0); GP142_rectangleXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 28, truck_center_y[truck] + 9, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 7, 0); GP142_lineXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 4, truck_center_y[truck] + 6, truck_center_x[truck] - truck_direction[truck] * 3, truck_center_y[truck] + 6, 1); GP142_pixelXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 29, truck_center_y[truck] + 7); GP142_pixelXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 28, truck_center_y[truck] + 6); GP142_pixelXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 20, truck_center_y[truck] + 6); GP142_pixelXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 12, truck_center_y[truck] + 6); GP142_pixelXY (*truck_color, truck_center_x[truck] - truck_direction[truck] * 3, truck_center_y[truck] + 5); /*pod support pivot*/ GP142_triangleXY (OLIVE, truck_center_x[truck] - truck_direction[truck] * 27, truck_center_y[truck] + 16, truck_center_x[truck] - truck_direction[truck] * 28, truck_center_y[truck] + 7, truck_center_x[truck] - truck_direction[truck] * 23, truck_center_y[truck] + 7, 0); /*Pod piston supports*/ GP142_rectangleXY (BLACK, truck_center_x[truck] - truck_direction[truck] * 6, truck_center_y[truck] + 11, truck_center_x[truck] - truck_direction[truck] * 5, truck_center_y[truck] + 10, 0); /*middle of truck*/ GP142_rectangleXY (OLIVE, truck_center_x[truck] - truck_direction[truck] * 2, truck_center_y[truck] + 6, truck_center_x[truck] + truck_direction[truck] * 2, truck_center_y[truck] + 1, 0); GP142_rectangleXY (*truck_color, truck_center_x[truck], truck_center_y[truck] + 16, truck_center_x[truck] + truck_direction[truck] * 5, truck_center_y[truck] + 7, 0); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 3, truck_center_y[truck] + 6, truck_center_x[truck] + truck_direction[truck] * 4, truck_center_y[truck] + 6, 1); GP142_pixelXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 3, truck_center_y[truck] + 4); /*smoke stack*/ GP142_rectangleXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 8, truck_center_y[truck] + 16, truck_center_x[truck] + truck_direction[truck] * 9, truck_center_y[truck] + 15, 0); GP142_rectangleXY (OLIVE, truck_center_x[truck] + truck_direction[truck] * 7, truck_center_y[truck] + 14, truck_center_x[truck] + truck_direction[truck] * 10, truck_center_y[truck] + 9, 0); GP142_lineXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 11, truck_center_y[truck] + 12, truck_center_x[truck] + truck_direction[truck] * 11, truck_center_y[truck] + 7, 0); GP142_lineXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 6, truck_center_y[truck] + 12, truck_center_x[truck] + truck_direction[truck] * 6, truck_center_y[truck] + 7, 1); GP142_pixelXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 8, truck_center_y[truck] + 17); /*truck cab*/ GP142_rectangleXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 9, truck_center_y[truck] + 12, truck_center_x[truck] + truck_direction[truck] * 11, truck_center_y[truck] + 7, 0); GP142_rectangleXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 12, truck_center_y[truck] + 18, truck_center_x[truck] + truck_direction[truck] * 18, truck_center_y[truck] + 7, 0); GP142_rectangleXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 10, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 7, 0); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 16, truck_center_x[truck] + truck_direction[truck] * 20, truck_center_y[truck] + 16, 1); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 12, truck_center_x[truck] + truck_direction[truck] * 24, truck_center_y[truck] + 12, 1); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 11, truck_center_x[truck] + truck_direction[truck] * 25, truck_center_y[truck] + 11, 1); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 20, truck_center_y[truck] + 6, truck_center_x[truck] + truck_direction[truck] * 25, truck_center_y[truck] + 6, 1); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 5, truck_center_x[truck] + truck_direction[truck] * 24, truck_center_y[truck] + 5, 1); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 4, truck_center_x[truck] + truck_direction[truck] * 23, truck_center_y[truck] + 4, 1); GP142_lineXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 3, truck_center_x[truck] + truck_direction[truck] * 22, truck_center_y[truck] + 3, 1); GP142_pixelXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 12, truck_center_y[truck] + 6); GP142_pixelXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 17); GP142_pixelXY (*truck_color, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 2); /*draw windows*/ GP142_rectangleXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 13, truck_center_y[truck] + 16, /*small side window*/ truck_center_x[truck] + truck_direction[truck] * 16, truck_center_y[truck] + 15, 0); GP142_rectangleXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 15, /*Windshield*/ truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 13, 0); GP142_lineXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 22, truck_center_y[truck] + 14, truck_center_x[truck] + truck_direction[truck] * 22, truck_center_y[truck] + 13, 1); GP142_pixelXY (BLACK, truck_center_x[truck] + truck_direction[truck] * 23, truck_center_y[truck] + 13); /*draw the outline of the truck*/ GP142_rectangleXY(BLACK, truck_center_x[truck] - 2, truck_center_y[truck] + 6, truck_center_x[truck] + 2, truck_center_y[truck] + 1, 1); GP142_lineXY(BLACK, truck_center_x[truck] - truck_direction[truck] * 29, truck_center_y[truck] + 2, truck_center_x[truck] - truck_direction[truck] * 29, truck_center_y[truck] + 5, 1); GP142_lineXY(BLACK, truck_center_x[truck] - truck_direction[truck] * 27, truck_center_y[truck] + 7, truck_center_x[truck] - truck_direction[truck] * -1, truck_center_y[truck] + 7, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 5, truck_center_y[truck] + 7, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 7, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 2, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 7, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 7, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 10, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 10, truck_center_x[truck] + truck_direction[truck] * 18, truck_center_y[truck] + 19, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 18, truck_center_y[truck] + 19, truck_center_x[truck] + truck_direction[truck] * 12, truck_center_y[truck] + 19, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 12, truck_center_y[truck] + 13, truck_center_x[truck] + truck_direction[truck] * 9, truck_center_y[truck] + 13, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 2, truck_center_x[truck] + truck_direction[truck] * 26, truck_center_y[truck] + 7, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 13, truck_center_y[truck] + 19, truck_center_x[truck] + truck_direction[truck] * 13, truck_center_y[truck] + 12, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 2, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 5, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 21, truck_center_y[truck] + 2, truck_center_x[truck] + truck_direction[truck] * 19, truck_center_y[truck] + 7, 1); GP142_rectangleXY(BLACK, truck_center_x[truck] + truck_direction[truck], truck_center_y[truck] + 17, truck_center_x[truck] + truck_direction[truck] * 5, truck_center_y[truck] + 7, 1); GP142_lineXY(BLACK, truck_center_x[truck] - truck_direction[truck] * 28, truck_center_y[truck] + 9, truck_center_x[truck] + truck_direction[truck] * 0, truck_center_y[truck] + 9, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 9, truck_center_y[truck] + 13, truck_center_x[truck] + truck_direction[truck] * 9, truck_center_y[truck] + 7, 1); GP142_lineXY(BLACK, truck_center_x[truck] + truck_direction[truck] * 7, truck_center_y[truck] + 14, truck_center_x[truck] + truck_direction[truck] * 10, truck_center_y[truck] + 14, 1); GP142_lineXY(BLACK, truck_center_x[truck] - truck_direction[truck] * 2, truck_center_y[truck] + 4, truck_center_x[truck] - truck_direction[truck] * 5, truck_center_y[truck] + 7, 1); GP142_triangleXY (BLACK, truck_center_x[truck] - truck_direction[truck] * 27, truck_center_y[truck] + 16, truck_center_x[truck] - truck_direction[truck] * 28, truck_center_y[truck] + 7, truck_center_x[truck] - truck_direction[truck] * 23, truck_center_y[truck] + 7, 1); } return; } /*************************************************************************** Finds the corners of the pod in terms of an angle theta and the truck center ***************************************************************************/ void get_pod_coordinates (int degree_angle[], int truck_direction[], int truck, int truck_center_x[], int truck_center_y[], int pod_pivot_x[], int pod_pivot_y[], int PodTopRear_x[], int PodTopRear_y[], int PodBottomRear_x[], int PodBottomRear_y[], int PodTopFront_x[], int PodTopFront_y[], int PodBottomFront_x[], int PodBottomFront_y[], int MountTop_x[], int MountTop_y[], int MountBottom_x[], int MountBottom_y[], int CylinderBottom_x[], int CylinderBottom_y[], int CylinderTop_x[], int CylinderTop_y[]) { PodTopRear_x[truck] = rnd(pod_pivot_x[truck] + truck_direction[truck] * DISTANCE_POD_REAR_UPPER * cos(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_REAR_UPPER)); PodTopRear_y[truck] = rnd(pod_pivot_y[truck] + DISTANCE_POD_REAR_UPPER * sin(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_REAR_UPPER)); PodBottomRear_x[truck] = rnd(pod_pivot_x[truck] + truck_direction[truck] * DISTANCE_POD_REAR_LOWER * cos(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_REAR_LOWER)); PodBottomRear_y[truck] = rnd(pod_pivot_y[truck] + DISTANCE_POD_REAR_LOWER * sin(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_REAR_LOWER)); PodTopFront_x[truck] = rnd(pod_pivot_x[truck] + truck_direction[truck] * DISTANCE_POD_FRONT_UPPER * cos(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_FRONT_UPPER)); PodTopFront_y[truck] = rnd(pod_pivot_y[truck] + DISTANCE_POD_FRONT_UPPER * sin(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_FRONT_UPPER)); PodBottomFront_x[truck] = rnd(pod_pivot_x[truck] + truck_direction[truck] * DISTANCE_POD_FRONT_LOWER * cos(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_FRONT_LOWER)); PodBottomFront_y[truck] = rnd(pod_pivot_y[truck] + DISTANCE_POD_FRONT_LOWER * sin(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_FRONT_LOWER)); MountTop_x[truck] = rnd(pod_pivot_x[truck] + truck_direction[truck] * DISTANCE_MOUNT_TOP * cos(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_MOUNT_TOP)); MountTop_y[truck] = rnd(pod_pivot_y[truck] + DISTANCE_MOUNT_TOP * sin(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_MOUNT_TOP)); MountBottom_x[truck] = rnd(pod_pivot_x[truck] + truck_direction[truck] * DISTANCE_MOUNT_BOTTOM * cos(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_MOUNT_BOTTOM)); MountBottom_y[truck] = rnd(pod_pivot_y[truck] + DISTANCE_MOUNT_BOTTOM * sin(degrees_to_radians(degree_angle, truck) + INITIAL_ANGLE_MOUNT_BOTTOM)); CylinderBottom_x[truck] = truck_center_x[truck] - truck_direction[truck] * 5; CylinderBottom_y[truck] = truck_center_y[truck] + 11; CylinderTop_x[truck] = CylinderBottom_x[truck] - rnd(((CylinderBottom_x[truck] - MountBottom_x[truck])* PISTON_C_LENGTH) / sqrt(pow(CylinderBottom_x[truck] - MountBottom_x[truck],2) + pow(MountBottom_y[truck] - CylinderBottom_y[truck],2))); CylinderTop_y[truck] = CylinderBottom_y[truck] + rnd(((MountBottom_y[truck] - CylinderBottom_y[truck]) * PISTON_C_LENGTH) / sqrt(pow(CylinderBottom_x[truck] - MountBottom_x[truck],2) + pow(MountBottom_y[truck] - CylinderBottom_y[truck],2))); return; } /****************************** Draws Menu buttons ***************************/ void draw_menu (int *score, int *kills, int *objective_kills) { int button; /*score*/ GP142_rectangleXY(MED_GRAY, -XMAX, -YMAX, -XMAX + 100, -YMAX + 30, 0); GP142_rectangleXY(BLACK, -XMAX, -YMAX, -XMAX + 100, -YMAX + 30, 1); GP142_rectangleXY(BLACK, -XMAX , -YMAX, -XMAX + 98, -YMAX + 28, 1); GP142_printfXY(WHITE, -XMAX + 16, -YMAX + 12, 11, "Score: %d", *score); /*kills*/ GP142_rectangleXY(MED_GRAY, XMAX, -YMAX, XMAX - 100, -YMAX + 30, 0); GP142_rectangleXY(BLACK, XMAX, -YMAX, XMAX - 100, -YMAX + 30, 1); GP142_rectangleXY(BLACK, XMAX , -YMAX, XMAX - 98, -YMAX + 28, 1); GP142_printfXY(WHITE, XMAX - 90, -YMAX + 12, 11, "Kills: %d / %d", *kills, *objective_kills); GP142_rectangleXY(MED_GRAY, XMAX, YMAX, -XMAX, -YMAX, 20); GP142_rectangleXY(MED_GRAY, XMAX, YMAX, -XMAX, MENU_BOTTOM, 0); GP142_rectangleXY(BLACK, XMAX, YMAX, -XMAX, -YMAX, 1); GP142_rectangleXY(BLACK, XMAX - 10, MENU_BOTTOM, -XMAX + 10, -YMAX + 10, 1); GP142_rectangleXY(BLACK, XMAX - 2, YMAX - 2, -XMAX + 2, -YMAX + 2, 1); GP142_rectangleXY(BLACK, XMAX - 8, MENU_BOTTOM + 2, -XMAX + 8, -YMAX + 8, 1); /*main menu*/ for (button = 1; button < 6; button ++) draw_button (- XMAX + button * XMAX/3, (YMAX - (YMAX - MENU_BOTTOM)/2) ); GP142_printfXY(WHITE, - XMAX + XMAX/3 - 9, (YMAX - (YMAX - MENU_BOTTOM)/2) - 7, 11, "File"); GP142_printfXY(WHITE, - XMAX + 2 * XMAX/3 - 16, (YMAX - (YMAX - MENU_BOTTOM)/2) - 7, 11, "Options"); GP142_printfXY(WHITE, - XMAX + 3 * XMAX/3 - 12, (YMAX - (YMAX - MENU_BOTTOM)/2) - 7, 11, "Levels"); GP142_printfXY(WHITE, - XMAX + 4 * XMAX/3 - 16, (YMAX - (YMAX - MENU_BOTTOM)/2) - 7, 11, "Scenery"); GP142_printfXY(WHITE, - XMAX + 5 * XMAX/3 - 10, (YMAX - (YMAX - MENU_BOTTOM)/2) - 7, 11, "Help"); return; } /*Buttons*/ /************************* draw button from center point **********************/ void draw_button (int x, int y) { int button_length = 80, button_height = 18; GP142_rectangleXY(BLACK, x + button_length/2 , y + button_height/2, x - button_length/2 , y - button_height/2, 1); GP142_rectangleXY(BLACK, x + button_length/2 - 2, y + button_height/2 -2, x - button_length/2 + 2, y - button_height/2 + 2, 1); return; } /***************************************** Draws the file menu *****************************************/ void draw_file_menu (void) { GP142_rectangleXY(MED_GRAY, FILE_XMAX + 4, YMAX, FILE_XMIN - 4, YMAX - FILE_MENU_LENGTH, 0); GP142_rectangleXY(BLACK, FILE_XMAX + 4, YMAX, FILE_XMIN - 4, YMAX - FILE_MENU_LENGTH, 1); GP142_rectangleXY(BLACK, FILE_XMAX + 2, YMAX, FILE_XMIN - 2, YMAX - FILE_MENU_LENGTH + 2, 1); draw_button (FILE_XMIN + (FILE_XMAX - FILE_XMIN)/2, YMAX - 40); GP142_printfXY(WHITE, FILE_XMIN + (FILE_XMAX - FILE_XMIN)/2 - 35, YMAX -48, 12, "New Game"); draw_button (FILE_XMIN + (FILE_XMAX - FILE_XMIN)/2, YMAX - 62); GP142_printfXY(WHITE, FILE_XMIN + (FILE_XMAX - FILE_XMIN)/2 - 35, YMAX - 70, 12, "Quit"); draw_button (FILE_XMIN + (FILE_XMAX - FILE_XMIN)/2, YMAX - 84); GP142_printfXY(WHITE, FILE_XMIN + (FILE_XMAX - FILE_XMIN)/2 - 35, YMAX - 92, 12, "Resume"); return; } /************************************** Draws the options menu **************************************/ void draw_options_menu(int *level) { int color; if (*level == 1) color = WHITE; else color = RED; GP142_rectangleXY(MED_GRAY, OPTIONS_XMAX + 4, YMAX, OPTIONS_XMIN - 4, YMAX - OPTIONS_MENU_LENGTH, 0); GP142_rectangleXY(BLACK, OPTIONS_XMAX + 4, YMAX, OPTIONS_XMIN - 4, YMAX - OPTIONS_MENU_LENGTH, 1); GP142_rectangleXY(BLACK, OPTIONS_XMAX + 2, YMAX, OPTIONS_XMIN - 2, YMAX - OPTIONS_MENU_LENGTH + 2, 1); draw_button (OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2, YMAX - 40); GP142_printfXY(color, OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2 - 35, YMAX -48, 12, "Easy"); draw_button (OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2, YMAX - 62); GP142_printfXY(color, OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2 - 35, YMAX - 70, 12, "Medium"); draw_button (OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2, YMAX - 84); GP142_printfXY(color, OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2 - 35, YMAX - 92, 12, "Hard"); draw_button (OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2, YMAX - 106); GP142_printfXY(WHITE, OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2 - 35, YMAX - 114, 12, "High Scores"); draw_button (OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2, YMAX - 128); GP142_printfXY(WHITE, OPTIONS_XMIN + (OPTIONS_XMAX - OPTIONS_XMIN)/2 - 35, YMAX - 136, 12, "Resume"); return; } /***************************************** Draws the level menu ******************************************/ void draw_levels_menu (int *level) { /*the conditionals check to see if the player has already passed the level the are trying to sklip t0*/ int color; GP142_rectangleXY(MED_GRAY, LEVELS_XMAX + 4, YMAX, LEVELS_XMIN - 4, YMAX - LEVELS_MENU_LENGTH, 0); GP142_rectangleXY(BLACK, LEVELS_XMAX + 4, YMAX, LEVELS_XMIN - 4, YMAX - LEVELS_MENU_LENGTH, 1); GP142_rectangleXY(BLACK, LEVELS_XMAX + 2, YMAX, LEVELS_XMIN - 2, YMAX - LEVELS_MENU_LENGTH + 2, 1); if (*level >= 5) color = RED; else color = WHITE; draw_button (LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2, YMAX - 40); GP142_printfXY(color, LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2 - 35, YMAX -48, 12, "Level 5"); if (*level >= 10) color = RED; else color = WHITE; draw_button (LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2, YMAX - 62); GP142_printfXY(color, LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2 - 35, YMAX -70, 12, "Level 10"); if (*level >= 15) color = RED; else color = WHITE; draw_button (LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2, YMAX - 84); GP142_printfXY(color, LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2 - 35, YMAX -92, 12, "Level 15"); draw_button (LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2, YMAX - 106); GP142_printfXY(WHITE, LEVELS_XMIN + (LEVELS_XMAX - LEVELS_XMIN)/2 - 35, YMAX -114, 12, "Resume"); return; } /*************************************** Draws the scenery menu ***************************************/ void draw_scenery_menu (void) { GP142_rectangleXY(MED_GRAY, SCENERY_XMAX + 4, YMAX, SCENERY_XMIN - 4, YMAX - SCENERY_MENU_LENGTH, 0); GP142_rectangleXY(BLACK, SCENERY_XMAX + 4, YMAX, SCENERY_XMIN - 4, YMAX - SCENERY_MENU_LENGTH, 1); GP142_rectangleXY(BLACK, SCENERY_XMAX + 2, YMAX, SCENERY_XMIN - 2, YMAX - SCENERY_MENU_LENGTH + 2, 1); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 40); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -48, 12, "Day "); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 62); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -70, 12, "Night "); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 84); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -92, 12, "Change Trucks"); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 106); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -114, 12, "Change Enemy"); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 128); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -136, 12, "Restore Color"); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 150); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -158, 12, "Windows"); draw_button (SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2, YMAX - 172); GP142_printfXY(WHITE, SCENERY_XMIN + (SCENERY_XMAX - SCENERY_XMIN)/2 - 35, YMAX -180, 12, "Resume"); return; } /***************************************************************************** Draws the help menu if the button is pressed *****************************************************************************/ void draw_help_menu (int *page) { int color; GP142_rectangleXY(MED_GRAY, 150, 80, -150, -80, 0); GP142_rectangleXY(BLACK, 150, 80, -150, -80,1); GP142_rectangleXY(BLACK, 148, 78, -148, -78,1); GP142_printfXY(WHITE, -15, 52, 15, "HELP"); if (*page == 1) { GP142_printfXY(WHITE, -110, 30, 12, "Welcome to Urban Defender, a challenging game of"); GP142_printfXY(WHITE, -130, 18, 12, "simulated city defense. You have two trucks with which"); GP142_printfXY(WHITE, -130, 6, 12, "you can shoot down aircraft.To select a truck press a key"); GP142_printfXY(WHITE, -130, -6, 12, "from one to four, one being the left most truck. The goal"); GP142_printfXY(WHITE, -130, -18, 12,"of the mission is to protect the city for as long as"); GP142_printfXY(WHITE, -130, -30, 12,"possible. To accomplish this, you must destroy bombers"); } else { GP142_printfXY(WHITE, -130, 30, 12, "before they disharge their payload. To destroy an aircraf,"); GP142_printfXY(WHITE, -130, 18, 12, "select the truck you want to use and click on the screen "); GP142_printfXY(WHITE, -130, 6, 12, "where you want it to fire. If the city is totally destroyed,"); GP142_printfXY(WHITE, -130, -6, 12, "you lose. With each successive level, more aircraft will "); GP142_printfXY(WHITE, -130, -18, 12,"appear and a greater number of kills will be required to "); GP142_printfXY(WHITE, -130, -30, 12,"move on. With a high score you can enter the hall of fame."); } if (*page == 1) color = WHITE; else color = RED; draw_button (-50,-60); GP142_printfXY(color, -74, -68, 12, "Next Page"); draw_button (50,-60); GP142_printfXY(WHITE, 30, -68, 12, "Resume"); return; } /************************************ draws the intorduction animation ************************************/ void show_intro (int *intro_radius, int *flash_count, int *animation) { int color, rad; if (*intro_radius < 20){ rad = rnd(pow(*intro_radius, 2)); GP142_rectangleXY(MED_GRAY,-rnd(rad / 20.0), rad * 3, rnd(rad / 20.0), 0, 0); GP142_rectangleXY(MED_GRAY, -rnd(rad / 20.0), 0, rnd(rad / 20.0), -rad * 3, 0); GP142_rectangleXY(MED_GRAY, -rad * 3, rnd(rad / 20.0), 0, -rnd(rad / 20.0), 0); GP142_rectangleXY(MED_GRAY, 0, rnd(rad / 20.0), rad * 3, -rnd(rad / 20.0), 0); GP142_circleXY(WHITE, 0, 0, rnd( rad)); GP142_circleXY(LT_GRAY, 0,0, rnd( rad / 2.0)); *intro_radius = *intro_radius + 1; } else { if (*flash_count < 20) { switch (rand() % 4) { case 0: color = RED; break; case 1: color = YELLOW; break; case 2: color = WHITE; break; case 3: color = ORANGE; break; default: break; } GP142_rectangleXY(color, GP142_XMAX, GP142_YMAX, -GP142_XMAX, -GP142_YMAX, 0); *flash_count = *flash_count + 1; } else *animation = FALSE; } return; } /**************************************** makes title screen ****************************************/ void intro_text (int *intro_timer, int big_missile_x[], int big_missile_y[], int big_big_missile_direction[], int *missiles_moved) { if (*intro_timer > 3) GP142_printfXY(GREEN, -140, 0, 20, "U"); if (*intro_timer > 6) GP142_printfXY(GREEN, -120, 0, 20, "R"); if (*intro_timer > 9) GP142_printfXY(GREEN, -100, 0, 20, "B"); if (*intro_timer > 12) GP142_printfXY(GREEN, -80, 0, 20, "A"); if (*intro_timer > 15) GP142_printfXY(GREEN, -60, 0, 20, "N"); if (*intro_timer > 18) GP142_printfXY(GREEN, -20, 0, 20, "D"); if (*intro_timer > 21) GP142_printfXY(GREEN, 0, 0, 20, "E"); if (*intro_timer > 24) GP142_printfXY(GREEN, 20, 0, 20, "F"); if (*intro_timer > 27) GP142_printfXY(GREEN, 40, 0, 20, "E"); if (*intro_timer > 30) GP142_printfXY(GREEN, 60, 0, 20, "N"); if (*intro_timer > 33) GP142_printfXY(GREEN, 80, 0, 20, "D"); if (*intro_timer > 36) GP142_printfXY(GREEN, 100, 0, 20, "E"); if (*intro_timer > 39) GP142_printfXY(GREEN, 120, 0, 20, "R"); if (*intro_timer > 42) draw_intro_missiles (big_missile_x, big_missile_y, big_big_missile_direction, missiles_moved); return; } /******************************************************* Draws introduction missiles *******************************************************/ void draw_intro_missiles (int big_missile_x[], int big_missile_y[], int big_missile_direction[], int *missiles_moved) { int number; for (number = 0; number < 2; number ++) { GP142_rectangleXY(WHITE, big_missile_x[number] + big_missile_direction[number] * 100, big_missile_y[number] + 10, big_missile_x[number] - big_missile_direction[number] * 140, big_missile_y[number] - 10, 0); GP142_rectangleXY(WHITE, big_missile_x[number] + big_missile_direction[number] * 125, big_missile_y[number] + 5, big_missile_x[number] + big_missile_direction[number] * 100, big_missile_y[number] - 5, 0); GP142_triangleXY(WHITE, big_missile_x[number] + big_missile_direction[number] * 125, big_missile_y[number] + 5, big_missile_x[number] + big_missile_direction[number] * 100, big_missile_y[number] + 10, big_missile_x[number] + big_missile_direction[number] * 100, big_missile_y[number] + 5, 0); GP142_triangleXY(WHITE, big_missile_x[number] + big_missile_direction[number] * 125, big_missile_y[number] - 5, big_missile_x[number] + big_missile_direction[number] * 100, big_missile_y[number] - 10, big_missile_x[number] + big_missile_direction[number] * 100, big_missile_y[number] - 5, 0); GP142_triangleXY(LT_GRAY, big_missile_x[number] + big_missile_direction[number] * 140, big_missile_y[number] + 0, big_missile_x[number] + big_missile_direction[number] * 125, big_missile_y[number] + 5, big_missile_x[number] + big_missile_direction[number] * 125, big_missile_y[number] - 5, 0); GP142_triangleXY(MED_GRAY, big_missile_x[number] + big_missile_direction[number] * 60, big_missile_y[number] + 10, big_missile_x[number] + big_missile_direction[number] * 50, big_missile_y[number] + 30, big_missile_x[number] + big_missile_direction[number] * 50, big_missile_y[number] + 10, 0); GP142_triangleXY(MED_GRAY, big_missile_x[number] + big_missile_direction[number] * 60, big_missile_y[number] - 10, big_missile_x[number] + big_missile_direction[number] * 50, big_missile_y[number] - 30, big_missile_x[number] + big_missile_direction[number] * 50, big_missile_y[number] - 10, 0); GP142_rectangleXY(MED_GRAY, big_missile_x[number] + big_missile_direction[number] * 60, big_missile_y[number] + 1, big_missile_x[number] + big_missile_direction[number] * 40, big_missile_y[number] - 1, 0); GP142_rectangleXY(MED_GRAY, big_missile_x[number] - big_missile_direction[number] * 80, big_missile_y[number] + 2, big_missile_x[number] - big_missile_direction[number] * 140, big_missile_y[number] - 2, 0); GP142_rectangleXY(MED_GRAY, big_missile_x[number] - big_missile_direction[number] * 120, big_missile_y[number] + 30, big_missile_x[number] - big_missile_direction[number] * 140, big_missile_y[number] + 10, 0); GP142_rectangleXY(MED_GRAY, big_missile_x[number] - big_missile_direction[number] * 120, big_missile_y[number] - 10, big_missile_x[number] - big_missile_direction[number] * 140, big_missile_y[number] - 30, 0); GP142_triangleXY(MED_GRAY, big_missile_x[number] - big_missile_direction[number] * 80, big_missile_y[number] + 10, big_missile_x[number] - big_missile_direction[number] * 120, big_missile_y[number] + 10, big_missile_x[number] - big_missile_direction[number] * 120, big_missile_y[number] + 30, 0); GP142_triangleXY(MED_GRAY, big_missile_x[number] - big_missile_direction[number] * 80, big_missile_y[number] - 10, big_missile_x[number] - big_missile_direction[number] * 120, big_missile_y[number] - 10, big_missile_x[number] - big_missile_direction[number] * 120, big_missile_y[number] - 30, 0); GP142_rectangleXY(MED_GRAY, big_missile_x[number] + big_missile_direction[number] * 50, big_missile_y[number] + 30, big_missile_x[number] + big_missile_direction[number] * 40, big_missile_y[number] + 10, 0); GP142_rectangleXY(MED_GRAY, big_missile_x[number] + big_missile_direction[number] * 50, big_missile_y[number] - 30, big_missile_x[number] + big_missile_direction[number] * 40, big_missile_y[number] - 10, 0); if (big_missile_direction[number] == LEFT && big_missile_x[number] > 0) big_missile_x[number] = big_missile_x[number] - 40; else if (big_missile_direction[number] == RIGHT && big_missile_x[number] < 0) big_missile_x[number] = big_missile_x[number] + 40; else *missiles_moved = TRUE; } return; } /******************************** Displays small intro text information ********************************/ void display_intro_menu (void) { GP142_ovalXY(RED, 20, 20, -20, -20, 1); GP142_ovalXY(RED, 40, 40, -40, -40, 1); GP142_ovalXY(RED, 60, 60, -60, -60, 1); GP142_ovalXY(RED, 80, 80, -80, -80, 1); GP142_lineXY(RED, 0, 0, 0, 100, 1); GP142_lineXY(RED, 0, 0, 0,-100, 1); GP142_lineXY(RED, 0, 0, 100, 0, 1); GP142_lineXY(RED, 0, 0,-100, 0, 1); GP142_lineXY(RED, 0, 0, 40, 40, 1); GP142_lineXY(RED, 0, 0, 40, -40, 1); GP142_lineXY(RED, 0, 0, -40, 40, 1); GP142_lineXY(RED, 0, 0, -40, -40, 1); GP142_printfXY(GREEN, 0, 30, 12, "By Joel Adriance"); GP142_printfXY(GREEN, -30, -20, 12, "v1.1"); GP142_rectangleXY(MED_GRAY, -50, -100, 50, -120, 1); GP142_rectangleXY(MED_GRAY, -48, -102, 48, -118, 1); GP142_printfXY(GREEN, -44, -119, 15, "PLAY GAME"); GP142_rectangleXY(MED_GRAY, -50, -130, 50, -150, 1); GP142_rectangleXY(MED_GRAY, -48, -132, 48, -148, 1); GP142_printfXY(GREEN, -20, -149, 15, "QUIT"); return; } /*********************************************************************** This function reinitializes all the values necessary for playing the game and starts the player on level one with no score ***********************************************************************/ void start_new_game (int fragment_x1[FRAG_MAX][TRUCK_MAX], int fragment_y1[FRAG_MAX][TRUCK_MAX], int fragment_x2[FRAG_MAX][TRUCK_MAX], int fragment_y2[FRAG_MAX][TRUCK_MAX], int fragment_x3[FRAG_MAX][TRUCK_MAX], int fragment_y3[FRAG_MAX][TRUCK_MAX], int frag_move_x[FRAG_MAX][TRUCK_MAX], int frag_move_y[FRAG_MAX][TRUCK_MAX], int frag_color[FRAG_MAX][TRUCK_MAX], int chunk_x1[CHUNK_MAX][BUILDING_MAX], int chunk_y1[CHUNK_MAX][BUILDING_MAX], int chunk_x2[CHUNK_MAX][BUILDING_MAX], int chunk_y2[CHUNK_MAX][BUILDING_MAX], int chunk_x3[CHUNK_MAX][BUILDING_MAX], int chunk_y3[CHUNK_MAX][BUILDING_MAX], int chunk_move_x[CHUNK_MAX][BUILDING_MAX], int chunk_move_y[CHUNK_MAX][BUILDING_MAX], int chunk_color[CHUNK_MAX][BUILDING_MAX], int chopper_x[], int chopper_y[], int blades[], int bomber_x[], int bomber_y[], int bomb_x[], int bomb_y[], int bomber_direction[], int bomber_speed[], int bomb_target[], int detonated[], int drop_time[], int bomb_dropped[], int can_bomb[], int bomber_leaving[], int falling[], int spray_distance[], int building[], int building_destroyed[], int star_x[], int star_y[], int truck_center_x[], int truck_center_y[], int pod_pivot_x[], int pod_pivot_y[], int truck_direction[], int playing_trucks, int degree_angle[], int objective_angle[], int missile_angle[], int can_fire[], int target_reached[], int target_selected[], int destroy_timer[], int can_collide[], int explode_radius[], int distance[], int *score, int *level, int bomb_target_hit[], int building_height[], int building_width[], int building_x[], int building_y[], int building_color[], int crumble_timer[], int *kills, int *chopper_total, int *bomber_total, int *truck_color, int *enemy_color, int *city_size, int mount_x1[], int mount_y1[], int mount_x2[], int mount_y2[], int mount_x3[], int mount_y3[], int mount_color[]) { int number; *enemy_color = FOREST_GREEN; *truck_color = FOREST_GREEN; *chopper_total = 0; *bomber_total = 0; *kills = 0; *score = 0; *level = 0; generate_ship_frags( fragment_x1, fragment_y1, fragment_x2, fragment_y2, fragment_x3, fragment_y3, frag_move_x, frag_move_y, frag_color, enemy_color); generate_city_chunks ( chunk_x1, chunk_y1, chunk_x2, chunk_y2, chunk_x3, chunk_y3, chunk_move_x, chunk_move_y, chunk_color, city_size); generate_mountains ( mount_x1, mount_y1, mount_x2, mount_y2, mount_x3, mount_y3, mount_color); /*Initialization of all values for the choppers*/ for(number = 0; number < BOMBER_MAX; number ++) bomber_x[number] = 350; for (number = 0; number < CHOPPER_MAX; number ++) { /*positions choppers off the screen*/ chopper_x[number] = 350; /*Radnomly generate helicopter blades. By having the first and second blade distinguished, their lengths are alternated to simulate movement*/ if (rand() % 2 == 0) blades[number] = TRUE; else blades[number] = FALSE; } /*These are initializations for the bombers*/ for (number =0; number < *bomber_total; number ++) { bomb_dropped[number] = FALSE; can_bomb[number] = FALSE; bomber_leaving[number] = FALSE; bomb_target_hit[number] = TRUE; spray_distance[number] = 0; detonated[number] = FALSE; drop_time[number] = 0; } /*This for loop initializes all the stars in the starfield*/ for (number = 0; number < STAR_MAX; number ++) { star_x[number] = (rand() % 600 - 300); star_y[number] = (rand() % (250 - ROAD_HEIGHT) + ROAD_HEIGHT); } /*Some variable initialization*/ /*GP142_clear();*/ /*get_skylint randomly generates a city with BUILDING_MAX buildings of various hieghts, widths and positions*/ get_skyline (building_height, building_width, building_x, building_y, building_color, building_destroyed, crumble_timer, city_size); for (number = 0; number < *city_size; number ++) { /*Initially draws the city*/ GP142_rectangleXY(building_color[number], building_x[number] - building_width[number]/2, building_height[number] + building_y[number], building_x[number] + building_width[number]/2, building_y[number], 0); } /*Initializes all values for the trucks and the positions of the parts*/ playing_trucks = 4; truck_center_x[0] = -250; truck_center_y[0] = TRUCK_LEVEL; truck_direction[0] = RIGHT; truck_center_x[1] = 250; truck_center_y[1] = TRUCK_LEVEL; truck_direction[1] = LEFT; truck_center_x[2] = -180; truck_center_y[2] = TRUCK_LEVEL; truck_direction[2] = RIGHT; truck_center_x[3] = 180; truck_center_y[3] = TRUCK_LEVEL; truck_direction[3] = LEFT; for (number = 0; number < playing_trucks ; number ++) { /*By setting these angles to zero, the truck is gauranteed to begin the game with the missile pod on the bed of the truck (horizontal)*/ degree_angle[number] = 0; objective_angle[number] = 0; missile_angle[number] = 0; /*Thes variables pertain to the firing of missiles and the details of their detonation. They are all initialized to "non-fired" settings here*/ can_fire[number] = TRUE; /*means the truck can aquire a target*/ target_reached[number] = TRUE; /*Means the missile reached it's last target*/ target_selected[number] = FALSE; /*means a target has not yet been selected*/ destroy_timer[number] = 0; /*Means the missile has not detonated*/ can_collide[number] = FALSE; /*Means that the missile cannot collide with an object*/ explode_radius[number] = 0; /*this resets the circular explosion for the missile*/ distance[number] = 0; /*this resets the lines that spray out from a missile detonation*/ /*sets the position of the pitot point of the missile pod in relation to the center of the truck*/ pod_pivot_x[number] = truck_center_x[number] - truck_direction[number] * 27; pod_pivot_y[number] = truck_center_y[number] + 14; } return; } void handle_level (int *chopper_total, int *bomber_total, int *objective_kills, int *level, int *kills, int *level_window_counter) { if (*kills >= *objective_kills) { *level = *level + 1; *level_window_counter = 0; } if (*level_window_counter < 20) { GP142_rectangleXY(MED_GRAY, 40, 12, -40, -12,0); GP142_rectangleXY(BLACK, 40, 12, -40, -12,1); GP142_rectangleXY(BLACK, 38, 10, -38, -10,1); GP142_printfXY(WHITE, -23, -9, 15, "Level %d", *level); *level_window_counter = *level_window_counter + 1; } *chopper_total = 1 + *level / 3; *bomber_total = *level / 2; *objective_kills = rnd((pow(*level,2)) / 2); return; } /********************************************************************************* This functions checks the score for high score placement and displays appropriate end of game messages *********************************************************************************/ void game_over (int high_scores[], int high_levels[], int *spots_filled, int *score, int *level , int *calculated_high_scores, int *top, int can_fire[]) { int number, /*A variable used to run various for loops*/ made_it, /*Whether or not the player made the high scores*/ temp; /*stores old scores and levels so they caan be rearranged in proper order*/ if (*calculated_high_scores == FALSE) { /*Avoids errors caused by negative score values*/ if (*score > 0) { /*This for loop starts from the bottom of the high score list and test to see if the players score was greater. If it was, the scores are switched. This ensures that all scores are initially placed in the correct positions*/ for (number = 0; number < HIGH_MAX; number ++) { if (*score > high_scores[number]){ temp = high_scores[number]; high_scores[number] = *score; high_scores[number - 1] = temp; temp = high_levels[number]; high_levels[number] = *level; high_levels[number - 1] = temp; *top = *top + 1; } } } } *calculated_high_scores = TRUE; /*If *top is greater than one, the players score was greater than at least one other score in the high scores list. this is used to decide if a congratualatory message will be displayed*/ if (*top > 1) made_it = TRUE; /*Make it so the player cannot continue playing until starting a new game*/ for (number = 0; number < TRUCK_MAX; number ++) can_fire[number] = FALSE; /*displays the end of game pop-up window*/ GP142_rectangleXY(MED_GRAY, 100, 80, -100, -80, 0); GP142_rectangleXY(BLACK, 100, 80, -100, -80,1); GP142_rectangleXY(BLACK, 98, 78, -98, -78,1); /*Displays the new game and quit buttons*/ draw_button (-50,-60); GP142_printfXY(WHITE, -75, -68, 12, "New Game"); draw_button (50,-60); GP142_printfXY(WHITE, 40, -68, 12, "Quit"); /*game_over message*/ GP142_printfXY(RED, -90, 20, 30, "GAME OVER"); /*If the player had a score above any in the high scores, this message is printed under game over*/ if (made_it == TRUE) { GP142_printfXY(WHITE, -55, -10, 15, "Congratulations!"); GP142_printfXY(WHITE, -75, -25, 15, "You got got a high score."); } return; } /****************************************************************** Handles the drawing of the high_core menu ******************************************************************/ void show_high_scores (int high_scores[], int high_levels[], int *spots_filled) { int number; GP142_rectangleXY(MED_GRAY, 100, 100, -100, -100, 0); GP142_rectangleXY(BLACK, 100, 100, -100, -100,1); GP142_rectangleXY(BLACK, 98, 98, -98, -98,1); GP142_printfXY(WHITE, -35, 80, 15, "High Scores"); draw_button (0,-85); GP142_printfXY(WHITE, -10, -92, 12, "Back"); for (number = 0; number < HIGH_MAX; number ++) GP142_printfXY(WHITE, -80, 60 - number * 15, 12, "%d.)", number + 1); for (number = 0; number < HIGH_MAX; number ++) { if (high_scores[number] != 0) { GP142_printfXY(WHITE, -60, -75 + number * 15, 12, "points: %d", high_scores[number]); GP142_printfXY(WHITE, 20, -75 + number * 15, 12, "level: %d", high_levels[number]); } } return; } /************************************************************************* This functions generates a random mountain range of MOUNTAIN_MAX mountains *************************************************************************/ void generate_mountains (int mount_x1[], int mount_y1[], int mount_x2[], int mount_y2[], int mount_x3[], int mount_y3[], int mount_color[]) { int number; for (number = 0; number < MOUNTAIN_MAX; number ++) { switch (rand() % 3) { case 0: mount_color[number] = BROWN; break; case 1: mount_color[number] = DUSTY_PLUM; break; case 2: mount_color[number] = PURPLE; break; default: break; } mount_x1[number] = rand() % 200 + 300; mount_x2[number] = rand() % 300 - 500; mount_x3[number] = rand() % 500 - 250; mount_y1[number] = HORIZON; mount_y2[number] = HORIZON; mount_y3[number] = rand() % 100; } return; } /******************************************************* prints an error message if an internal error is detected *******************************************************/ void something_is_wrong (void) { /*print an error message*/ GP142_printfXY (RED, 0, 0, 16, "Program error!"); return; }