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

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

  1. 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=,W=;
  6. const Uint32 FPS=;
  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={,,,};
  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=,Buttonnow=;
  28. if (!UpdateButton()) 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!=){
  39. if (!UpdateButton()) halt();
  40. Buttonnow=;
  41. }
  42. break;
  43. case SDL_MOUSEMOTION:
  44. if (isOnButton(Mouse.button.x,Mouse.button.y)){
  45. if (Buttonnow!=){
  46. if (!UpdateButton()) halt();
  47. Buttonnow=;
  48. }}else
  49. if (Buttonnow!=){
  50. if (!UpdateButton()) halt();
  51. Buttonnow=;
  52. }
  53. break;
  54. case SDL_MOUSEBUTTONUP:
  55. if (isOnButton(Mouse.button.x,Mouse.button.y)){
  56. if (Buttonnow!=){
  57. if (!UpdateButton()) halt();
  58. Buttonnow=;
  59. }}else
  60. if (Buttonnow!=){
  61. if (!UpdateButton()) halt();
  62. Buttonnow=;
  63. }
  64. }
  65. }
  66. if(SDL_GetTicks()-_FPS_Timer</FPS)
  67. SDL_Delay(/FPS-SDL_GetTicks()+_FPS_Timer);
  68. _FPS_Timer=SDL_GetTicks();
  69. }
  70. return ;
  71. }
  72. void halt(){
  73. cerr<<SDL_GetError()<<endl;
  74. Destroy();
  75. exit(-);
  76. }
  77. bool System_Init(){
  78. if (SDL_Init(SDL_INIT_VIDEO)==-) return false;
  79. if (IMG_Init(IMG_INIT_PNG)==-) return false;
  80. MainWin=SDL_CreateWindow("Button Test",,,W,H,SDL_WINDOW_SHOWN);
  81. if (MainWin==NULL) return false;
  82. Render=SDL_CreateRenderer(MainWin,-,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,,,);
  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>=&&x<=)
  119. if (y>=&&y<=) return true;
  120. return false;
  121. }

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

SDL实现按钮的更多相关文章

  1. SDL Guide 中文译版

    SDL即Simple DirectMedia Layer,类似DirectX,是完整的游戏.多媒体开发包,但不同的是它跨越几乎所有的平台,有各种语言的接口,多种语言的文档,而这一切都是广大志愿者完成的 ...

  2. 【C语言探索之旅】 第三部分第二课:SDL开发游戏之创建窗口和画布

    内容简介 1.第三部分第二课: SDL开发游戏之创建窗口和画布 2.第三部分第三课预告: SDL开发游戏之显示图像 第三部分第二课:SDL开发游戏之创建窗口和画布 在上一课中,我们对SDL这个开源库做 ...

  3. 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL

    内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...

  4. 2.SDL规范文档

    01.安全设计Checklist 输入验证 校验跨信任边界传递的不可信数据(策略检查数据合法性,含白名单机制等)格式化字符串时,依然要检验用户输入的合法性,避免可造成系统信息泄露或者拒绝服务 禁止向J ...

  5. SDL 开发实战(四): SDL 事件处理

    在前面学习SDL的例子运行时,我们发现我们的窗口只停留了几秒,但是如果设置更长时间显然也有其他的弊端. 那么有没有一种好的办法可以解决这个问题呢?例如:能不能让窗口一直显示,直到检测到用户用鼠标点击关 ...

  6. Beginning SDL 2.0(5) 基于MFC和SDL的YuvPlayer

    本文是在“Beginning SDL 2.0(4) YUV加载及渲染”(以下简称BS4)基础上做的功能完善,如果你对之间介绍的内容了解不多,麻烦先阅读之前的内容. 本文主要介绍如何完成一个基于MFC和 ...

  7. 音视频处理之FFmpeg+SDL+MFC视频播放器20180411

    一.FFmpeg+SDL+MFC视频播放器 1.MFC知识 1).创建MFC工程的方法 打开VC++ 文件->新建->项目->MFC应用程序 应用程序类型->基于对话框 取消勾 ...

  8. FFmpeg再学习 -- FFmpeg+SDL+MFC实现图形界面视频播放器

    继续看雷霄骅的 课程资料 - 基于FFmpeg+SDL的视频播放器的制作最后一篇,主要是想学一下 MFC 创建和配置. 一.创建 MFC 工程 文件->新建->项目->Visual ...

  9. ExtJS 4.2 Date组件扩展:添加清除按钮

    ExtJS中除了提供丰富的组件外,我们还可以扩展他的组件. 在这里,我们将在Date日期组件上添加一个[清除]按钮,用于此组件已选中值的清除. 目录 1. Date组件介绍 2. 主要代码说明 3. ...

随机推荐

  1. 【CSS3】Advanced4:Advanced Colors

    1.rgba(red,green,blue,alpha(不透明度0.0(完全透明)与 1.0(完全不透明)) 2.HSLa(hue(色调 0red 120green 240blue),saturati ...

  2. vijosP1210 盒子与球

    vijosP1210 盒子与球 链接:https://vijos.org/p/1210 [思路] Stirling+全排列. 因为第二类stirling所求是没有标明盒子顺序的方案数,所以最后需要乘一 ...

  3. CF29D - Ant on the Tree(DFS)

    题目大意 给定一棵树,要求你按给定的叶子节点顺序对整棵树进行遍历,并且恰好经过2*n-1个点,输出任意一条符合要求的路径 题解 每次从叶子节点开始遍历到上一个叶子节点就OK了, 这个就是符合要求的路径 ...

  4. HDU4607 - Park Visit(树的直径)

    题目大意 给定一颗树,要求走过其中连续的k个点,使得步数最少 题解 每条边要么经过两次,要么一次,因为我们的目标就是使得走一次的边尽量的多,这样就转换成求树的直径了,求树的直径我用的是两次dfs,先随 ...

  5. 小波变换和motion信号处理(三)(转)

    这篇文章算太监了,去作者blog提问去吧:http://www.kunli.info/2012/04/08/fourier-wavelet-motion-signal-3/ 从前两篇发布到现在,过去一 ...

  6. linux设备驱动----利用mdev(udev)自动创建设备文件节点

    1.mdev的使用方法和原理: mdev是busybox 自带的一个简化版的udev,适合于嵌入式的应用埸合.其具有使用简单的特点.它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程 ...

  7. 8-18-Exercise

    8-18-小练 A.HDU 1172   猜数字 采用枚举~[赤果果的暴力~] 代码: #include <iostream> #include <cstdio> #inclu ...

  8. python 语句,条件,循环

    #coding:utf-8__author__ = 'Administrator'#想要在同一行打印,print后面加','print 12,print 34'''从模块导入函数import some ...

  9. 团队项目·冰球模拟器——cmake 自动化构建系统的配置文件的编写

    1 前言 考虑到命令行界面下编译程序并不如在 IDE 那么直观,再考虑到各位队友对 Linux 并不熟悉,如何大幅度地减轻整个项目的开发复杂度就是一个很重要的问题. 在 Linux 下有个很古老但很有 ...

  10. Hibernate复合主键映射

    目录: 1. 实现方式一:将复合主键对应的属性与实体其他普通属性放在一起 2. 实现方式二:将主键属性提取到一个主键类中,实体类只需包含主键类的一个引用 在日常开发中会遇到这样一种情况,数据库中的某张 ...