defender.c

来自「开发linux应用-用gtk+和gdk开发linux图形用户界面应用--的实例」· C语言 代码 · 共 1,642 行 · 第 1/3 页

C
1,642
字号
/* * File: defender.c * Auth: Eric Harlow * * Sort of like the 1980's game defender, but not a  * complete version. * */#include <gtk/gtk.h>#include "defender.h"#include "defproto.h"#include "mutant.h"#include "math.h"/* * How many people and aliens should the game start * out with? */#define START_ALIENS 10#define START_PEOPLE 10/* * These are for the acceleration, of the player/hero, the * effect of friction to slow him down, and the maximum * velocity that can be attained. */#define FRICTION .5#define MAX_SPEED 16#define ACCELERATION 3.5    /* * Of course, the laser has to be configurable too.  The  * laser beam has a speed (how fast it travels out) and  * a length (primarily for show). */#define LASER_LENGTH 60#define LASER_SPEED 60/* * Range of the game. */#define X_RANGE 2000/* * How high the mountain peaks are. */#define MAX_PEAK 150/* * The number of mountain peaks generated. */#define NUM_PEAKS 10 /*   * --- Trigger happiness  * * The mutants are much more trigger happy than the landers * are.  */#define LANDER_TRIGGER_PCT 3#define MUTANT_TRIGGER_PCT 6/* * During an explosion, we use eight sprites spiraling away * from where the item exploded.  These are the eight  * directions. */int x_exp[] = {1, 1, 0, -1, -1, -1, 0, 1};int y_exp[] = {0, 1, 1, 1, 0, -1, -1, -1}; /* * How big is the radar screen. */#define RADAR_WIDTH 200#define RADAR_HEIGHT 50/* * How big are other things in the screen */#define GAME_HEIGHT 220#define BOTTOM_HEIGHT 30#define PERSON_HEIGHT (RADAR_HEIGHT+GAME_HEIGHT+7)/* * Colors used for drawing */GdkGC *penGreen = NULL;GdkGC *penWhite = NULL;GdkGC *penPurple = NULL;GdkGC *penRed = NULL;/* * variables used in calculations */int nShipAdjustment;int nRelativeAdjustment;int nScreenWidth;/* * Define the sprites for the cast of characters. */typSprite sprite_man[1]     = { { xpm_man, NULL, NULL, 0, 0 } };typSprite sprite_ship1[1]   = { { xpm_ship1, NULL, NULL, 0, 0 } };typSprite sprite_ship2[1]   = { { xpm_ship2, NULL, NULL, 0, 0 } };typSprite sprite_lander[1]  = { { xpm_lander, NULL, NULL, 0, 0 } };typSprite sprite_mutant[1]  = { { xpm_mutant, NULL, NULL, 0, 0 } };typSprite sprite_missile[1] = { { xpm_missile, NULL, NULL, 0, 0 } };/* * The ship could be pointing left or right (sprite_ship1, * sprite_ship2) - however, sprite_ship is what's used to  * draw it.  If the ship changes direction, then this  * should also be adjusted. */typSprite *sprite_ship = sprite_ship1;/* * List of mountain peaks. */GList *terrainList = NULL;/* * All the units in the game */GList *unitList = NULL;/* * The hero. */typUnit *hero = NULL;/* * Prototypes. */GdkColor *NewColor (long red, long green, long blue);GdkGC *GetPen (GdkColor *c);void GetWidthHeight (gchar **xpm, int *width, int *height);void DisplaySprite (GtkWidget *drawing_area, typSprite *sprite, int x, int y);/* * UnitScreenX * * Convert the unit's X coordinates to screen coordinates  * relative to the hero's coordinates. */int UnitScreenX (typUnit *unit){    int xPos;    /* --- Adjust -x- if out of range --- */    if (unit->x < 0) {        unit->x += X_RANGE;    } else if (unit->x > X_RANGE) {        unit->x -= X_RANGE;    }    /* --- Make it relative --- */    xPos = (int) (unit->x - nRelativeAdjustment);    /* --- Readjust -x- if out of range --- */    if (xPos < 0) xPos += X_RANGE;    if (xPos > X_RANGE) xPos -= X_RANGE;    return (xPos);}/* * ScreenX * * Take the game -x- value and convert it to the screen  * -x- value.  */int ScreenX (int x){    int xPos;    /* --- Adjust if out of range --- */    if (x < 0) {        x += X_RANGE;    } else if (x > X_RANGE) {        x -= X_RANGE;    }    /* --- Make it absolute --- */    xPos = (int) (x - nRelativeAdjustment);    /* --- Readajust if out of range --- */    if (xPos < (-(X_RANGE - nScreenWidth) / 2)) {        xPos += X_RANGE;    } else if (xPos > ((X_RANGE - nScreenWidth) / 2)) {        xPos -= X_RANGE;    }    return (xPos);}/* * GameX * * Take a screen -x- value and convert it to the  * game coordinate -x- value. */int GameX (int x){    int xPos;    /* --- Relative to the hero --- */    xPos = (int) (x + nRelativeAdjustment);      /* --- Make sure it's not out of range --- */    if (xPos < 0) xPos += X_RANGE;    if (xPos > X_RANGE) xPos -= X_RANGE;    return (xPos);}/* * Move  * * Move a unit in the X direction by vx (velocity in x) and * in the Y direction by vy. */void Move (typUnit *unit){    /* --- Move the unit --- */    unit->y += unit->vy;    unit->x += unit->vx;    /* --- But keep it within the world --- */    if (unit->x < 0) unit->x += X_RANGE;    if (unit->x > X_RANGE) unit->x -= X_RANGE;}/* * LoadPixmaps * * Load the image into the sprite. */void LoadPixmaps (GtkWidget *widget, typSprite *sprites){    /* --- Create a pixmap from the xpm data --- */    sprites->pixmap = gdk_pixmap_create_from_xpm_d (                               widget->window,                               &sprites->mask,                               NULL,                               sprites->xpm_data);    /* --- Get the width and height --- */    GetWidthHeight (sprites->xpm_data,                     &sprites->width,                     &sprites->height);}/* * LoadImages * * Load up the images so that we can display them in the * game and configure the colors. */void LoadImages (GtkWidget *window){    /* --- Load up the images --- */    LoadPixmaps (window, sprite_man);    LoadPixmaps (window, sprite_ship1);    LoadPixmaps (window, sprite_ship2);    LoadPixmaps (window, sprite_lander);    LoadPixmaps (window, sprite_mutant);    LoadPixmaps (window, sprite_missile);    /* --- Get the colors defined --- */    penRed = GetPen (NewColor (0xffff, 0x8888, 0x8888));    penGreen = GetPen (NewColor (0, 0xffff, 0));    penPurple = GetPen (NewColor (0xffff, 0, 0xffff));    penWhite = GetPen (NewColor (0xffff, 0xffff, 0xffff));}/* * CreateHero * * Create the typUnit for the player and initialize * it with the player settings. */typUnit *CreateHero (){    /* --- Allocate the memory --- */    hero = g_malloc (sizeof (typUnit));    /* --- Initialize player information --- */    hero->bDestroy = FALSE;    hero->direction = 1;    hero->type = HERO;    hero->x = 0;    hero->y = 150;    hero->vx = 0;    hero->vy = 0;    hero->lockunit = NULL;    /* --- Return object. --- */    return (hero);}/* * HeroFile * * Our hero is opening fire!  Create a laser shot * and add it to the global list of units. */void HeroFire (){    typUnit *laser;    /* --- Create the laser --- */    laser = (typUnit *) g_malloc (sizeof (typUnit));    /* --- The direction is the same as the spaceship --- */    laser->direction = hero->direction;    laser->type = LASER;    /*      * Move the starting point of the laser in front of the      * spaceship.      */    if (laser->direction > 0) {        laser->x = hero->x + (sprite_ship->width / 2);    } else {        laser->x = hero->x - (sprite_ship->width / 2);    }    laser->y = hero->y + 4;    laser->vx = LASER_SPEED * hero->direction;    laser->vy = 0;    laser->lockunit = NULL;    laser->bDestroy = 0;    /* --- Laser bolt lasts through two movements. --- */    laser->life = 2;    /* --- Add the laser to the list of units --- */    unitList = g_list_append (unitList, laser);}/* * HeroMove * * Move the player in the direction specified.  */void HeroMove (int direction){    switch (direction) {        case MOVE_UP:            hero->y -= 3;            break;        case MOVE_DOWN:            hero->y += 3;            break;        case MOVE_LEFT:            /*              * Make sure the ship is pointing in the             * correct direction.             */            sprite_ship = sprite_ship2;            hero->direction = -1;            /* --- Speed up the ship --- */            hero->vx -= ACCELERATION;            break;        case MOVE_RIGHT:            /*              * Make sure the ship is pointing in the             * correct direction.             */            sprite_ship = sprite_ship1;            hero->direction = 1;            /* --- Speed up the ship --- */            hero->vx += ACCELERATION;            break;    }}/* * ApplyFriction * * Slow down gradually and make sure the player cannot go  * into warp speed by holding down the acceleration. */void ApplyFriction (){    /* --- Slow ship down --- */    if (hero->vx > FRICTION) {        hero->vx -= FRICTION;    } else if (hero->vx < -FRICTION) {        hero->vx += FRICTION;    } else {        /* --- Speed less than friction, we stop --- */        hero->vx = 0;    }    /* --- Don't let the maximum speed be exceeded --- */    if (hero->vx > MAX_SPEED) hero->vx = MAX_SPEED;    if (hero->vx < -MAX_SPEED) hero->vx = -MAX_SPEED;}/* * CreatePerson * * Create the little people on the planet. */typUnit *CreatePerson (){    typUnit *person;    /* --- Allocate the memory --- */    person = g_malloc (sizeof (typUnit));    /* --- Initialize the person --- */    person->bDestroy = FALSE;    person->direction = 0;    person->type = PERSON;    person->x = rand () % X_RANGE;    person->y = PERSON_HEIGHT;    person->vx = 0;    person->vy = 0;    person->lockunit = NULL;    return (person);}/* * PlacePeople * * Create people randomly and place them on the screen */void PlacePeople (){    int i;    typUnit *person;    /* --- Create all the little people --- */    for (i = 0; i < START_PEOPLE; i++) {        /* --- Create a person --- */        person = CreatePerson ();        /* --- Add it to the list of units --- */        unitList = g_list_append (unitList, person);    }}/* * CreateAlien * * Create an alien lander  */typUnit *CreateAlien (){    typUnit *alien;    /* --- Get the memory --- */    alien = g_malloc (sizeof (typUnit));    /* --- Initialize the structure --- */    alien->bDestroy = FALSE;    alien->pctFiring = LANDER_TRIGGER_PCT;    alien->type = LANDER;    alien->x = rand () % X_RANGE;    alien->y = rand () % 50 + RADAR_HEIGHT ;    alien->vx = 0;    alien->vy = 0;    alien->lockunit = NULL;    return (alien);}/* * CreateMissile * * Missiles are what the aliens fire.  They are given * a fixed direction and last a limited amount of time * before they disappear. */typUnit *CreateMissile (typUnit *alien, typUnit *hero){    float flength;    typUnit *missile;    /* --- Allocate the memory --- */    missile = (typUnit *) g_malloc (sizeof (typUnit));    /* --- Inialize the structure --- */    missile->bDestroy = FALSE;    missile->pctFiring = 0;    missile->type = MISSILE;    missile->x = alien->x;    missile->y = alien->y;    /* --- Calculate missile velocity --- */    missile->vx = (float) DistanceBetween (missile, hero) *                           Direction (missile, hero);    missile->vy = (float) (hero->y - alien->y);    /*      * Adjust missile velocity     */    flength = sqrt (missile->vx * missile->vx + missile->vy * missile->vy);    if (flength < .1) flength = .1;    flength /= 3;    missile->vx /= flength;    missile->vy /= flength;    missile->lockunit = NULL;    /* 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?