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

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

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

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/* spacers.c - handle movement, etc. of the little space ships. */
X
X#include "vaders.h"
X
XBoolean spacer_shown;
X
X#define SPACERY 0
X#define SPACERV 2
X
Xtypedef struct _SpacerRec {
X  int x;			/* Location. */
X  int width, height;		/* box of this rock. */
X  int score;			/* value of this guy */
X  XImage *shape_image;		/* an XImage for the spaceship */
X} SpacerRec, *Spacer;
X
XSpacerRec spacerrec;
X
XSpacer spacer = &spacerrec;
X
X#define SpacerNearPoint(spacer, x, y)	\
X  ((spacer)->x <= (x) && (x) < (spacer)->x + (spacer)->width  && \
X   y <= SPACERY + (spacer)->height && y > SPACERY)
X
Xint spacer_counter;		/* number of steps to wait for new spacer */
X
Xint showing_sexplosion = FALSE;
X
X/* now the code */
X
Xvoid PaintSpacer(gc)
X     GC gc;
X{
X    XPutImage(dpy, gamewindow, gc, spacer->shape_image,
X	      0, 0, spacer->x, SPACERY, spacer->width, spacer->height);
X}
X
X
Xvoid ShowSexplosion(gc)
XGC gc;
X{
X  char score[5];
X
X  sprintf(score,"%3d", spacer->score);
X  XDrawString(dpy, gamewindow, gc, spacer->x, SPACERY+spacer->height, score, 3);
X
X}
X
X/*
X * Destroy the Spacer, much like the ship.
X */
X
Xstatic void DestroySpacer()
X{
X  XImage ximage;
X  int num, value, ex, ey;
X  score += spacer->score;
X  PaintScore();
X
X  if(!paused) {
X    PaintSpacer(backgc);
X    ShowSexplosion(spacergc);
X    if (spacertimerid)
X      XtRemoveTimeOut(spacertimerid);
X    XtAddTimeOut(1000, MoveSpacer, (Opaque) MoveSpacer);
X    showing_sexplosion = TRUE;
X    spacer_shown = FALSE;
X  }
X}
X
XBoolean ShotHitsSpacer(x, y)
X     int x, y;
X{
X  if(spacer_shown) {
X    if (SpacerNearPoint(spacer, x, y)) {
X      DestroySpacer();
X      return TRUE;
X    }
X  }
X  return FALSE;
X}
X
X
X
Xvoid MakeSpacer()
X{
X  spacer_shown = TRUE;
X
X  spacer->x=0;
X  spacer->score = 50*(random()%6+1);
X  PaintSpacer(spacergc);
X}
X  
Xvoid MoveSpacer(closure, id)
X     Opaque closure;
X     XtIntervalId id;
X{
X  register int i;
X  int minx, miny, maxx, maxy, spy;
X  if (closure != (Opaque) MoveSpacer) return;
X  spacertimerid = XtAddTimeOut(spacerwait, MoveSpacer, (Opaque) MoveSpacer);
X  if (!paused) {
X    if (showing_sexplosion) {
X      showing_sexplosion = FALSE;
X      ShowSexplosion(backgc);
X      spacer_shown = FALSE;
X      spacer_counter = 1000;
X      return;
X    }
X    if (spacer_shown) {
X      PaintSpacer(backgc);
X      spacer->x += SPACERV;
X      if (spacer->x < gamewidth-spacer->width) {
X	PaintSpacer(spacergc);
X      } else {
X	spacer_shown = FALSE;
X	spacer_counter = 1000;
X      }
X    } else
X      if (spacer_counter-- == 0) MakeSpacer();
X  }
X}
X
X
Xint ReadSpacerImages()
X{
X  unsigned int width, height;
X  int x_hot, y_hot;
X  unsigned char *data;
X  int status;
X
X  status = XmuReadBitmapDataFromFile ("spacer.bit",
X				      &width, &height, &data,
X				      &x_hot, &y_hot);
X  if (status != BitmapSuccess) return status;
X
X  spacer->width = width;
X  spacer->height = height;
X  spacer->shape_image = XCreateImage(dpy,
X				     DefaultVisual(dpy, DefaultScreen(dpy)),
X				     1,
X				     XYBitmap,
X				     0,
X				     data,
X				     spacer->width, spacer->height,
X				     8, 0);
X
X  spacer->shape_image->bitmap_bit_order = LSBFirst;
X  spacer->shape_image->byte_order = LSBFirst;
X
X  return BitmapSuccess;
X}
X
Xvoid InitSpacers()
X{
X  ReadSpacerImages();
X  spacertimerid = NULL;
X}
END_OF_FILE
if test 3543 -ne `wc -c <'spacers.c'`; then
    echo shar: \"'spacers.c'\" unpacked with wrong size!
