SDL历程--课程设计之精灵图(支持触摸屏)

简介:

终于算是忙过去了一段时间,可以好好地写写总结了,这一周写了不少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,如需转载请自行联系原作者

相关文章
[笔记]音视频学习之SDL篇《十四》简单的动画
[笔记]音视频学习之SDL篇《十四》简单的动画
|
3月前
|
vr&ar C# 图形学
从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动
这篇文章是PICO开发系列教程的第四部分,详细介绍了在VR世界中实现射线传送、视角旋转和人物移动的方法,包括使用Teleportation组件进行区域传送和锚点传送,通过Snap Turn Provider组件实现视角快速旋转,以及创建PlayControl脚本来控制人物移动,并通过手柄与脚本组件的交互来增强VR体验。
|
3月前
|
API
【threejs教程】场景视角切换的神器:轨道控制器
【8月更文挑战第5天】threejs教程:场景视角切换的神器,轨道控制器
193 1
【threejs教程】场景视角切换的神器:轨道控制器
|
5月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
71 0
|
5月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
56 0
|
5月前
|
定位技术 图形学 开发者
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
76 0
|
5月前
|
自然语言处理 图形学
【unity实战】一个通用的FPS枪支不同武器射击控制脚本
【unity实战】一个通用的FPS枪支不同武器射击控制脚本
74 0
[笔记]音视频学习之SDL篇《十三》播放音乐和特效
[笔记]音视频学习之SDL篇《十三》播放音乐和特效
|
存储 传感器 C#
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞(一)
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞(一)
|
存储 安全 C#
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞(二)
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞
从零开始做一款Unity3D游戏<二>——移动,相机控制与碰撞(二)