|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 7268 (0x1c64) Types: TextFile Names: »rocks.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/X/Roids/rocks.c«
/* rkocks.c - handle movement, etc. of the rocks. */ #include "roids.h" #define NUMTYPES 3 /* How many types of rocks there are. */ #define MAXPOINTS 10 /* Maximum number of points in a rock. */ #define MAXROCKS 256 /* Maximum rocks we'll have at one time. */ static int numtocreate = 4; /* How many rocks to create each round. */ #define DIAMONDDATA(size) \ {0, size}, \ {size, 0}, \ {0, -size}, \ {-size, 0}, static int smallshape[][2] = { DIAMONDDATA(10) }; static int mediumshape[][2] = { DIAMONDDATA(15) }; static int largeshape[][2] = { DIAMONDDATA(20) }; static int ***shapes; static int numpoints[NUMTYPES] = {XtNumber(largeshape), XtNumber(mediumshape), XtNumber(smallshape)}; int radius[NUMTYPES]; extern double sx, sy; /* Ship location. */ typedef struct _RockRec { double x, y; /* Location. */ double vx, vy; /* Velocity. */ int radius; /* Radius of this rock. */ int **shape; /* Pointer to shape record. */ int numpoints; /* Number of points in shape record. */ } RockRec, *Rock; RockRec rocks[MAXROCKS+2]; int numrocks = 0; /* Number of rocks existing. */ #define RockNearBox(rock, minx, maxx, miny, maxy) \ (rint((rock)->x) - (rock)->radius <= (maxx) && \ rint((rock)->y) - (rock)->radius <= (maxy) && \ rint((rock)->x) + (rock)->radius >= (minx) && \ rint((rock)->y) + (rock)->radius >= (miny)) #define RandomSpeed() (maxrockspeed * (random() % 2000 - 1000) / 1000.0) Boolean AreaForShipIsClear() { int minx, maxx, miny, maxy, i; Rock rock; minx = sx - 5 * shipradius; maxx = sx + 5 * shipradius; miny = sy - 5 * shipradius; maxy = sy + 5 * shipradius; for (i=0, rock = rocks ; i<numrocks ; i++, rock++) { if (RockNearBox(rock, minx, maxx, miny, maxy)) return FALSE; } return TRUE; } static void ConfigureRock(rock, x, y, vx, vy, shape, numpoints, radius) Rock rock; double x, y, vx, vy; int **shape; int numpoints, radius; { rock->x = x; rock->y = y; rock->vx = vx; rock->vy = vy; rock->shape = shape; rock->numpoints = numpoints; rock->radius = radius; } static void PaintRock(rock, gc) Rock rock; GC gc; { register int x = rock->x; register int y = rock->y; register int i; for (i=0 ; i<rock->numpoints ; i++) AddLine(x + rock->shape[i][0], y + rock->shape[i][1], x + rock->shape[i+1][0], y + rock->shape[i+1][1], gc); } /* * Destroy rock #i. Often, this means creating two rocks in its place. The * point given is used to determine the direction of the destroying influence, * and thus which direction the two rocks should go. */ static void DestroyRock(i, x, y) int i, x, y; { int num, value; Rock rock = rocks + i; double oldx = rock->x; double oldy = rock->y; PaintRock(rock, backgc); value = 50; for (num = 0 ; num < NUMTYPES ; num++) if (rock->shape == shapes[num]) break; else value *= 2; if (num >= NUMTYPES) Punt("Couldn't find shape in DestroyRock!"); score += value; PaintScore(); numrocks--; rocks[i] = rocks[numrocks]; num++; if (num < NUMTYPES) { for (i=numrocks ; i<MIN(MAXROCKS, numrocks+2) ; i++) { ConfigureRock(rocks + i, oldx, oldy, RandomSpeed(), RandomSpeed(), shapes[num], numpoints[num], radius[num]); } numrocks = MIN(MAXROCKS, numrocks + 2); } } Boolean LineHitsRock(ax, ay, bx, by) int ax, ay, bx, by; { register Rock rock; int i, j, x, y; register int minx, miny, maxx, maxy; int **shape; minx = MIN(ax, bx); maxx = MAX(ax, bx); miny = MIN(ay, by); maxy = MAX(ay, by); for (i=0, rock = rocks ; i<numrocks ; i++, rock++) { if (RockNearBox(rock, minx, maxx, miny, maxy)) { shape = rock->shape; x = rock->x; y = rock->y; for (j=0 ; j<rock->numpoints ; j++) { if (CheckIntersects(ax, ay, bx, by, shape[j][0] + x, shape[j][1] + y, shape[j+1][0] + x, shape[j+1][1] + y)) { DestroyRock(i, ax, ay); return TRUE; } } } } return FALSE; } /* * Carefully check if the given rock has hit the ship. If so, destroy the * rock (creating new rocks as necessary), and return TRUE. This does not * touch the ship; that is left to the calling routine. */ static Boolean CheckForCrash(rock) Rock rock; { extern int px[], py[]; int i, j, ax, ay, bx, by; int **shape = rock->shape; int x = rock->x; int y = rock->y; if (shipdestroyed) return FALSE; for (i=0 ; i < NPOINTS ; i++) { ax = px[i]; ay = py[i]; bx = px[(i+1) % NPOINTS]; by = py[(i+1) % NPOINTS]; for (j=0 ; j<rock->numpoints ; j++) { if (CheckIntersects(ax, ay, bx, by, shape[j][0] + x, shape[j][1] + y, shape[j+1][0] + x, shape[j+1][1] + y)) { DestroyRock(rock - rocks, rint(sx), rint(sy)); return TRUE; } } } return FALSE; } Boolean CheckIfShipHitRocks() { int i, minx, miny, maxx, maxy; Rock rock; minx = sx - shipradius; miny = sy - shipradius; maxx = sx + shipradius; maxy = sy + shipradius; for (i=0, rock = rocks ; i < numrocks ; i++, rock++) { if (RockNearBox(rock, minx, maxx, miny, maxy)) { if (CheckForCrash(rock)) return TRUE; } } return FALSE; } void PaintAllRocks() { int i; for (i=0 ; i<numrocks ; i++) PaintRock(rocks + i, rockgc); } void MoveRocks(closure, id) Opaque closure; XtIntervalId id; { register Rock rock; register int i; int minx, miny, maxx, maxy; if (closure != (Opaque) MoveRocks) return; rocktimerid = XtAddTimeOut(rockwait, MoveRocks, (Opaque) MoveRocks); if (numrocks == 0) { numrocks = MIN(numtocreate, MAXROCKS); numtocreate += 2; for (i=0 ; i<numrocks ; i++) { ConfigureRock(rocks + i, 0.0, 0.0, RandomSpeed(), RandomSpeed(), shapes[0], numpoints[0], radius[0]); } } minx = sx - shipradius; miny = sy - shipradius; maxx = sx + shipradius; maxy = sy + shipradius; for (i=0 ; i<numrocks ; i++) { rock = rocks + i; PaintRock(rock, backgc); rock->x += rock->vx; rock->y += rock->vy; rock->x = (rock->x < 0) ? rock->x + gamewidth : ((rock->x > gamewidth) ? rock->x - gamewidth : rock->x); rock->y = (rock->y < 0) ? rock->y + gameheight : ((rock->y > gameheight)? rock->y - gameheight: rock->y); PaintRock(rock, rockgc); if (RockNearBox(rock, minx, maxx, miny, maxy)) { if (CheckForCrash(rock)) DestroyShip(); } } } static void SetIt(shape, init, num) int **shape; int init[][2]; int num; { int i, j; for (i=0 ; i<num+1 ; i++) { shape[i] = (int *) XtMalloc(sizeof(int) * 2); for (j=0 ; j<2 ; j++) shape[i][j] = init[i%num][j]; } } void InitRocks() { int i, j, m; rocktimerid = NULL; shapes = (int ***) XtMalloc(sizeof(int **) * NUMTYPES); for (i=0 ; i<NUMTYPES ; i++) { shapes[i] = (int **) XtMalloc(sizeof(int *) * (numpoints[i] + 1)); } SetIt(shapes[0], largeshape, numpoints[0]); SetIt(shapes[1], mediumshape, numpoints[1]); SetIt(shapes[2], smallshape, numpoints[2]); for (i=0 ; i<NUMTYPES ; i++) { m = -1; for (j=0 ; j<numpoints[i] ; j++) { m = MAX(m, shapes[i][j][0]); m = MAX(m, shapes[i][j][1]); } radius[i] = m; } }