SDL实现按钮


      是的,按钮控件很常见,几乎在每一个Windows窗体内都能找到它的身影。SDL作为一套“一套开放源代码的跨平台多媒体开发库”,自然可以实现按钮。而按钮实现的重点,就是SDL的鼠标响应事件。

      SDL的鼠标事件包括鼠标移动事件、按下鼠标键、松开鼠标键,和键盘一样,当你移动鼠标时发生鼠标移动事件,按下一个鼠标键,比如说左键时,发生按下鼠标键事件,松开鼠标键时会发生松开鼠标键事件。可以通过

SDL_PollEvent(&Event);

来把上一个事件从事件队列中取出。接下来可以进行判断,如果其type为SDL_MOUSEBUTTONDOWN则为鼠标按下,这时可以进行按下按钮后该做的事情,并把按钮的图片更新为按下后的样式。如果type为SDL_MOUSEBUTTONUP则为鼠标松开,则把按钮图片样式恢复未按下的情况。SDL_MOUSEMOTION表示鼠标在窗口表面移动,这时候可以把按钮更新到被指向的样式。当然,以上的一切更新,都是在鼠标的xy坐标位于按钮上才进行的。

      懂了鼠标事件,SDL实现按钮就很容易了。下面我直接贴上源代码,如果要背景图片和按钮图片可以点击下载。这个程序还有一些缺陷,主要是按钮图片有渐变色,去背景不彻底导致不美观。大家可以自己修改按钮图片。当然修改时要把程序中原来的图片宽、高的信息修改。

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <SDL2/SDL.h>
  4 #include <SDL2/SDL_image.h>
  5 const Uint32 H=650,W=1000;
  6 const Uint32 FPS=20;
  7 const char* BuFile[]={"B1.png","B2.png","B3.png"};
  8 SDL_Window *MainWin=NULL;
  9 SDL_Surface *BackGround=NULL,*ButtonSur=NULL;
 10 SDL_Renderer *Render=NULL;
 11 SDL_Texture *BackText=NULL,*ButtonText=NULL;
 12 SDL_Rect ButtRect={0,0,64,64};
 13 SDL_Event Mouse;
 14 using namespace std;
 15 
 16 bool System_Init();
 17 bool DrawBackGround();
 18 bool UpdateButton(Uint32);
 19 bool isOnButton(Uint32,Uint32);
 20 void halt();
 21 void Destroy();
 22 
 23 int main(int argc,char *argv[]){
 24     if (!System_Init()) halt();
 25     if (!DrawBackGround())   halt();
 26     bool quit=false;
 27     Uint32 _FPS_Timer=0,Buttonnow=0;
 28     if (!UpdateButton(0))   halt();
 29     while (!quit){
 30         while (SDL_PollEvent(&Mouse)){
 31             switch (Mouse.type){
 32             case SDL_QUIT:
 33                 quit=true;
 34                 break;
 35             case SDL_MOUSEBUTTONDOWN:
 36                 if (Mouse.button.button==SDL_BUTTON_LEFT)
 37                     if (isOnButton(Mouse.button.x,Mouse.button.y))
 38                         if (Buttonnow!=2){
 39                             if (!UpdateButton(2))   halt();
 40                             Buttonnow=2;
 41                         }
 42             break;
 43             case SDL_MOUSEMOTION:
 44                 if (isOnButton(Mouse.button.x,Mouse.button.y)){
 45                     if (Buttonnow!=1){
 46                         if (!UpdateButton(1))   halt();
 47                         Buttonnow=1;
 48                     }}else
 49                     if (Buttonnow!=0){
 50                         if (!UpdateButton(0))   halt();
 51                         Buttonnow=0;
 52                     }
 53             break;
 54             case SDL_MOUSEBUTTONUP:
 55                 if (isOnButton(Mouse.button.x,Mouse.button.y)){
 56                     if (Buttonnow!=1){
 57                         if (!UpdateButton(1))   halt();
 58                         Buttonnow=1;
 59                     }}else
 60                     if (Buttonnow!=0){
 61                         if (!UpdateButton(0))   halt();
 62                         Buttonnow=0;
 63                     }
 64             }
 65         }
 66        if(SDL_GetTicks()-_FPS_Timer<1000/FPS)
 67             SDL_Delay(1000/FPS-SDL_GetTicks()+_FPS_Timer);
 68        _FPS_Timer=SDL_GetTicks();
 69     }
 70     return 0;
 71 }
 72 void halt(){
 73     cerr<<SDL_GetError()<<endl;
 74     Destroy();
 75     exit(-1);
 76 }
 77 bool System_Init(){
 78     if (SDL_Init(SDL_INIT_VIDEO)==-1)   return false;
 79     if (IMG_Init(IMG_INIT_PNG)==-1)     return false;
 80     MainWin=SDL_CreateWindow("Button Test",540,270,W,H,SDL_WINDOW_SHOWN);
 81     if (MainWin==NULL)                  return false;
 82     Render=SDL_CreateRenderer(MainWin,-1,SDL_RENDERER_ACCELERATED);
 83     if (Render==NULL)                   return false;
 84     return true;
 85 }
 86 bool DrawBackGround(){
 87     BackGround=IMG_Load("BG.png");
 88     if (BackGround==NULL)               return false;
 89     BackText=SDL_CreateTextureFromSurface(Render,BackGround);
 90     if (BackText==NULL)                 return false;
 91     SDL_RenderClear(Render);
 92     SDL_RenderCopy(Render,BackText,NULL,NULL);
 93     SDL_RenderPresent(Render);
 94     return true;
 95 }
 96 void Destroy(){
 97     SDL_FreeSurface(BackGround);
 98     SDL_DestroyWindow(MainWin);
 99     SDL_DestroyRenderer(Render);
100     SDL_DestroyTexture(BackText);
101     IMG_Quit();
102     SDL_Quit();
103 }
104 bool UpdateButton(Uint32 ButtonMode){
105     DrawBackGround();
106     const char* OpenButton=BuFile[ButtonMode];
107     ButtonSur=IMG_Load(OpenButton);
108     Uint32 color_key=SDL_MapRGB(ButtonSur->format,255,255,255);
109     SDL_SetColorKey(ButtonSur,SDL_TRUE,color_key);
110     if (ButtonSur==NULL)    return false;
111     ButtonText=SDL_CreateTextureFromSurface(Render,ButtonSur);
112     if (BackText==NULL)     return false;
113     SDL_RenderCopy(Render,ButtonText,NULL,&ButtRect);
114     SDL_RenderPresent(Render);
115     return true;
116 }
117 bool isOnButton(Uint32 x,Uint32 y){
118     if (x>=0&&x<=64)
119         if (y>=0&&y<=64)    return true;
120     return false;
121 }

Bug Fix(2015-3-13 18:02):解决了鼠标提起那个时候按钮不能切换到状态0的问题。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM