关键词搜索

源码搜索 ×
×

C语言SDL基础库扩展开发-动态显示鼠标的位置信息

发布2018-07-02浏览1003次

详情内容

原文地址:https://my.oschina.net/freestyletime/blog/166826

今天要讲的是,把鼠标的位置在SDL窗口上动态的显示,也就是画在窗口上。这里要用到SDL的其中一个extension library叫做SDL_ttf,用于把文字渲染到屏幕上,在http://www.libsdl.org/projects/SDL_ttf/release-1.2.html有下载。

不过下载完后把头文件库文件什么的加到环境中以后,写了一个小的Demo,并不能编译通过,详细信息请见http://www.oschina.net/questionhttps://cdn.jxasp.com:9143/image/250247_127725 ,嘿嘿,也是我今天下午在OSC上提出的问题,并没有人回答,是我最后自己解决的。

你可能会问博主,SDL_ttf 2.0.9 版本在哪下,你也不用考虑了,博主已经下好了,关于这几天的SDL文章的代码已经上传到了博主的OSC@GIT ,请在这里http://git.oschina.net/ChristianChen/SDL_demo.git将代码拷下来就行了,都是最新的代码。整个工程拷下来以后,SDL_demo目录下有个env_zip的文件夹,里面是所有迄今为止用到的压缩包,包括SDL、SDL_image、SDL_ttf等,你只需把里面的东西放到PC上正确的位置,即搭建好开发环境即可,看到这里是不是觉得博主考虑很周到呢?其实我也是这样想的,哈哈哈...

先来看看博主目前的工程目录:

上一篇博主在SDL_fun.h里封装了一个ScreenSurface的class对象,实现代码忘记给大家贴出来了,下面补上:

  1. //-----------------------Class------------------------------
  2. ScreenSurface::ScreenSurface(SDL_Surface* screen) :
  3. screen(screen) {
  4. if (screen != NULL) {
  5. this->screen = screen;
  6. } else {
  7. std::cerr << "creenSurface(SDL_Surface* screen) screen is NULL" << "\n";
  8. }
  9. }
  10. ScreenSurface::ScreenSurface(int w, int h, int b, Uint32 f) {
  11. this->screen = SDL_SetVideoMode(w, h, b, f);
  12. }
  13. ScreenSurface::~ScreenSurface(void) {
  14. }
  15. bool ScreenSurface::flip(void) const {
  16. if (SDL_Flip(this->screen) < 0) {
  17. std::cerr << SDL_GetError() << "\n";
  18. SDL_ClearError();
  19. return false;
  20. }
  21. return true;
  22. }
  23. SDL_Surface* ScreenSurface::acquire(void) {
  24. return this->screen;
  25. }
  26. //-----------------------Class------------------------------

由于在用到SDL_ttf,博主又在SDL_init.h头文件中,封装了初始化和退出SDL_ttf环境的函数

  1. /*
  2. * SDL_init.h
  3. *
  4. * Created on: 2013-10-3
  5. * Author: Christian
  6. */
  7. #ifndef SDL_INIT_H_
  8. #define SDL_INIT_H_
  9. #include <SDL/SDL.h>
  10. #include <SDL/SDL_ttf.h>
  11. #include <iostream>
  12. /** 初始化SDL环境 initiate SDL environment
  13. *
  14. * @param title represent current window's headline*/
  15. void createSDL(const char* title);
  16. /** 退出SDL环境 quit SDL environment*/
  17. void destroySDL(void);
  18. /** 初始化SDL TTF 环境 initiate SDL TTF environment */
  19. TTF_Font* createSDLTTF(const char* ttfFile, int size);
  20. /** 退出SDL TTF 环境 quit SDL TTF environment*/
  21. void destroySDLTTF(TTF_Font* font);
  22. #endif /* SDL_INIT_H_ */

当中的TTF_Font是个结构体,我理解的这个结构体的大概意思是代表某一种字体,比如宋体、楷体等等...

下面是实现:

  1. TTF_Font* createSDLTTF(const char* ttfFile, int size) {
  2. //Initialize all SDL subsystems
  3. if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
  4. std::cerr << "Call TTF_Init before call SDL_Init\n";
  5. return NULL;
  6. }
  7. if (TTF_WasInit() != 0) {
  8. std::cerr << "TTF is already running.\n";
  9. return NULL;
  10. }
  11. if (ttfFile == NULL) {
  12. std::cerr << "TTF_Init ttfFile is NULL" << "\n";
  13. return NULL;
  14. }
  15. //Initialize SDL_ttf
  16. if (TTF_Init() == -1) {
  17. std::cerr << "TTF_Init Failed:" << SDL_GetError() << std::endl;
  18. SDL_ClearError();
  19. return NULL;
  20. }
  21. std::cout << "TTF_Init successfully:\n";
  22. return TTF_OpenFont(ttfFile, size);
  23. }
  24. void destroySDLTTF(TTF_Font* font) {
  25. if (TTF_WasInit() == 0) {
  26. std::cout << "TTF was NOT running!\n";
  27. return;
  28. }
  29. TTF_CloseFont(font);
  30. //Quit SDL_ttf
  31. atexit(TTF_Quit);
  32. std::cout << "TTF_Quit successfully:\n";
  33. }

 

