终于算是忙过去了一段时间,可以好好地写写总结了,这一周写了不少SDL方面的小项目;
下面就一一粘出来:
1.精灵图问题
/* preDefine.h*/ #ifndef __PRE_DEFINE_H #define __PRE_DEFINE_H #include <stdio.h> #ifndef false #define false 0 #endif #ifndef true #define true 1 #endif #ifndef error #define error -1 #endif #endif /* Global.h*/ #ifndef __GLOBAL_H #define __GLOBAL_H #include <stdio.h> #include <SDL.h> #ifdef __cplusplus extern "C" { #endif SDL_Surface *ObtainScreen( void ); void RegisterScreen(SDL_Surface *screen); SDL_Surface *ObtainScreenImage( void ); void RegisterScreenImage(SDL_Surface *screen); #ifdef __cplusplus } #endif #endif /* Global.c*/ #include "Global.h" static SDL_Surface *surf; static SDL_Surface *surfImage; SDL_Surface *ObtainScreen(void) { return surf; } void RegisterScreen(SDL_Surface *screen) { surf = screen; } SDL_Surface *ObtainScreenImage(void) { return surfImage; } void RegisterScreenImage(SDL_Surface *screen) { surfImage = screen; } /* Surface.h*/ #ifndef __SUFACE_H #define __SUFACE_H #include <SDL.h> #include <SDL_gfxPrimitives.h> #include <SDL_image.h> #include <SDL_rotozoom.h> #include <SDL_ttf.h> #include <stdio.h> #include "preDefine.h" #include "Global.h" #include "tslib.h" typedef struct BtnInfo { SDL_Rect rect; char *BtnTitle; int Flag; }BtnInfo; #ifdef __cplusplus extern "C" { #endif //SDL初始化, //成功返回true,失败返回false int SDLInit(); //释放资源 //成功返回true,失败返回false int freeSDL(); //初始化界面 //第一个参数为所要画按钮的坐标,第二个参数为按钮名字 //成功返回true,失败返回false int DrawBtn(SDL_Rect myrect, char *Btntitle); //描绘图案 //第一个参数为事件对象和按钮坐标,第二个参数为按钮名字,第三个参数为按钮弹起按下标记 //成功返回true,失败返回false int Draw(SDL_Rect myrect, char *BtnTitle, int Flag); //鼠标按下处理的事件 //参数为事件对象 //成功返回true,失败返回false int OnMouseDown(SDL_Event event); //鼠标弹起处理的事件 //参数为事件对象 //成功返回true,失败返回false int OnMouseUp(SDL_Event event); //事件处理 void *Event( void *junk); //获取用户输入控制信息 void *getCtrlMessage( void *junk); //比较触摸屏位置与哪个按钮向对应,返回值为生成按钮时的编号 int comparison( struct ts_sample, BtnInfo BtnArray[]); #ifdef __cplusplus } #endif #endif /* Surface.c*/ #include "Surface.h" BtnInfo BtnArray[10]; Uint32 BeginTicks, EndTicks; static int PlayerStarts = 0; static int PlayerIndex = 0; SDL_Rect PRect; static int BtnCount = 0; static int STATE_EVENT = 4; struct tsdev *ts; struct ts_sample sample; int SDLInit() { SDL_Rect BRect = {0, 0, 32, 48}; if (SDL_Init(SDL_INIT_VIDEO) < 0 || TTF_Init() < 0 ) { printf( "Init error\n" ); return false ; } SDL_Surface *screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); if (!screen) { printf( "Init video mode error\n" ); return false ; } SDL_Surface *PlayerImage = SDL_LoadBMP( "./player.bmp" ); if (PlayerImage == NULL) { fprintf(stderr, "Couldn't load player, %s\n" , SDL_GetError()); return error; } //读取第一个像素 Uint8 key = *((Uint8 *)PlayerImage->pixels); //设置色键 SDL_SetColorKey(PlayerImage, SDL_SRCCOLORKEY, key); RegisterScreenImage(PlayerImage); PRect.x = 0; //初始化动画显示的图片。 PRect.y = 0; PRect.w = 32; PRect.h = 48; //贴上测试用的表面 if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) < 0) { fprintf(stderr, "BlitSurface error: %s\n" , SDL_GetError()); //看看提示吧 return error; } RegisterScreen(screen); SDL_UpdateRects(screen,1,&screen->clip_rect); return true ; } int freeSDL() { SDL_Quit(); return true ; } int DrawBtn(SDL_Rect myrect, char *Btntitle) { TTF_Font * font = TTF_OpenFont( "simfang.ttf" , 20); SDL_Color color = {255, 255, 255}; SDL_Rect temprect; SDL_Surface *screen = ObtainScreen(); if (!screen) return ; SDL_FillRect(screen, &myrect, 0x9eabff); hlineRGBA(screen, myrect.x, myrect.x + myrect.w, myrect.y, 0xff, 0xff, 0xff, 0xff); vlineRGBA(screen, myrect.x, myrect.y, myrect.y + myrect.h, 0xff, 0xff, 0xff, 0xff); hlineRGBA(screen, myrect.x + 1, myrect.x + myrect.w - 1, myrect.y + myrect.h - 1, 0x00, 0x00, 0x00, 0xff); vlineRGBA(screen, myrect.x + myrect.w - 1, myrect.y + 1, myrect.y + myrect.h - 1, 0x00, 0x00, 0x00, 0xff); SDL_Surface *text = TTF_RenderUTF8_Solid(font, Btntitle, color); temprect.x = myrect.x + 5; temprect.y = myrect.y + 10; temprect.w = myrect.w - 10; temprect.h = myrect.h - 20; SDL_BlitSurface(text, 0, screen, &temprect); RegisterScreen(screen); SDL_UpdateRect(screen, myrect.x, myrect.y, myrect.w, myrect.h); //每增加一个Btn就将其按钮信息保存在全局变量之中 BtnArray[BtnCount].rect = myrect; BtnArray[BtnCount].BtnTitle = ( char *)malloc( sizeof ( char )*(strlen(Btntitle)+1)); strcpy(BtnArray[BtnCount].BtnTitle, Btntitle); BtnArray[BtnCount].Flag = true ; BtnCount++; TTF_CloseFont(font); return true ; } int Draw(SDL_Rect myrect, char *BtnTitle, int Flag) { SDL_Rect temprect; TTF_Font * font = TTF_OpenFont( "simfang.ttf" , 20); SDL_Color color = {255, 255, 255}; SDL_Surface *screen = ObtainScreen(); if (!screen) return ; SDL_FillRect(screen,&myrect,0x9eabff); if (Flag) { hlineRGBA(screen,myrect.x,myrect.x + myrect.w,myrect.y,0xff,0xff,0xff,0xff); vlineRGBA(screen,myrect.x,myrect.y,myrect.y + myrect.h,0xff,0xff,0xff,0xff); hlineRGBA(screen,myrect.x + 1,myrect.x + myrect.w - 1,myrect.y + myrect.h - 1,0x00,0x00,0x00,0xff); vlineRGBA(screen,myrect.x + myrect.w - 1,myrect.y + 1,myrect.y + myrect.h - 1,0x00,0x00,0x00,0xff); SDL_Surface *text = TTF_RenderUTF8_Solid(font, BtnTitle, color); temprect.x = myrect.x + 5; temprect.y = myrect.y + 10; temprect.w = myrect.w - 10; temprect.h = myrect.h - 20; SDL_BlitSurface(text, 0, screen, &temprect); } else { hlineRGBA(screen,myrect.x,myrect.x + myrect.w,myrect.y,0x00,0x00,0x00,0xff); vlineRGBA(screen,myrect.x,myrect.y,myrect.y + myrect.h,0x00,0x00,0x00,0xff); hlineRGBA(screen,myrect.x + 1,myrect.x + myrect.w - 1,myrect.y + myrect.h - 1,0xff,0xff,0xff,0xff); vlineRGBA(screen,myrect.x + myrect.w - 1,myrect.y + 1,myrect.y + myrect.h - 1,0xff,0xff,0xff,0xff); SDL_Surface *text = TTF_RenderUTF8_Solid(font, BtnTitle, color); temprect.x = myrect.x + 7; temprect.y = myrect.y + 13; temprect.w = myrect.w - 10; temprect.h = myrect.h - 20; SDL_BlitSurface(text, 0, screen, &temprect); } SDL_UpdateRect(screen,myrect.x,myrect.y,myrect.w,myrect.h); return true ; } int OnMouseDown(SDL_Event event) { if (STATE_EVENT == 4) return false ; PlayerStarts = STATE_EVENT+1; BtnArray[STATE_EVENT].Flag = false ; Draw(BtnArray[STATE_EVENT].rect, BtnArray[STATE_EVENT].BtnTitle, BtnArray[STATE_EVENT].Flag); return true ; } int OnMouseUp(SDL_Event event) { if (STATE_EVENT == 4) return false ; PlayerStarts = 0; BtnArray[STATE_EVENT].Flag = true ; Draw(BtnArray[STATE_EVENT].rect, BtnArray[STATE_EVENT].BtnTitle, BtnArray[STATE_EVENT].Flag); return true ; } void *Event( void *junk) { SDL_Surface *screen = ObtainScreen(); SDL_Rect BRect = {0, 0, 32, 48}; BeginTicks = SDL_GetTicks(); while ( true ) { SDL_MouseButtonEvent event; SDL_Event event1 ; if (sample.pressure) { event.type = SDL_MOUSEBUTTONDOWN; event.state = SDL_PRESSED; } else { event.type = SDL_MOUSEBUTTONUP; event.state = SDL_RELEASED; } event.x = sample.x; event.y = sample.y; event.which = 0; event.button = 0; event1.button = event ; SDL_PushEvent(&event1); SDL_Event event2; SDL_WaitEvent(&event2); SDL_Delay(50); switch (event2.type) { case SDL_MOUSEBUTTONDOWN: OnMouseDown(event2); break ; case SDL_MOUSEBUTTONUP: OnMouseUp(event2); break ; case SDL_QUIT: goto Exit; break ; } EndTicks = SDL_GetTicks(); //运用定时器 //到了50MS BeginTicks = EndTicks; SDL_FillRect(screen, &BRect, 0); //清除以前的图片。 if (PlayerStarts) { switch (PlayerStarts) { case 1: //向上移动。 if ((BRect.y - 5) > 0) { BRect.y -= 5; } else { BRect.y = 0; //设置位置在顶部。 } PRect.x = PlayerIndex * 32; //使用序号计算该显示那个动画图片 PRect.y = 144; //向上的图组 PlayerIndex ++; //动画序号加1 if (PlayerIndex > 2) PlayerIndex = 0; //循环显示动画 break ; case 2: if ((BRect.y + BRect.h + 5) < screen->h) { BRect.y += 5; } else { BRect.y = screen->h - BRect.h; } PRect.x = PlayerIndex * 32; PRect.y = 0; PlayerIndex ++; if (PlayerIndex > 2) PlayerIndex = 0; break ; case 3: if ((BRect.x - 5) > 0) { BRect.x -= 5; } else { BRect.x = 0; } PRect.x = PlayerIndex * 32; PRect.y = 48; PlayerIndex ++; if (PlayerIndex > 2) PlayerIndex = 0; break ; case 4: if ((BRect.x + BRect.w + 5) < screen->w) { BRect.x += 5; } else { BRect.x = screen->w - BRect.w; } PRect.x = PlayerIndex * 32; PRect.y = 96; PlayerIndex ++; if (PlayerIndex > 2) PlayerIndex = 0; break ; } } SDL_Surface *PlayerImage = ObtainScreenImage(); if (SDL_BlitSurface(PlayerImage, &PRect, screen, &BRect) < 0) { fprintf(stderr, "BlitSurface error : %s\n" , SDL_GetError()); return NULL; } SDL_Flip(screen); } Exit: freeSDL(); } int comparison( struct ts_sample sample, BtnInfo BtnArray[]) { int i = 0; for (; i < BtnCount; i++) { if ((sample.x >= BtnArray[i].rect.x && sample.x <= (BtnArray[i].rect.x+BtnArray[i].rect.w)) && (sample.y >= BtnArray[i].rect.y && sample.y <= (BtnArray[i].rect.y+BtnArray[i].rect.h))) return i; } } /*线程t_c,用于拾取用户操作命令*/ void *getCtrlMessage( void *junk) { int fangdou_flag = 1; //防抖标志。1:处理触摸点信息许可 ,0:处理触摸点信息禁止 int choice; ts = ts_open( "/dev/event1" , 0); if (!ts) { printf( "open device error!\n" ); return NULL; } if (ts_config(ts)) { perror( "ts_config\n" ); return NULL; } for (;;) { if (ts_read(ts , &sample, 1)) { /*只处理第一个触摸点信息*/ if ((sample.pressure) && (fangdou_flag == 1)) { choice = comparison(sample, BtnArray); switch (choice) { case 0: STATE_EVENT = 0; break ; case 1: STATE_EVENT = 1; break ; case 2: STATE_EVENT = 2; break ; case 3: STATE_EVENT = 3; break ; default : STATE_EVENT = 4; break ; } fangdou_flag = 0; //防止处理那些由于抖动所产生触摸点信息 } if (sample.pressure == 0) fangdou_flag = 1; } } /*关闭触摸屏设备文件*/ ts_close(ts); } /*main.c*/ #include "Surface.h" #include <pthread.h> int main( int argc, char *argv[]) { pthread_t t_a; pthread_t t_b; SDL_Rect myrect = {290, 385, 60, 40}; SDL_Rect myrect1 = {290, 435, 60, 40}; SDL_Rect myrect2 = {220, 435, 60, 40}; SDL_Rect myrect3 = {360, 435, 60, 40}; SDLInit(); DrawBtn(myrect, "上" ); DrawBtn(myrect1, "下" ); DrawBtn(myrect2, "左" ); DrawBtn(myrect3, "右" ); SDL_ShowCursor(0); pthread_create(&t_a, NULL, Event, ( void *)NULL); pthread_create(&t_b, NULL, getCtrlMessage, ( void *)NULL); pthread_join(t_a, NULL); freeSDL(); return 0; }
本文转自 驿落黄昏 51CTO博客,原文链接:http://blog.51cto.com/yiluohuanghun/863971,如需转载请自行联系原作者