From decwrl!wyse!mips!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!uunet!zephyr.ens.tek.com!tekred!saab!billr Tue May 1 21:41:01 PDT 1990 Article 866 of comp.sources.games: Path: decwrl!wyse!mips!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!uunet!zephyr.ens.tek.com!tekred!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v09i043: xasteroids - asteroids for X11 (V2), Part01/01 Message-ID: <5527@tekred.CNA.TEK.COM> Date: 30 Apr 90 16:23:46 GMT Sender: news@tekred.CNA.TEK.COM Lines: 735 Approved: billr@saab.CNA.TEK.COM Submitted-by: philip s goetz Posting-number: Volume 9, Issue 43 Archive-name: xasteroids/Part01 [Although an X-only game, it does not meet the requirements of the comp.sources.x newsgroup (e.g. no Imakefile), so it is posted here. I made a simple Makefile (I don't know anything about Imakefiles either). -br] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'README' <<'END_OF_FILE' XNOTE: You require X-windows to run this game. X X Here is the source to X-Asteroids, version 2. The compiled code is 230K Xon my system, so don't ask for it unless you absolutely can't get it to Xcompile. Besides, it probably wouldn't run on anything at all different Xthan our SPARCstations. They run X11R4, but I believe it works on R3. X X Thanks to David Elliot, Ken Whaley, and Christophe Moret for Xfinding 2 bugs in the program. The first version didn't run on color clients. X There are 2 known bugs: X 1. After the game is over, if you leave the window Xalone, the enemy spaceship will eventually destroy all the asteroids, and Xa new level will start with your (free) spaceship in the center. From then Xon you can play the game indefinitely, since when you die, you will have -1 Xships, and the program stops when you have 0 ships. I consider this a Xfeature, and have no intention of removing it. X 2. While the game is paused (with a 'p'), you can input commands to Xchange direction and thrust, and they will be executed. So this is a way Xof cheating. This could be corrected, but why bother? If you don't like Xit, don't do it. X Also, David Elliot (dce@sonyusa.sony.com) says that he had to put Xan XSync(disp) after the XDrawLines call or he would get protocol errors. X X On anything slower than a SPARCstation 1 - say, a Sun 3/60 - it Xwill really drag. The code is not optimized because the XWindows Xcalls take the vast majority of the time. I tried, for instance, Xreading sines and cosines from a table instead of calculating them - Xit made no noticeable difference in speed. Similarly, the collision Xdetection could be optimized only to check objects nearby - but why Xbother. Same goes for using registers, pointers to frequently-referenced Xarray elements, etc. It MIGHT make a significant difference in runtime Xif you replace the vector drawing with bitmaps. X The vast majority of time seems to be used in erasing the pixmap Xeach round, & there isn't much to do about that. My tests have indicated Xthat blanking individual asteroids rather than the whole screen would Xtake comparable time, unless you had a complicated routine to optimize Xblanking. X This is only the 2nd program I have written in C, so I may have written Xpoor code. If you have any suggestions for better coding, please tell me. X(Unless you're just going to complain about my global variables and goto's Xand quota Dijkstra at me, in which case you can direct your comments Xto anal-retentive@ivory.tower.EDU where they will be better appreciated.) X XChanges that would have been made if I were being paid to do this: X X New asteroids shapes that actually look like asteroids would be nice. XYou could also specify a different graphics context for the first line of Xeach shape, so it could be invisible. (No spokes on the asteroids.) X Changing the collision-detection routine to actually check for line Xintersections rather than bounding-circle intersection would be nice. XIf you do this, only check for line intersections on objects that are Xsufficiently close to the ship. X Enough people have mentioned that they have SPARCstations that I Xmight add sound effects to it. The SPARCs have a sound chip, but Xanything I did with it would be totally incompatible with anything else. X If you modify this program, please send me a copy. X Please send any comments, suggestions, bug reports, small unmarked Xbills, etc., to X XPhil Goetz Xgoetz@cs.buffalo.EDU X XIf I could go back in time and change 20 lines in the Bible, XI could alter Western civilization beyond recognition. END_OF_FILE if test 3601 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(269 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 1 X README 1 X ast.c 1 X ast.doc 1 END_OF_FILE if test 269 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(173 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# Simple makefile for asteroids XCFLAGS = -O XX11LIB = /usr/X11/lib XX11INCLUDE = /usr/X11/include X Xast: ast.c X cc -o ast $(CFLAGS) ast.c -I$(X11INCLUDE) -L$(X11LIB) -lX11 -lm END_OF_FILE if test 173 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'ast.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ast.c'\" else echo shar: Extracting \"'ast.c'\" \(15037 characters\) sed "s/^X//" >'ast.c' <<'END_OF_FILE' X/* Version 2 4/22/90 */ X#include X#include X#include X X/* Indexes for 1st dimension of obj */ X/* The order they are in is important */ X#define AST 0 X#define ENEMY 96 X#define ENEMYBUL 97 X#define FBUL 98 X#define LASTBUL 102 X#define SHIP 103 X#define LASTSHAPE 103 X X/* Shapes */ X#define ASTSHAPE1 0 X#define ASTSHAPE2 1 X#define ASTSHAPE3 2 X#define SHIPSHAPE 3 X#define ENEMYSHAPE 4 X#define ENBULSH 5 X#define BULSHAPE 6 X X#define pi 3.1415926535897932384 X#define letheight 20 /* height of font */ X X/* Global variables: */ Xtypedef struct {double angle; int length} PolarPair; Xtypedef struct {int shape, alive, time; double x, y, xvel, yvel, rot, rotvel} Objtype; XObjtype obj[SHIP+1]; X/* In shapes pairs, 1st # is radians, 2nd is length in pixels. X Degrees: 0 ->, pi/2 down, pi <-, 3*pi/2 up X*/ XPolarPair shapes[BULSHAPE+1][11] = X { {{0,0}, {3*pi/2,40}, {0,20}, {pi/4,28}, {pi/2,40}, /* just crossed 0-deg line */ X {3*pi/4,28},{pi,40},{5*pi/4,28},{3*pi/2,40},{7*pi/4,28},{0,20}}, X/* hexagon if you prefer X {{0,0}, {3*pi/2, 20}, {pi/6, 20}, {pi/2, 20}, X {5*pi/6, 20}, {7*pi/6, 20}, {3*pi/2, 20}, {11*pi/6, 20}}, X*/ X {{0,0}, {3*pi/2,20}, {0,10}, {pi/4,14}, {pi/2,20}, X {3*pi/4,14},{pi,20},{5*pi/4,14},{3*pi/2,20},{7*pi/4,14},{0,10}}, X {{0,0}, {3*pi/2,10}, {0,5}, {pi/4,7}, {pi/2,10}, X {3*pi/4,7},{pi,10},{5*pi/4,7},{3*pi/2,10},{7*pi/4,7},{0,5}}, X {{0,0}, {5*pi/4,28}, {0,20}, {pi/4,28},{3*pi/4,28},{pi,20},{7*pi/4,28}}, /* Ship */ X {{0,0}, {pi,20},{7*pi/4,28},{pi/4,28},{pi,20}}, X {{0,0}, {7*pi/4, 4}, {pi/4, 4}, {3*pi/4, 4}, {5*pi/4, 4}}, X {{0,0}, {0,10}} X }; Xint width, height, numasts, ships, score, X highscore = 0, X rndint = 73, X oldships = 99, oldscore = 99, X nextbul = FBUL, /* Obj# of next bullet fired */ X numpairs[BULSHAPE+1] = {11, 11, 11, 7, 5, 5, 2}, X shapesize[BULSHAPE+1] = {44*44, 21*21, 10*10, 28*28, 20*20, 2, 1}; X Xdouble square(n) X double n; X{ return n*n; X} X Xint myrand() X{ extern int rndint; X rndint = rand(rndint); X return rndint; X/* Random # generator that could work if fiddled with X if (!i) i = (int) 890934; need some 1 bits X i = i >> 1 ^ (i & 4)<<13; X i = i >> 1 ^ (i & 64)<<9; X i = i >> 1 ^ (i & 2048)<<5; X return i; X*/ X} X Xinitasts() X{ int i; X extern Objtype obj[SHIP+1]; X X for (i = 0; i < LASTSHAPE+1; i++) X { obj[i].rot = 0; X obj[i].rotvel = 0; X } X for (i = 0; i < ENEMY; i++) X { obj[i].shape = ASTSHAPE1; X } X obj[SHIP].shape = SHIPSHAPE; X obj[ENEMY].shape = ENEMYSHAPE; X obj[ENEMYBUL].shape = ENBULSH; X for (i = FBUL; i < LASTBUL+1; i++) X obj[i].shape = BULSHAPE; X} X Xmakeasts(level) X{ int i; X extern Objtype obj[SHIP+1]; X extern int numasts; X unsigned char a; X X for (i = 0; i < LASTSHAPE+1; i++) X obj[i].alive = 0; /* Erase objs from last level */ X for (i = ENEMYBUL; i < LASTBUL+1; i++) X obj[i].time = 0; /* No bullets in the air */ X for (i = 0; i < level+4; i++) /* Asteroids: */ X { a = myrand(); a>>=1; /* a = rand# from 0 to 127 */ X if (a > 63) X obj[i].x = (double) a; X else obj[i].x = (double) (width - a); X a = myrand(); a>>=1; /* Now the same for y */ X if (a > 63) X obj[i].y = (double) a; X else obj[i].y = (double) height - a; X a = myrand(); a = 4 - a>>5; X obj[i].rot = (double) a; X a = myrand(); X obj[i].rotvel = ((double) a)/2048; X a = myrand(); X obj[i].xvel = cos((double) a); obj[i].yvel = sin((double) a); X obj[i].shape = ASTSHAPE1; X obj[i].alive = 1; X } X numasts = i; X} X Xmakeenemy(level) /* Start an enemy ship */ X int level; X{ extern Objtype obj[SHIP+1]; X extern int height; X unsigned char c; X X obj[ENEMY].alive = 1; X obj[ENEMY].x = 0; X obj[ENEMY].y = (double) height/4; X c = myrand(); obj[ENEMY].y += (double) c; /* May put enemy outside window */ X obj[ENEMY].xvel = (double) level/2; X obj[ENEMY].yvel = 0; X} X Xint nextast() /* Find next unused asteroid object */ X{ extern Objtype obj[SHIP+1]; X int i; X for (i = 0; obj[i].alive; i++); /* guaranteed to find one */ X return i; X} X Xint collide(i, j) /* Returns non-zero if i collided with j */ X int i, j; X{ extern Objtype obj[SHIP+1]; X extern int shapesize[BULSHAPE+1]; X int diff, xd, yd; X xd = obj[i].x - obj[j].x; X yd = obj[i].y - obj[j].y; X diff = xd*xd + yd*yd; X return (diff < shapesize[obj[i].shape] + shapesize[obj[j].shape]) ? 1 : 0; X} X Xblastpair(i, j) /* Generate random velocity vector v. */ X int i, j ; /* Add v to i, -v to j. */ X{ extern Objtype obj[SHIP+1]; X unsigned char c; /* for rand */ X double vx, vy; X c = myrand(); X/* c = 4 - c>>5; if you need angles from -3 to 4 */ X c>>2; /* possibly save some time on sin/cos */ X vx = cos((double) c); vy = sin((double) c); X obj[i].xvel = obj[i].xvel + vx; X obj[i].yvel = obj[i].yvel + vy; X obj[j].xvel = obj[j].xvel - vx; X obj[j].yvel = obj[j].yvel - vy; X obj[i].rotvel = obj[i].rotvel + .05; X obj[j].rotvel = obj[j].rotvel - .05; X} X Xprintss(disp, window, gc) /* Print ships and score */ X Display *disp; X Drawable window; X GC gc; X{ extern int ships, score, highscore, height, X oldships, oldscore; X extern Objtype obj[SHIP+1]; /* to kill ship */ X char sstring[30]; X if (score != oldscore) X { if (score/10000 > oldscore/10000) ships++; X if (score/10000 < oldscore/10000) X { ships--; X if (!ships) obj[SHIP].alive = 0; X } X if (score > highscore) X { highscore = score; X sprintf(sstring, "High score: %d", highscore); X XDrawImageString (disp, window, gc, 330, height+letheight, sstring, strlen(sstring)); X } X sprintf(sstring, "Score: %d ", score); X XDrawImageString (disp, window, gc, 110, height+letheight, sstring, strlen(sstring)); X oldscore = score; X } X if (ships != oldships) X { sprintf(sstring, "Ships: %d ", ships); X XDrawImageString (disp, window, gc, 0, height+letheight, sstring, strlen(sstring)); X oldships = ships; X } X} X Xupscore(killer, up) /* Only award score for things the player shot */ X int killer, up; X{ extern int score; X if (killer != ENEMYBUL && killer != SHIP) X score = score + up; X} X Xkillast(killer, i) X int killer, i; /* i = Asteroid # to kill */ X{ extern Objtype obj[SHIP+1]; X extern int numasts; X int k, na, oldna; X X if (obj[i].shape == ASTSHAPE1) X { na = nextast(); /* Could put 6 lines in a sub */ X obj[na].x = obj[i].x; X obj[na].y = obj[i].y; X obj[na].xvel = obj[i].xvel; X obj[na].yvel = obj[i].yvel; X obj[na].alive++; X obj[na].shape = ASTSHAPE2; X obj[i].shape = ASTSHAPE2; X blastpair(i, na); X numasts = numasts + 1; X upscore(killer, 25); X } X else if (obj[i].shape == ASTSHAPE2) X { X for (k = 0; k < 3; k++) X { oldna = na; X na = nextast(); X obj[na].x = obj[i].x; X obj[na].y = obj[i].y; X obj[na].xvel = obj[i].xvel; X obj[na].yvel = obj[i].yvel; X obj[na].alive++; X obj[na].shape = ASTSHAPE3; X if (k == 1) blastpair(oldna,na); X } X obj[i].shape = ASTSHAPE3; X blastpair(na, i); X numasts = numasts + 3; X upscore(killer, 50); X } X else if (obj[i].shape == ASTSHAPE3) X { obj[i].alive = 0; numasts--; upscore(killer, 100);} X else /* enemy {ship or bullet} */ X { obj[i].alive = 0; upscore(killer, 500);} X} Xmoveobjs(crash) X int *crash; X{ extern Objtype obj[SHIP+1]; X extern int ships; X int i, j; /* Indexes */ X double *temp; X X for (i = 0; i < LASTSHAPE+1; i++) X if (obj[i].alive) X { temp = &obj[i].x; X *temp = *temp + obj[i].xvel; X while (*temp < 0) *temp = *temp + (double) width; X while (*temp > width) *temp = *temp - (double) width; X temp = &obj[i].y; X *temp = *temp + obj[i].yvel; X while (*temp < 0) *temp = *temp + height; X while (*temp > height) *temp = *temp - height; X obj[i].rot = obj[i].rot + obj[i].rotvel; X } X for (i = 0; i < FBUL; i++) X if (obj[i].alive) X { X if (obj[SHIP].alive && collide(i, SHIP)) X { *crash = 2; X ships--; obj[SHIP].alive = 0; X killast(SHIP, i); X } X for (j = ENEMYBUL; j < LASTBUL+1; j++) X if (obj[j].alive && collide(i, j) && (j != ENEMYBUL || (i != ENEMYBUL && i != ENEMY))) X { obj[j].alive = 0; /* Kill the bullet */ X killast(j,i); X } X } X} X Xfire() X{ extern Objtype obj[SHIP+1]; X extern int width, nextbul; X double *shiprot, cosrot, sinrot; X X obj[nextbul].alive++; X shiprot = &obj[SHIP].rot; X cosrot = cos(*shiprot); sinrot = sin(*shiprot); X obj[nextbul].x = obj[SHIP].x + 20 * cosrot; X obj[nextbul].y = obj[SHIP].y + 20 * sinrot; X obj[nextbul].xvel = obj[SHIP].xvel + 10 * cosrot; X obj[nextbul].yvel = obj[SHIP].yvel + 10 * sinrot; X obj[nextbul].rot = *shiprot; X obj[nextbul].time = width/11; /* loops before bullet expires */ X nextbul++; if (nextbul == LASTBUL+1) nextbul = FBUL; X} X Xhyper() X{ extern Objtype obj[SHIP+1]; X extern int width, height; X unsigned char c; X unsigned int i; X X c = myrand(); i = c; i<<=2; /* 0 - 1024 */ X while (i > width) i -= width; X obj[SHIP].x = (double) i; X c = myrand(); i = c; i<<=2; /* 0 - 1024 */ X while (i > height) i -= height; X obj[SHIP].y = (double) i; X} X Xvdraw(disp, window, gc, shape, x, y, rot) X Display *disp; X Drawable window; X GC gc; X int shape, x, y; X double rot; X{ int line; X extern PolarPair shapes[BULSHAPE+1][11]; X extern int numpairs[BULSHAPE+1]; X XPoint figure[20]; X figure[0].x = x; figure[0].y = y; X for (line=1; line < numpairs[shape]; line++) /* 2 pairs = 1 line */ X { figure[line].x = shapes[shape][line].length * X cos(shapes[shape][line].angle + rot); X figure[line].y = shapes[shape][line].length * X sin(shapes[shape][line].angle + rot); X } X XDrawLines (disp, window, gc, figure, numpairs[shape], CoordModePrevious); X} X Xmain(argc, argv) X int argc; X char **argv; X{ Display *disp; X Pixmap pixmap; X Window window; X GC gc, pmgc; X Font font; X XEvent event; X KeySym key; X XSizeHints hint; X extern int width, height; X int screen, depth; X char text[10]; X unsigned long fg, bg; X X int level, crashed, flashon, len, pause = 0, delay = 64, X enemycount, X i; /* index for drawing objs, counting bullets */ X unsigned char c; /* for rand */ X double *temp, dx, dy, dist; X extern Objtype obj[SHIP+1]; X extern int numasts, ships, score, oldscore, oldships; X X disp = XOpenDisplay(0); X screen = DefaultScreen(disp); X bg = BlackPixel(disp, screen); X fg = WhitePixel(disp, screen); X hint.x = 150; hint.y = 200; hint.width = 550; hint.height = 550; X hint.flags = PPosition | PSize; X width = hint.width; height = hint.height-letheight-1; X depth = DefaultDepth (disp, screen); X window = XCreateSimpleWindow (disp, DefaultRootWindow(disp), X hint.x, hint.y, hint.width, hint.height, 5, fg, bg); X pixmap = XCreatePixmap (disp, window, width, height, depth); X XSetStandardProperties (disp, window, "asteroids", "asteroids", None, X argv, argc, &hint); X gc = XCreateGC (disp, window, 0, 0); X XSetGraphicsExposures(disp, gc, 0); /* IMPORTANT! If you do not X specifically ask not to get Expose events, every XCopyArea X will generate one, & the event queue will fill up. */ X font = XLoadFont(disp, "10x20\0"); /* If you don't have this X font, try replacing it with 9x15\0 */ X XSetFont(disp, gc, font); X pmgc = XCreateGC (disp, window, 0, 0); X XSetBackground (disp, gc, bg); X XSetForeground (disp, gc, fg); X XSetForeground (disp, pmgc, bg); /* fg of pixmap is bg of window */ X XSelectInput (disp, window, KeyPressMask | StructureNotifyMask); X XMapRaised (disp, window); X X/* srand(); */ X initasts(); XNewgame: X ships = 3; X score = 0; X printss(disp, window, gc); X XSync(disp, 0); /* Should let user see ships & score X but apparently XSync doesn't work */ X for (level = 0; ;) X { if (level < 8) level++; X makeasts (level); XNewship: obj[SHIP].alive = 1; X obj[SHIP].x = width/2; X obj[SHIP].y = height/2; X obj[SHIP].xvel = 0; X obj[SHIP].yvel = 0; X obj[SHIP].rot = 3*pi/2; X obj[SHIP].rotvel = 0; X crashed = 0; flashon = 0; enemycount = 20; X while (numasts) X { for (i = FBUL; i < LASTBUL+1; i++) /* Bullet timer */ X if (obj[i].alive) X { obj[i].time--; X if (!obj[i].time) obj[i].alive = 0; /* Not --! */ X } X if (XEventsQueued(disp, QueuedAfterReading)) X { XNextEvent(disp, &event); X switch (event.type) X { case MappingNotify: X XRefreshKeyboardMapping (&event); X break; X case ConfigureNotify: X width = event.xconfigure.width; X height = event.xconfigure.height-letheight-1; X XFreePixmap (disp, pixmap); X pixmap = XCreatePixmap (disp, window, width, height, depth); X break; X case KeyPress: X len = XLookupString (&event, text, 10, &key, 0); X if (len == 1) switch (text[0]) X { case 'e': X obj[SHIP].rot = obj[SHIP].rot - .2; break; X case 'r': X obj[SHIP].rot = obj[SHIP].rot + .2; break; X case 'd': X obj[SHIP].rotvel = obj[SHIP].rotvel - .02; break; X case 'f': X obj[SHIP].rotvel = obj[SHIP].rotvel + .02; break; X case ';': /* thrust */ X temp = &obj[SHIP].xvel; X *temp = *temp + X cos(obj[SHIP].rot); X temp = &obj[SHIP].yvel; X *temp = *temp + X sin(obj[SHIP].rot); X break; X case '\'': X if (obj[SHIP].alive) fire(); break; X case ' ': X if (obj[SHIP].alive) X { hyper(); flashon = 1; X/* XSetForeground (disp, gc, bg); X If you set the fg black, & print the highscore, it will effectively erase it. */ X XSetForeground (disp, pmgc, fg); X } X break; X case '<': /* decrease delay */ X if (delay > 1) delay >>=1; break; X case '>': /* increase delay */ X delay <<=1; break; X case 'p': /* pause */ X pause = 1 - pause; break; X case 'q': /* quit */ X goto End; X case 's': /* start new ship */ X if (!obj[SHIP].alive) X if (!ships) goto Newgame; X else goto Newship; X break; X } X/* break; */ X } } X if (!pause) X { moveobjs(&crashed); X /* Draw objects */ X if (crashed == 2) X { crashed--; flashon++; X/* XSetForeground (disp, gc, bg); X*/ X XSetForeground (disp, pmgc, fg); X } X for (i = 0; i <= LASTSHAPE; i++) X if (obj[i].alive) X vdraw(disp, pixmap, gc, obj[i].shape, X (int) obj[i].x, (int) obj[i].y, obj[i].rot); X /* update display: */ X if (ships) score--; /* timer effect */ X printss(disp, window, gc); X XCopyArea(disp, pixmap, window, gc, 0, 0, width, height, 0, 0); X XFillRectangle (disp, pixmap, pmgc, 0, 0, width, height); /* erase pixmap; */ X if (flashon) X { flashon--; X/* XSetForeground (disp, gc, fg); X*/ X XSetForeground (disp, pmgc, bg); X } X XSync(disp, 0); X c = myrand()>>8; X if (!obj[ENEMY].alive) X { if (c < level) X { c = myrand(); X if (c < level * 10) makeenemy(level); X } } X else X obj[ENEMY].yvel += (c>128+6*obj[ENEMY].yvel) ? .5 : -.5; X enemycount--; if (!enemycount) X { enemycount = 100; X if (obj[ENEMY].alive) X { obj[ENEMYBUL].alive++; X obj[ENEMYBUL].x = obj[ENEMY].x; X obj[ENEMYBUL].y = obj[ENEMY].y; X dx = obj[SHIP].x - obj[ENEMY].x; X dy = obj[SHIP].y - obj[ENEMY].y; X dist = sqrt(square(dx) + square(dy)); X obj[ENEMYBUL].xvel = 3*dx/dist; X obj[ENEMYBUL].yvel = 3*dy/dist; X } X else obj[ENEMYBUL].alive = 0; X } X for (i = 0; i < delay; i++); X } X } X } XEnd: printf("\nYour high score was %d\n", highscore); X XFreeGC (disp, gc); X XFreeGC (disp, pmgc); X XFreePixmap (disp, pixmap); X XDestroyWindow (disp, window); X XCloseDisplay (disp); X exit(0); X} X END_OF_FILE if test 15037 -ne `wc -c <'ast.c'`; then echo shar: \"'ast.c'\" unpacked with wrong size! fi # end of 'ast.c' fi if test -f 'ast.doc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ast.doc'\" else echo shar: Extracting \"'ast.doc'\" \(800 characters\) sed "s/^X//" >'ast.doc' <<'END_OF_FILE' X X X-Asteroids X X Copyright 1990 by Phil Goetz X goetz@cs.Buffalo.EDU X XKeypress Command X-------- ------- X e Rotate counterclockwise ("left") X r Rotate clockwise ("right") X d Increase counterclockwise rotational velocity X f Increase clockwise rotational velocity X ; Thrust X ' Fire X space Hyperspace X s Start new ship in center of playing field X (Also used to start a new game) X > Increase delay: Slow the game down X < Decrease delay: Speed game up X p Pause X XObject Score X------- ----- XBig asteroid 25 XMedium asteroid 50 XLittle asteroid 100 XEnemy spaceship 500 XEnemy bullet 500 X XCommands can only be entered when the mouse pointer is in the Xasteroids window. X XResize the window with your window manager Xat any time for a different playing field. END_OF_FILE if test 800 -ne `wc -c <'ast.doc'`; then echo shar: \"'ast.doc'\" unpacked with wrong size! fi # end of 'ast.doc' fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have the archive. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0