再来看看SDL_fun.h中新增的方法:

  1. /*
  2. * SDL_fun.h
  3. *
  4. * Created on: 2013-10-1
  5. * Author: Christian
  6. */
  7. #ifndef SDL_FUN_H_
  8. #define SDL_FUN_H_
  9. #include <iostream>
  10. #include <SDL/SDL.h>
  11. #include <SDL/SDL_image.h>
  12. #include <SDL/SDL_ttf.h>
  13. class ScreenSurface {
  14. public:
  15. ScreenSurface(SDL_Surface* screen = NULL);
  16. ScreenSurface(int width, int height, int bpp = 32, Uint32 flags =
  17. SDL_SWSURFACE);
  18. ~ScreenSurface(void);
  19. /** 将数据push到物理屏幕 */
  20. bool flip(void) const;
  21. /** 得到当前指向物理屏幕接口的指针 */
  22. SDL_Surface* acquire(void);
  23. private:
  24. SDL_Surface* screen;
  25. };
  26. void drawBitmap(ScreenSurface s, const char* fileName);
  27. void readKeyboard(ScreenSurface s);
  28. void getRadioInfo(ScreenSurface s);
  29. void renderPictures(ScreenSurface s, const char* fgFile, const char* bgFile);
  30. void drawClips(ScreenSurface s, const char* file, SDL_Rect* clip = NULL, int size = 0);
  31. void getMousePostion(ScreenSurface s);
  32. void drawTest(ScreenSurface s, TTF_Font* font, const char* message);
  33. void showMousePostion(ScreenSurface s, TTF_Font* font);
  34. void playAudio(ScreenSurface s, const char* fileName);
  35. void playVidio(ScreenSurface s, const char* fileName);
  36. #endif /* SDL_FUN_H_ */
 

其中的showMousePostion便是今天要讲的主要函数,用于显示鼠标在当前窗口的位置信息.

下面看看它的实现:

  1. /** 画出鼠标位置信息 */
  2. void showMousePostion(ScreenSurface s, TTF_Font* font) {
  3. if (font == NULL) {
  4. std::cerr << "font is NULL" << "\n";
  5. return;
  6. }
  7. SDL_Surface* msg = NULL;
  8. //将文字的颜色设为白色
  9. SDL_Color textColor = { 0, 0xFF, 0xFF };
  10. // SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
  11. SDL_Event event;
  12. char buf[11];
  13. do {
  14. SDL_WaitEvent(&event);
  15. //在SDL_Surface之上渲染文字
  16. if (event.type == SDL_MOUSEMOTION) {
  17. SDL_FillRect(s.acquire(), &s.acquire()->clip_rect,
  18. SDL_MapRGB(s.acquire()->format, 0xFF, 0xFF, 0xFF));
  19. sprintf(buf, "%d:%d", event.motion.x, event.motion.y);
  20. msg = TTF_RenderText_Solid(font, buf, textColor);
  21. //If there was an error in rendering the text
  22. if (SDL_BlitSurface(msg, NULL, s.acquire(), NULL) != 0) {
  23. std::cerr << SDL_GetError() << "\n";
  24. }
  25. if (!s.flip()) {
  26. std::cerr << SDL_GetError() << "\n";
  27. }
  28. }
  29. } while (event.type != SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE);
  30. SDL_FreeSurface(msg);
  31. }

 

 函数还是很简单的吧,哈哈,一看就懂的~再来看看main函数入口是怎么写的:

  1. //============================================================================
  2. // Name : SDL_demo.cpp
  3. // Author : Christian
  4. // Version : 1.0
  5. // Copyright : Copyright (c) 2013,Christian
  6. // Description : SDL in C++
  7. //============================================================================
  8. #include "include/SDL_init.h"
  9. #include "include/SDL_fun.h"
  10. using namespace std;
  11. int SDL_main(int argc, char *argv[]) {
  12. createSDL("Christian Test");
  13. TTF_Font* font = createSDLTTF("FreeSans.ttf", 30);
  14. //创建全局唯一的指向物理屏幕的SDL_Surface
  15. ScreenSurface screen(600, 600);
  16. //getMousePostion(screen);
  17. //drawBitmap(screen, "sheet.jpg");
  18. //drawTest(screen, "FreeMono.ttf", "Bitch , Fuck you ~");
  19. showMousePostion(screen, font);
  20. destroySDLTTF(font);
  21. destroySDL();
  22. return EXIT_SUCCESS;
  23. }

现在你便知道,工程下的那些ttf文件是干嘛用的啦,传给createSDLTTF函数,打开一种字体并设置字体的字号大小,相当于是拿到了窗口的画笔吧,但是颜色没有单独封装出来,想要更严谨的话,可以自己试试。

下面是编译链接运行后的效果图:

 

注意:SDL_ttf1.2依赖FreeType2.0或者更新的库(2.1.3除外)。

更多更好的SDL入门请参考:SDL入门教程


相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载