[comp.sources.x] v08i065: xinvaders -- space invaders for X, Part04/05

jgoldman@parc.xerox.com (Jonny Goldman) (08/04/90)

Submitted-by: Jonny Goldman <jgoldman@parc.xerox.com>
Posting-number: Volume 8, Issue 65
Archive-name: xinvaders/part04

X	vader1pixel = defaultfore;
X	vader2pixel = defaultfore;
X	vader3pixel = defaultfore;
X	shotpixel = defaultfore;
X	vshotpixel = defaultfore;
X	scorepixel = defaultfore;
X    }
X    width = VWIDTH;
X    height = VHEIGHT;
X    args[0].value = (XtArgVal) width;
X    args[1].value = (XtArgVal) height;
X    pane = XtCreateWidget("pane", panedWidgetClass, toplevel,
X			  args, XtNumber(args));
X    XtManageChild(pane);
X    scoreargs[0].value = (XtArgVal) scorepixel;
X    scorewidget = XtCreateWidget("score", labelWidgetClass, pane,
X				 scoreargs, XtNumber(scoreargs));
X    /*
X    XtManageChild(scorewidget);
X    */
X    gamewidget = (VadersWidget)
X	XtCreateWidget("field", vadersWidgetClass, pane, NULL, 0);
X    XtManageChild(gamewidget);
X    XtRealizeWidget(toplevel);
X    spacer_counter = 1000;
X    XtMainLoop();
X}
X
X
XPunt(msg)
X{
X    fprintf(stderr, "%s\n", msg);
X    exit(1);
X}
END_OF_FILE
if test 5151 -ne `wc -c <'main.c'`; then
    echo shar: \"'main.c'\" unpacked with wrong size!
