📄 sprite.c
字号:
/*---------------------------------------------------------------------- File : sprite.c Contents: sprite management (Microsoft Windows Version) Author : Christian Borgelt History : 15.10.1997 file created 16.10.1997 first version completed 31.10.1997 device context stored in SPRITE structure 16.06.1998 switching to new sprite image improved----------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <time.h>#include "sprite.h"/*---------------------------------------------------------------------- Functions----------------------------------------------------------------------*/SPRITE* spr_create (HWND hwnd, int xext, int yext, HBITMAP bitmap, HBITMAP mask){ /* --- create a sprite */ SPRITE *spr; /* created sprite */ 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 = 0; /* sprite is not drawn */ spr->hwnd = hwnd; /* note window handle */ spr->hdc_win = GetDC(hwnd); /* get device context for window */ if (!spr->hdc_win) { free(spr); return NULL; } spr->hdc_bmp = CreateCompatibleDC(spr->hdc_win); spr->hdc_msk = CreateCompatibleDC(spr->hdc_win); spr->hdc_buf = CreateCompatibleDC(spr->hdc_win); spr->buffer = CreateCompatibleBitmap(spr->hdc_win, xext, yext); spr->bitmap = bitmap; /* create device contexts and buffer */ spr->mask = mask; /* note sprite bitmap and mask bitmap */ if (!spr->hdc_bmp || !spr->hdc_msk || !spr->hdc_buf || !spr->buffer) { spr_delete(spr, 0); return NULL; } SelectObject(spr->hdc_bmp, bitmap); SelectObject(spr->hdc_msk, mask); SelectObject(spr->hdc_buf, spr->buffer); return spr; /* return created sprite */} /* spr_create() *//*--------------------------------------------------------------------*/void spr_delete (SPRITE *spr, int del){ /* --- delete a sprite */ if (spr->hdc_buf) DeleteDC(spr->hdc_buf); if (spr->buffer) DeleteObject(spr->buffer); if (spr->hdc_msk) DeleteDC(spr->hdc_msk); if (spr->mask && (del & 1)) DeleteObject(spr->mask); if (spr->hdc_bmp) DeleteDC(spr->hdc_bmp); if (spr->bitmap && (del & 2)) DeleteObject(spr->bitmap); if (spr->hdc_win) ReleaseDC(spr->hwnd, spr->hdc_win); free(spr); /* delete objects 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 currently 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; /* note coordinates */ BitBlt(spr->hdc_buf, 0, 0, spr->xext, spr->yext, spr->hdc_win, spr->xpos, spr->ypos, SRCCOPY); BitBlt(spr->hdc_win, spr->xpos, spr->ypos, spr->xext, spr->yext, spr->hdc_msk, spr->xoff, spr->yoff, SRCAND); BitBlt(spr->hdc_win, spr->xpos, spr->ypos, spr->xext, spr->yext, spr->hdc_bmp, spr->xoff, spr->yoff, SRCPAINT); spr->drawn = 1; /* copy background, draw sprite, */ 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 */ BitBlt(spr->hdc_win, spr->xpos, spr->ypos, spr->xext, spr->yext, spr->hdc_buf, 0, 0, SRCCOPY); spr->drawn = 0; /* copy background to device */ return 0; /* return 'ok' */} /* spr_undraw() *//*--------------------------------------------------------------------*/int spr_move (SPRITE *spr, int dx, int dy, int di, int cnt, float delay){ /* --- animate a sprite */ int t, dt; /* time buffer for delay loop */ if (!spr->drawn) /* if sprite is not drawn, */ spr_draw(spr, INT_MIN, INT_MIN); /* draw it */ t = clock(); /* get time and compute increment */ dt = (delay <= 1/100.0) ? 0 : (int)(delay *CLOCKS_PER_SEC); while (--cnt >= 0) { /* animation loop */ t += dt; /* compute next end time */ while (clock() < t); /* delay loop */ BitBlt(spr->hdc_win, spr->xpos, spr->ypos, spr->xext, spr->yext, spr->hdc_buf, 0, 0, SRCCOPY); spr->xpos += dx; /* undraw sprite and */ spr->ypos += dy; /* move to new position */ spr->xoff = spr->xnew += di *spr->xext; spr->yoff = spr->ynew; /* move to new image */ BitBlt(spr->hdc_buf, 0, 0, spr->xext, spr->yext, spr->hdc_win, spr->xpos, spr->ypos, SRCCOPY); BitBlt(spr->hdc_win, spr->xpos, spr->ypos, spr->xext, spr->yext, spr->hdc_msk, spr->xoff, spr->yoff, SRCAND); BitBlt(spr->hdc_win, spr->xpos, spr->ypos, spr->xext, spr->yext, spr->hdc_bmp, spr->xoff, spr->yoff, SRCPAINT); } /* draw sprite at new position */ return 0; /* return 'ok' */} /* spr_move() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -