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