fi
# end of 'main.c'
fi
if test -f 'vaders.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vaders.c'\"
else
echo shar: Extracting \"'vaders.c'\" \(6812 characters\)
sed "s/^X//" >'vaders.c' <<'END_OF_FILE'
X/* 
XCopyright notice:
X
XThis is mine.  I'm only letting you use it.  Period.  Feel free to rip off
Xany of the code you see fit, but have the courtesy to give me credit.
XOtherwise great hairy beasties will rip your eyes out and eat your flesh
Xwhen you least expect it.
X
XJonny Goldman <jgoldman@parc.xerox.com>
X
XTue Jul 17 1990
X*/
X
X/* vaders.c - handle movement, etc. of the vaders. */
X
X#include "vaders.h"
X
X#define NUMTYPES	3	/* How many types of vaders there are. */
X#define NUMROWS		5	/* number of rows of vaders */
X#define NUMVADERS	11	/* Maximum of vaders of each type. */
X#define BASEY 10
X#define VADERWIDTH	14
X#define VADERHEIGHT	12
X#define VADERYINC	8
X
Xstatic XImage *Vader_Image[NUMTYPES][2];	/* XImages for the vaders. */
X
Xextern int basex;		/* Base location */
X
Xstatic int tick = 0;
Xstatic int vaderwaitinit;
X
Xtypedef struct _VaderRec {
X  int x, y;			/* Location. */
X  int vx, vy;			/* Velocity. */
X  int width, height;		/* size of this Vader. */
X  GC gc;			/* graphics context */
X  XImage *shape_image[2];
X  int value;
X  Boolean alive;
X} VaderRec, *Vader;
X
XVaderRec vaders[NUMROWS][NUMVADERS];
X
Xint numvaders = 0;		/* Number of vaders existing. */
X
X
Xtypedef struct _BaseRec {
X  int x;			/* Location. */
X  int v;			/* velocity */
X  int width, height;		/* box of this base. */
X  XImage *shape_image;		/* an XImage for the spaceship */
X} BaseRec, *Base;
X
Xextern Base base;
X
X#define PointInVader(vader, x, y)	\
X  (x >= (vader)->x && y >= (vader)->y &&		\
X   x <= (vader)->x + (vader)->width  && y <= (vader)->y + (vader)->height)
X
X#define VaderNearBox(vader, minx, miny, maxx, maxy)	\
X  ((vader)->x <= minx && maxx <= (vader)->x + (vader)->width && \
X   (vader)->y <= miny && maxy <= (vader)->y + (vader)->height)
X
X
Xstatic void PaintVader(vader, gc)
X     Vader vader;
X     GC gc;
X{
X  int rx, ry, w, h;
X  
X  w = vader->width;
X  h = vader->height;
X
X  rx = vader->x;
X  ry = vader->y;
X  
X  XPutImage(dpy, gamewindow, gc, vader->shape_image[tick],
X	    0, 0, rx, ry, w, h);
X}
X
Xstatic void DestroyVader(vader)
XVader vader;
X{
X  int num, value;
X  int oldx = vader->x;
X  int oldy = vader->y;
X  PaintVader(vader, backgc);
X  score += vader->value;
X  PaintScore();
X  numvaders--;
X  switch (numvaders) {
X  case 32:
X  case 16:
X  case 8:
X  case 4:
X  case 2:
X  case 1:
X    vaderwait /= 2; break;
X  }
X  vader->alive = FALSE;
X}
X
X
X
XBoolean ShotHitsVader(x, y)
X     int x, y;
X{
X  register Vader vader;
X  int i, j;
X
X  for(j = 0; j < NUMROWS; j++)
X    for (i=0 ; i<NUMVADERS ; i++) {
X      vader = &vaders[j][i];
X      if(vader->alive && PointInVader(vader, x, y)) {
X	DestroyVader(vader);
X	return TRUE;
X    }
X  }
X  return FALSE;
X}
X
X
X
Xvoid PaintAllVaders()
X{
X  int i, j;
X  Vader vader;
X
X  for(j = 0; j < NUMROWS; j++)
X    for (i=0 ; i< NUMVADERS ; i++) {
X      vader = &vaders[j][i];
X      if(vader->alive) PaintVader(vader, vader->gc);
X    }
X}
X
X/* add some random shot */
X
Xvoid SFire()
X{
X  register Vader vader;
X  int i, j, c;
X
X  for(j = 0, c = random()%NUMVADERS; j < NUMVADERS; j++) {
X    for (i= NUMROWS-1; i>=0; i--) {
X      vader = &vaders[i][(c+j)%NUMVADERS];
X      if(vader->alive) {
X	AddVshot(vader->x+vader->width/2, vader->y+vader->height);
X	return;
X      }
X    }
X  }
X}
X
Xstatic int createvaderp = FALSE;
X
Xvoid MoveVaders(closure, id)
X     Opaque closure;
X     XtIntervalId id;
X{
X  register Vader vader;
X  register int i, j;
X  int oldx, newx;
X  Boolean reversep;
X
X  reversep = FALSE;
X
X  if (closure != (Opaque) MoveVaders) return;
X  if (createvaderp) {
X    createvaderp = FALSE;
X    CreateVaders(level);
X  }
X  if (numvaders == 0 && numvshots == 0) {
X    vadertimerid = XtAddTimeOut(2000, MoveVaders, (Opaque) MoveVaders);
X    level++;
X    createvaderp = TRUE;
X    InitBuildings();
X    DrawBuildings();
X  } else {
X    vadertimerid = XtAddTimeOut(vaderwait, MoveVaders, (Opaque) MoveVaders);
X    if((random()%1000)>900) SFire();
X    for(j = 0; j < NUMROWS; j++)
X      for (i=0 ; i< NUMVADERS ; i++) {
X	vader = &vaders[j][i];
X	if (vader->alive) {
X	  if (vader->vx > 0)
X	    ShotHitsBuilding(vader->x+vader->width, vader->y+vader->height);
X	  else
X	    ShotHitsBuilding(vader->x, vader->y+vader->height);
X	  PaintVader(vader, backgc);
X	  vader->x += vader->vx;
X	  if ((vader->x < (VADERWIDTH-vader->width)/2 && vader->vx < 0) || 
X	      (vader->x > gamewidth-VADERWIDTH && vader->vx > 0))
X	    reversep = TRUE;
X	  tick = tick ? 0 : 1;
X	  PaintVader(vader, vader->gc);
X	  tick = tick ? 0 : 1;
X	}
X      }
X    tick = tick ? 0 : 1;
X    if (reversep) {
X      for(j = 0; j < NUMROWS; j++)
X	for (i=0 ; i< NUMVADERS ; i++) {
X	  vader = &vaders[j][i];
X	  if (vader->alive) {
X	    PaintVader(vader, backgc);
X	    vader->vx = -vader->vx;
X	    vader->y = vader->y + VADERYINC;
X	    PaintVader(vader, vader->gc);
X	    if(vader->y >= gameheight-base->height+vader->height) {
X	      ResetGame();
X	      return;
X	    }
X	  }
X	}
X    }
X  }
X}
X
X
Xint ReadVaderImages()
X{
X  unsigned int width, height;
X  int x_hot, y_hot;
X  char *data, filename[30];
X  int i, j, status;
X
X  for (i = 0; i < NUMTYPES; i++)
X    for (j = 0; j < 2; j++) {
X      sprintf(filename, "vader%d%s.bit", (i+1), (j ? "b" : "a")); 
X      status = XmuReadBitmapDataFromFile (filename,
X					  &width, &height, &data,
X					  &x_hot, &y_hot);
X
X      if (status != BitmapSuccess) return status;
X
X      Vader_Image[i][j] = XCreateImage(dpy,
X				       DefaultVisual(dpy, DefaultScreen(dpy)),
X				       1,
X				       XYBitmap,
X				       0,
X				       data,
X				       width, height,
X				       8, 0);
X      Vader_Image[i][j]->bitmap_bit_order = LSBFirst;
X      Vader_Image[i][j]->byte_order = LSBFirst;
X    }
X
X  return BitmapSuccess;
X}
X
X
Xvoid CreateVaders(level)
Xint level;
X{
X  int offset, i, j;
X  Vader vader;
X
X  offset = MIN(level, 8);
X  vaderwait = vaderwaitinit;
X  numvaders = NUMROWS*NUMVADERS;
X  for (j = 0; j < NUMROWS; j++)
X    for (i = 0; i < NUMVADERS; i++) {
X      vader = &vaders[j][i];
X      vader->x = 3 + VADERWIDTH*i+(VADERWIDTH-vader->width)/2;
X      vader->y = VADERHEIGHT*(offset+j);
X      vader->vx = 1;
X      vader->alive = TRUE;
X    }
X}
X
Xvoid InitVaders()
X{
X  int i, j, k, width, height;
X  Vader vader;
X
X  level = 1;
X  if (ReadVaderImages() != BitmapSuccess) {
X    fprintf(stderr, "Error reading Invader images\n");
X    exit(10);
X  }
X
X  for (j = 0; j < NUMROWS; j++) {
X    switch (j) {
X    case 0:
X      k = 0; break;
X    case 1:
X    case 2:
X      k = 1; break;
X    case 3:
X    case 4:
X      k = 2; break;
X    }
X    width = Vader_Image[k][0]->width;
X    height = Vader_Image[k][0]->height;
X    for (i = 0; i < NUMVADERS; i++) {
X      vader = &vaders[j][i];
X      vader->shape_image[0] = Vader_Image[k][0];
X      vader->shape_image[1] = Vader_Image[k][1];
X      vader->gc = vadergc[k];
X      vader->width = width;
X      vader->height = height;
X      vader->value = 10*(3-k);
X    }
X  }
X  vaderwaitinit = vaderwait;
X  CreateVaders(level);
X  vadertimerid = NULL;
X}
END_OF_FILE
if test 6812 -ne `wc -c <'vaders.c'`; then
    echo shar: \"'vaders.c'\" unpacked with wrong size!
fi
# end of 'vaders.c'
fi
if test -f 'shot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'shot.c'\"
else
echo shar: Extracting \"'shot.c'\" \(4984 characters\)
sed "s/^X//" >'shot.c' <<'END_OF_FILE'
X/* 
XCopyright notice:
X
XThis is mine.  I'm only letting you use it.  Period.  Feel free to rip off
Xany of the code you see fit, but have the courtesy to give me credit.
XOtherwise great hairy beasties will rip your eyes out and eat your flesh
Xwhen you least expect it.
X
XJonny Goldman <jgoldman@parc.xerox.com>
X
XTue Jul 17 1990
X*/
X
X/* shot.c - handle movement, etc. of the shots. */
X
X#include "vaders.h"
X
Xextern int paused;
X
X#define MAXSHOTS	1
X#define MAXVSHOTS	6
X#define SHOTSIZE	8
X
Xtypedef struct _ShotRec {
X    int x, y;		/* Location of this shot. */
X} ShotRec, *Shot;
X
XShotRec shots[MAXSHOTS], vshots[MAXVSHOTS];
X
XXImage *vshot_image[2];
X
Xstatic int tick = 0;
X
Xint numshots;		/* Number of shots currently flying. */
Xint numvshots;		/* Number of shots currently flying. */
X
Xstatic void PaintShot(shot, gc)
XShot shot;
XGC gc;
X{
X    AddLine(shot->x, shot->y,
X	    shot->x, shot->y + SHOTSIZE, gc);
X}
X
Xstatic void PaintVshot(vshot, gc)
XShot vshot;
XGC gc;
X{
X  XPutImage(dpy, gamewindow, gc, vshot_image[tick],
X	    0, 0, vshot->x, vshot->y, vshot_image[tick]->width, vshot_image[tick]->height);
X}
X
X
Xvoid PaintAllShots()
X{
X    int i;
X    for (i=0 ; i<numshots ; i++)
X	PaintShot(shots + i, shotgc);
X    for (i=0 ; i<numvshots ; i++)
X	PaintVshot(vshots + i, vshotgc);
X}
X
X
Xstatic void DestroyShot(i)
Xint i;
X{
X    PaintShot(shots + i, backgc);
X    numshots--;
X    shots[i] = shots[numshots];
X}
X
X
Xstatic void DestroyVshot(i)
Xint i;
X{
X    PaintVshot(vshots + i, backgc);
X    numvshots--;
X    vshots[i] = vshots[numvshots];
X}
X
X
Xvoid MoveShots(closure, id)
XOpaque closure;
XXtIntervalId id;
X{
X  int i, x, y, newx, newy;
X  Shot shot;
X  if (closure != (Opaque) MoveShots) return;
X  if (!paused) {
X    if (numshots > 0)
X      shottimerid = XtAddTimeOut(shotwait, MoveShots, (Opaque) MoveShots);
X    else
X      shottimerid = NULL;
X    for (i=0 ; i<numshots ; i++) {
X      shot = shots + i;
X      newy = shot->y - SHOTSIZE/2;
X      x = shot->x;
X      y = shot->y;
X      if (ShotHitsVader(x, y)
X	  || ShotHitsSpacer(x, y)
X	  || ShotHitsBuilding(x, y)
X	  || y < 0) {
X	DestroyShot(i);
X	i--;			/* Ensures we don't skip moving a shot. */
X      } else {
X	PaintShot(shot, backgc);
X	shot->y = newy;
X	PaintShot(shot, shotgc);
X      }
X    }
X  }
X}
X
XBoolean VshotHitsShot(x, y)
Xint x, y;
X{
X  int i, dx, dy;
X  Shot shot;
X
X  for (i=0; i<numshots; i++) {
X    shot = shots + i;
X    dx = shot->x;
X    dy = shot->y;
X    if(dx >= x && dx < x+vshot_image[tick]->width
X       && dy >= y && dy < y+vshot_image[tick]->height) {
X      DestroyShot(i);
X      return TRUE;
X    }
X  }
X  return FALSE;
X}
X       
X
Xvoid MoveVshots(closure, id)
XOpaque closure;

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.