这是一个移动的精灵,用到了SDL2 的图片分割、键盘事件。
// spirit.c// SDL2 移动的精灵//#define _DEBUG_#include#include // 图片文件// 文件名char *ImageFileName[] ={ "res/Town.jpg", // 背景图文件 "res/Fighter.png", // Player文件 "res/chick.png" // NPC文件};// 图形属性:x = 横向分几幅,y = 纵向分几幅,w = 宽度,h = 高度SDL_Rect ImageInfo[] ={ {1, 2, 640, 640}, {4, 4, 128, 192}, {4, 4, 128, 192}};// 图片的背景色int BackColor = 0xFFFFFF;// 字符串常量char szWindowTitle[] = "SDL2 移动的精灵";SDL_Texture *GetImageTexture(SDL_Renderer *pRenderer, char *FileName, _Bool bTransparent, int color);void UpdateWindow(SDL_Window *pWindow, SDL_Renderer *pRenderer, SDL_Texture **pImageTexture, int bx, int by, int px, int py, int nx, int ny, SDL_Rect *pd, SDL_Rect *nd);#undef mainint main(int argc, char **argv){ int nWindowWidth = 640; // 屏幕尺寸 int nWindowHeight = 320; SDL_Window *pWindow; // 主窗口 SDL_Renderer *pRenderer; // 主窗口渲染器 SDL_Texture *pImageTexture[3]; // 棋盘背景、黑白棋子图纹理 SDL_Event event; // 事件 _Bool bRun = 1; // 持续等待事件控制循环标识 // 背景、人物、NPC 的图幅坐标 int bx = 0, by = 0, px = 0, py = 0, nx = 0, ny = 0; // 人物、NPC 的目标位置及大小 SDL_Rect pr = {300, 300, 32, 48}, nr = {380, 230, 16, 24}; // 移动速度 int speed = 10; // 初始化:SDL2、SDL_Image(jpg) if(SDL_Init(SDL_INIT_VIDEO) == -1 || IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG) == -1) {#ifdef _DEBUG_ fprintf(stderr, "1 %s", SDL_GetError());#endif return 1; } // 创建主窗口及其渲染器 if(SDL_CreateWindowAndRenderer(640, 480, SDL_WINDOW_SHOWN, &pWindow, &pRenderer) == -1) {#ifdef _DEBUG_ fprintf(stderr, "2 %s", SDL_GetError());#endif goto label_error; } SDL_SetWindowTitle(pWindow, szWindowTitle); // 加载图片文件 if(NULL == (pImageTexture[0] = GetImageTexture(pRenderer, ImageFileName[0], 0, 0)) || NULL == (pImageTexture[1] = GetImageTexture(pRenderer, ImageFileName[1], 1, BackColor)) || NULL == (pImageTexture[2] = GetImageTexture(pRenderer, ImageFileName[2], 1, BackColor))) {#ifdef _DEBUG_ fprintf(stderr, "3 %s", IMG_GetError());#endif goto label_error; } // 等待事件 while(bRun && SDL_WaitEvent(&event)) { switch(event.type) { case SDL_KEYDOWN : // 键盘按键消息 switch(event.key.keysym.sym) { case SDLK_RIGHT : py = 2; px++; pr.x = SDL_min(pr.x+speed, nWindowWidth-pr.w); break; case SDLK_LEFT : py = 1; px++; pr.x = SDL_max(pr.x-speed, 0); break; case SDLK_DOWN : py = 0; px++; pr.y = SDL_min(pr.y+speed, nWindowHeight-pr.h); break; case SDLK_UP : py = 3; px++; pr.y = SDL_max(pr.y-speed, 0); break; default : break; } px %= 4; UpdateWindow(pWindow, pRenderer, pImageTexture, bx, by, px, py, nx, ny, &pr, &nr); break; case SDL_WINDOWEVENT : // 有窗口消息,重新计算窗口尺寸 SDL_GetWindowSize(pWindow, &nWindowWidth, &nWindowHeight); UpdateWindow(pWindow, pRenderer, pImageTexture, bx, by, px, py, nx, ny, &pr, &nr); break; case SDL_QUIT : bRun = 0; break; default : break; } }label_error:// 清理 if(pImageTexture[0] != NULL) SDL_DestroyTexture(pImageTexture[0]); if(pImageTexture[1] != NULL) SDL_DestroyTexture(pImageTexture[1]); if(pImageTexture[2] != NULL) SDL_DestroyTexture(pImageTexture[2]); IMG_Quit(); SDL_Quit(); return 0;}// 重绘窗口void UpdateWindow(SDL_Window *pWindow, SDL_Renderer *pRenderer, SDL_Texture **pImageTexture, int bx, int by, int px, int py, int nx, int ny, SDL_Rect *pr, SDL_Rect *nr){ SDL_Rect srt; SDL_RenderClear(pRenderer); srt.x = bx*ImageInfo[0].w/ImageInfo[0].x; srt.y = by*ImageInfo[0].h/ImageInfo[0].y; srt.w = ImageInfo[0].w/ImageInfo[0].x; srt.h = ImageInfo[0].h/ImageInfo[0].y; SDL_RenderCopy(pRenderer, pImageTexture[0], &srt, NULL); srt.x = px*ImageInfo[1].w/ImageInfo[1].x; srt.y = py*ImageInfo[1].h/ImageInfo[1].y; srt.w = ImageInfo[1].w/ImageInfo[1].x; srt.h = ImageInfo[1].h/ImageInfo[1].y; SDL_RenderCopy(pRenderer, pImageTexture[1], &srt, pr); srt.x = nx*ImageInfo[2].w/ImageInfo[2].x; srt.y = ny*ImageInfo[2].h/ImageInfo[2].y; srt.w = ImageInfo[2].w/ImageInfo[2].x; srt.h = ImageInfo[2].h/ImageInfo[2].y; SDL_RenderCopy(pRenderer, pImageTexture[2], &srt, nr); SDL_RenderPresent(pRenderer);}// 取得图片文件纹理// 参数:pRenderer = 渲染器;FileName = 图片文件名;bTransparent = 是否透明处理;color = 背景色// 返回值:纹理指针SDL_Texture *GetImageTexture(SDL_Renderer *pRenderer, char *FileName, _Bool bTransparent, int color){ SDL_Texture *pTexture; SDL_Surface *pSurface; if((pSurface = IMG_Load(FileName)) == NULL) return NULL; if(bTransparent) SDL_SetColorKey(pSurface, 1, SDL_MapRGB(pSurface->format, color>>16, (color>>8)&0xFF, color&0xFF)); pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface); SDL_FreeSurface(pSurface); return pTexture;}
图片是从 C4droid 百度吧找来的。
人物移动位置没有进行合理性检查,这需要对地图进行分格定性。