⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sprite.c

📁 数据挖掘中de一个算法 hamster的实例
💻 C
字号:
/*----------------------------------------------------------------------  File    : sprite.c  Contents: sprite management, single color (X11 version)  Author  : Christian Borgelt  History : 30.10.1997 file created            31.10.1997 first version completed            01.11.1997 event processing in function spr_move added            02.11.1997 NOFLICKER version hardcoded            04.11.1997 move function changed to timeout procedure            06.11.1997 callback function added to function spr_move            16.06.1998 switching to new sprite image improved----------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <time.h>#include "sprite.h"#include <X11/Xutil.h>/*----------------------------------------------------------------------  Auxiliary Functions----------------------------------------------------------------------*/static void move (XtPointer data, XtIntervalId *iid){                               /* --- move sprite one step */  SPRITE *spr = data;           /* sprite to be moved */  if (spr->cnt <= 0) return;    /* if stopped, abort function */  XSetClipOrigin(spr->display, spr->gc,       /* duplicate */    spr->xext -spr->xoff, -spr->yoff);        /* background */  XCopyArea(spr->display, spr->buffer, spr->buffer, spr->gc,    0, 0, spr->xext, spr->yext, spr->xext, 0);  spr->xnew += spr->di *spr->xext; /* get offset for new image */  XSetClipOrigin(spr->display, spr->gc,       /* draw new image */    spr->dx -spr->xnew, spr->dy -spr->ynew);  /* into buffer */  XFillRectangle(spr->display, spr->buffer, spr->gc,    spr->dx, spr->dy, spr->xext, spr->yext);  XSetClipOrigin(spr->display, spr->gc,       /* undraw sprite */    spr->xpos -spr->xoff, spr->ypos -spr->yoff);  XCopyArea(spr->display, spr->buffer, spr->window, spr->gc,    0, 0, spr->xext, spr->yext, spr->xpos, spr->ypos);  spr->xpos += spr->dx;         /* move sprite to */  spr->ypos += spr->dy;         /* new position */  XSetClipOrigin(spr->display, spr->gc,       /* copy background */    -spr->xnew, -spr->ynew);                  /* into buffer */  XCopyArea(spr->display, spr->window, spr->buffer, spr->gc,    spr->xpos, spr->ypos, spr->xext, spr->yext, 0, 0);  XSetClipOrigin(spr->display, spr->gc,       /* complete background */    -spr->dx -spr->xoff, -spr->dy -spr->yoff);/* from duplicate */  XCopyArea(spr->display, spr->buffer, spr->buffer, spr->gc,    spr->xext, 0, spr->xext, spr->yext, -spr->dx, -spr->dy);  /* It is necessary to complete the background with the */  /* background data from the duplicate in the second buffer, */  /* since we drew the new sprite image into the background */  /* buffer and copied this modified background to the screen. */  /* Hence, if the new and the old sprite image overlap, */  /* we cannot get the complete background from the screen, */  /* but only the part that is not obscured by the overlap. */  /* The obscured part we get from the buffered duplicate. */  XSetClipOrigin(spr->display, spr->gc,  /* draw sprite */    spr->xpos -spr->xnew, spr->ypos -spr->ynew);  XFillRectangle(spr->display, spr->window, spr->gc,    spr->xpos, spr->ypos, spr->xext, spr->yext);  XFlush(spr->display);         /* flush buffered drawing commands */  spr->xoff = spr->xnew;        /* transfer offsets for new image */  spr->yoff = spr->ynew;        /* to offsets for current image */  if (--spr->cnt > 0)           /* if not done, reregister function */    spr->iid = XtAppAddTimeOut(spr->appctx, spr->delay, move, spr);  else if (spr->cback)          /* otherwise call callback function */    spr->cback(spr->widget, spr->data, (XtPointer)spr);}  /* move() *//*----------------------------------------------------------------------  Main Functions----------------------------------------------------------------------*/SPRITE* spr_create (Widget widget, int xext, int yext,                    Pixmap bitmap, unsigned long color){                               /* --- create a sprite */  SPRITE *spr;                  /* created sprite */  int    depth;                 /* color depth of display */  spr = (SPRITE*)malloc(sizeof(SPRITE));  if (!spr) return NULL;        /* allocate sprite body */  spr->xext    = xext;          /* and initialize fields */  spr->yext    = yext;          /* note sprite extensions */  spr->xoff    = spr->yoff = 0; /* select first image of first series */  spr->xnew    = spr->ynew = 0; /* for the current and the new image */  spr->xpos    = spr->ypos = 0; /* initialize position */  spr->drawn   = spr->cnt  = 0; /* sprite is not drawn and not moving */  spr->appctx  = XtWidgetToApplicationContext(widget);  spr->widget  = widget;        /* note app. context and widget */  spr->display = XtDisplay(widget);  /* get display and */  spr->window  = XtWindow(widget);   /* window of widget */  /* --- create window graphic context --- */  spr->gc = XCreateGC(spr->display, spr->window, 0, NULL);  if (!spr->gc) { free(spr); return NULL; }  XSetForeground(spr->display, spr->gc, color);   /* set color */  XSetClipMask  (spr->display, spr->gc, bitmap);  /* and bitmap */  /* --- create background buffer --- */  depth = XDefaultDepth(spr->display, XDefaultScreen(spr->display));  spr->buffer = XCreatePixmap(spr->display, spr->window,                              2 *xext, yext, depth);  if (spr->buffer == None) { spr_delete(spr); return NULL; }  /* The reason why the background buffer is allocated with */  /* double sprite width can be seen in the function spr_move. */  return spr;                   /* return created sprite */}  /* spr_create() *//*--------------------------------------------------------------------*/void spr_delete (SPRITE *spr){                               /* --- delete a sprite */  if (spr->drawn)          spr_undraw(spr);  if (spr->buffer != None) XFreePixmap(spr->display, spr->buffer);  if (spr->gc)             XFreeGC(spr->display, spr->gc);  free(spr);                    /* delete buffer, gcs and sprite body */}  /* spr_delete() *//*--------------------------------------------------------------------*/void spr_select (SPRITE *spr, int series, int index){                               /* --- select a sprite image */  spr->xnew = (index  > 0) ? index  *spr->xext : 0;  spr->ynew = (series > 0) ? series *spr->yext : 0;}  /* spr_select() *//*--------------------------------------------------------------------*/int spr_draw (SPRITE *spr, int x, int y){                               /* --- draw a sprite */  if (spr->drawn) {             /* if sprite is drawn */    if (((x == INT_MIN) || (x == spr->xpos))    &&  ((y == INT_MIN) || (y == spr->ypos))    &&  (spr->xoff == spr->xnew)    &&  (spr->yoff == spr->ynew))      return 0;                 /* if sprite is already drawn at the */    spr_undraw(spr);            /* correct position, abort function, */    spr->xoff = spr->xnew;      /* otherwise undraw sprite */    spr->yoff = spr->ynew;      /* and get the offsets for */  }                             /* the new sprite image */  if (x > INT_MIN) spr->xpos = x;  /* if new coordinates given, */  if (y > INT_MIN) spr->ypos = y;  /* use coordinates */  XSetClipOrigin(spr->display, spr->gc,    -spr->xoff, -spr->yoff);    /* save background in buffer */  XCopyArea(spr->display, spr->window, spr->buffer, spr->gc,    spr->xpos, spr->ypos, spr->xext, spr->yext, 0, 0);  XSetClipOrigin(spr->display, spr->gc,    spr->xpos -spr->xoff, spr->ypos -spr->yoff);  XFillRectangle(spr->display, spr->window, spr->gc,    spr->xpos, spr->ypos, spr->xext, spr->yext);  XFlush(spr->display);         /* draw sprite */  spr->drawn = 1;               /* note that sprite is drawn */  return 0;                     /* return 'ok' */}  /* spr_draw() *//*--------------------------------------------------------------------*/int spr_undraw (SPRITE *spr){                               /* --- undraw a sprite */  if (!spr->drawn) return -1;   /* if sprite is not drawn, abort */  XCopyArea(spr->display, spr->buffer, spr->window, spr->gc,    0, 0, spr->xext, spr->yext, spr->xpos, spr->ypos);  XFlush(spr->display);         /* copy background back to window */  spr->drawn = 0;               /* note that sprite is not drawn */  return 0;                     /* return 'ok' */}  /* spr_undraw() *//*--------------------------------------------------------------------*/int spr_move (SPRITE *spr, int dx, int dy, int di, int cnt, float delay,              XtCallbackProc callback, XtPointer data){                               /* --- animate a sprite */  if (spr->cnt > 0) return -1;  /* if sprite is (still) moving, abort */  if (!spr->drawn)              /* if sprite is not drawn, */    spr_draw(spr, INT_MIN, INT_MIN);            /* draw it */  if (cnt <= 0) return 0;       /* if not to move, abort function */  spr->dx    = dx; spr->dy = dy; spr->di = di;  spr->cnt   = cnt;             /* note parameters */  spr->delay = (unsigned int)(delay *1000);  spr->cback = callback;        /* note callback function */  spr->data  = data;            /* and client data */  spr->iid   = XtAppAddTimeOut(spr->appctx, spr->delay, move, spr);  return 0;                     /* register function and return 'ok' */}  /* spr_move() *//*--------------------------------------------------------------------*/void spr_stop (SPRITE *spr){                               /* --- stop moving sprite */  if (spr->cnt <= 0) return;    /* if sprite is not moving, abort */  XtRemoveTimeOut(spr->iid);    /* remove timer procedure */  spr->cnt = 0;                 /* and clear number of steps */}  /* spr_stop() */

⌨️ 快捷键说明

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