fi
# end of 'spacers.c'
fi
if test -f 'base.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'base.c'\"
else
echo shar: Extracting \"'base.c'\" \(6969 characters\)
sed "s/^X//" >'base.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/* base.c - handle movement, etc. of the base. */
X
X#include "vaders.h"
X
Xextern int paused;
XBoolean basedestroyed;
X
Xstatic int ex, ey;		/* Where we're painting an explosion. */
Xstatic Boolean showingexplosion = FALSE;
X
Xvoid DrawBuildings();
X
X#define BASEY (gameheight-base->height)
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
XBaseRec baserec;
X
XBase base = &baserec;
X
XXImage *explosion;
X
X#define BaseNearPoint(base, x, y)	\
X  ((base)->x <= (x) && (x) < (base)->x + (base)->width  && \
X   y <= BASEY + (base)->height && y > BASEY)
X
Xint ReadBaseImage()
X{
X  unsigned int width, height;
X  int x_hot, y_hot;
X  char *data;
X  int i, status;
X
X  status = XmuReadBitmapDataFromFile ("base.bit",
X				      &width, &height, &data,
X				      &x_hot, &y_hot);
X
X  if (status != BitmapSuccess) return status;
X
X  base->shape_image = XCreateImage(dpy,
X				   DefaultVisual(dpy, DefaultScreen(dpy)),
X				   1,
X				   XYBitmap,
X				   0,
X				   data,
X				   width, height,
X				   8, 0);
X  
X  base->width = width;
X  base->height = height;
X  base->shape_image->bitmap_bit_order = LSBFirst;
X  base->shape_image->byte_order = LSBFirst;
X
X  status = XmuReadBitmapDataFromFile ("explode.bit",
X				      &width, &height, &data,
X				      &x_hot, &y_hot);
X
X  if (status != BitmapSuccess) return status;
X
X  explosion = XCreateImage(dpy,
X			   DefaultVisual(dpy, DefaultScreen(dpy)),
X			   1,
X			   XYBitmap,
X			   0,
X			   data,
X			   width, height,
X			   8, 0);
X  explosion->bitmap_bit_order = LSBFirst;
X  explosion->byte_order = LSBFirst;
X  
X  return BitmapSuccess;
X}
X
Xvoid InitBase()
X{
X    if( ReadBaseImage() != BitmapSuccess) {
X      fprintf(stderr, "Error reading base image.\n");
X      exit(20);
X    }
X    basedestroyed = TRUE;
X    showingexplosion = FALSE;
X    basetimerid = NULL;
X    base->v = 0;
X}
X
X
X
Xvoid PaintBase(gc)
XGC gc;
X{
X  XPutImage(dpy, gamewindow, gc, base->shape_image,
X	    0, 0, base->x, gameheight-base->height, base->width, base->height);
X}
X
X
XShowBase(i, gc)
Xint i;
XGC gc;
X{
X  XPutImage(dpy, gamewindow, gc, base->shape_image,
X	    0, 0, gamewidth+i*(base->width+2), 70,
X	    base->width, base->height);
X}
X
XPaintBasesLeft()
X{
X  int i;
X  XDrawString(dpy, gamewindow, scoregc, gamewidth, 55, "Bases", 5);
X  for(i = 0; i < basesleft; i++) {
X    ShowBase(i, basegc);
X  }
X}
X
X
Xvoid ShowExplosion(gc)
XGC gc;
X{
X  XPutImage(dpy, gamewindow, gc, explosion,
X	      0, 0, base->x, gameheight-base->height, explosion->width, explosion->height);
X}
X
Xvoid DestroyBase()
X{
X  if(!paused) {
X    PaintBase(backgc);
X    basedestroyed = TRUE;
X    showingexplosion = TRUE;
X    ShowExplosion(basegc);
X    if (basetimerid) XtRemoveTimeOut(basetimerid);
X    basetimerid = XtAddTimeOut(1000, MoveBase, (Opaque) MoveBase);
X  }
X}
X
X
XBoolean ShotHitsBase(x,y)
Xint x,y;
X{
X  if(!basedestroyed && BaseNearPoint(base, x, y)) {
X    DestroyBase();
X    return TRUE;
X  }
X  return FALSE;
X}
X
XResetGame()
X{
X  spacer_shown = 0;
X  SuspendTimers();
X  XClearWindow(dpy, gamewindow);
X  paused = 1;
X  InitScore();
X  basesleft--;
X  level = 1;
X  CreateVaders(level);
X  spacer_counter = 1000;
X  numshots = 0;
X  numvshots = 0;
X  PaintAllVaders();
X  PaintBasesLeft();
X  InitBuildings();
X  DrawBuildings();
X  lastscore = 0;
X  PaintScore();
X  XSync(dpy, 0);
X  basedestroyed = FALSE;
X  base->x = base->v = 0;
X  showingexplosion = FALSE;
X  PaintBase(basegc);
X}
X
Xvoid MoveBase(closure, id)
XOpaque closure;
XXtIntervalId id;
X{
X  int i, j, newx, newy;
X  if (closure != (Opaque) MoveBase) return;
X  if(!paused) {
X    if (basedestroyed) {
X      if (showingexplosion) {
X	ShowExplosion(backgc);
X	showingexplosion = FALSE;
X	basetimerid = XtAddTimeOut(2000, MoveBase, (Opaque) MoveBase);
X	return;
X      }
X      if (basesleft <= 0) {
X	ResetGame();
X	return;
X      }
X      base->x = 0;
X      basesleft--;
X      ShowBase(basesleft, backgc);
X      PaintBase(basegc);
X      PaintScore();
X      basedestroyed = FALSE;
X      base->v = 0;
X    }
X
X    if (!paused)
X      basetimerid = XtAddTimeOut(basewait, MoveBase, (Opaque) MoveBase);
X    if(base->v) {
X      PaintBase(backgc);
X      base->x += base->v;
X      base->x = (base->x < 0) ? 0 :
X      ((base->x > gamewidth-base->width) ? gamewidth-base->width : base->x);
X      PaintBase(basegc);
X    }
X  }
X}
X
Xvoid MoveLeft()
X{
X  if(!paused) base->v= -1;
X}
X
X
Xvoid MoveRight()
X{
X  if(!paused) base->v = 1;
X}
X
X
Xvoid Stop()
X{
X  if(!paused)
X    base->v = 0;
X}
X
X
Xvoid Fire()
X{
X    if (!basedestroyed&&!paused) AddShot(base->x+base->width/2, gameheight-base->height);
X}
X
X/* this part is for the buildings */
X
X#define NUMBUILDINGS 4
X#define HUNKROWS 4
X#define NUMHUNKS 10
X#define HUNKWIDTH 2
X#define HUNKHEIGHT 4
X#define buildingwidth HUNKWIDTH*NUMHUNKS
X#define buildingheight HUNKHEIGHT*HUNKROWS
X
Xtypedef struct {
X  int x,y;
X  Boolean hunks[HUNKROWS][NUMHUNKS];
X} BuildingRec, *Building;
X
XBuildingRec buildings[NUMBUILDINGS];
X
X
Xvoid DrawBuildingHunk(building, r, c, gc)
XBuilding building;
Xint r,c;
XGC gc;
X{
X  int x, y, w, h;
X
X  x = building->x+c*HUNKWIDTH;
X  y = gameheight-45+r*HUNKHEIGHT;
X
X  XFillRectangle(dpy, gamewindow, gc, x, y, HUNKWIDTH, HUNKHEIGHT);
X}
X
Xvoid ToastHunk(building,r,c)
XBuilding building;
Xint r,c;
X{
X  building->hunks[r][c] = FALSE;
X  DrawBuildingHunk(building, r, c, backgc);
X}
X
XBoolean ShotHitsBuilding(x, y)
Xint x,y;
X{
X  int i, r, c;
X  Building building;
X
X  for(i=0; i< NUMBUILDINGS; i++) {
X    building = &buildings[i];
X    if(x>=building->x && x<building->x+buildingwidth &&
X       y>=gameheight-45 && y<gameheight-45+buildingheight) {
X      r = (y-(gameheight-45))/HUNKHEIGHT;
X      c = (x-building->x)/HUNKWIDTH;
X      if (r<0 || r>=HUNKROWS)
X	printf("Error in row");
X      if (c<0 || c>=NUMHUNKS)
X	printf("Error in column");
X      if(building->hunks[r][c]) {
X	ToastHunk(building, r,c);
X	return TRUE;
X      }
X      return FALSE;
X    }
X  }
X  return FALSE;
X}
X
XInitBuildings()
X{
X  int i, j, k;

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