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的问题。

你可能感兴趣的:(实现)