SDL学习(七) Mouse Move(鼠标事…

xiaoxiao2021-02-28  124

前面已经学习了键盘事件的简单处理,当然现在就要来学习鼠标事件了,鼠标事件不必键盘难,只是多了移动的操作而已,我们先看一下下面可以简单表示鼠标响应方式的Sprite Sheet:

 下面的演示程序实现的是在屏幕中设置一个button区域,该区域的显示通过判断鼠标事件(移动/远离/按下/弹起),然后调用上面的sprite sheet中的sprite进行相应,从而实现动态鼠标移动和按键响应的效果,首先是要定义个区域button,鼠标移动到此区域中button就显示mouse over 的图片,反之显示mouse over,如果鼠标左键在该区域中按下就显示mouse down的图片,弹起以后显示mouse up的图片(当然按下就会有弹起了..-_-)

下面是代码:

#include"SDL.h" #include<string> //屏幕相关信息定义const int SCREEN_WIDTH=640; const int SCREEN_HEIGHT=480; const int SCREEN_BPP=32; //定义四种鼠标按键状态const int CLIP_MOUSEOVER=0; const int CLIP_MOUSEOUT=1; const int CLIP_MOUSEDOWN=2; const int CLIP_MOUSEUP=3; //定义表面SDL_Surface *buttonSheet=NULL; SDL_Surface *screen=NULL;

SDL_Event event; //定义四个SDL_Rect来容纳四个按键图片的大小和offsetSDL_Rect Clip[4]; //设置各个鼠标事件图片在sprite sheet上面的范围的函数void set_clips() {  Clip[CLIP_MOUSEOVER].x=0;  Clip[CLIP_MOUSEOVER].y=0;  Clip[CLIP_MOUSEOVER].w=320;  Clip[CLIP_MOUSEOVER].h=240;  Clip[CLIP_MOUSEOUT].x=320;  Clip[CLIP_MOUSEOUT].y=0;  Clip[CLIP_MOUSEOUT].w=320;  Clip[CLIP_MOUSEOUT].h=240;  Clip[CLIP_MOUSEDOWN].x=0;  Clip[CLIP_MOUSEDOWN].y=240;  Clip[CLIP_MOUSEDOWN].w=320;  Clip[CLIP_MOUSEDOWN].h=240;  Clip[CLIP_MOUSEUP].x=320;  Clip[CLIP_MOUSEUP].y=240;  Clip[CLIP_MOUSEUP].w=320;  Clip[CLIP_MOUSEUP].h=240; }     //装载图片的函数SDL_Surface *load_image(std::string filename) {  SDL_Surface *loadedImage=NULL;     SDL_Surface *optimizedImage=NULL;  loadedImage=IMG_Load(filename.c_str());  if(loadedImage!=NULL)  {   optimizedImage=SDL_DisplayFormat(loadedImage);   SDL_FreeSurface(loadedImage);   if(optimizedImage!=NULL)   {    SDL_SetColorKey(optimizedImage,SDL_SRCCOLORKEY,SDL_MapRGB(optimizedImage->format,0,0xFF,0xFF));   }  }  return optimizedImage; } //sticky两表面的函数void apply_surface(int x,int y,SDL_Surface *source,SDL_Surface *destination,SDL_Rect *clip=NULL) {     SDL_Rect offset;  offset.x=x;  offset.y=y;  SDL_BlitSurface(source,clip,destination,&offset);

}

//定义button类,中间封装了按键的位置和大小信息,如此一来我们就可以从sprite sheet中得到我们需要使用的按键的sprite。 //我们会偶设置button和坐标和其对于鼠标事件的响应函数,从而在button中封装一个surface用来显示现在的鼠标事件 class Button { private:  SDL_Rect box;  SDL_Rect *clip; public:  Button(int x,int  y,int w, int h)   {    //初始化button的函数   box.x=x;    box.y=y;    box.w=w;    box.h=h;    clip=&Clip[CLIP_MOUSEOUT];//默认的鼠标状态是在button外   };  void handle_event();//定义button的事件响应动作 void show();//显示当前事件的响应button};

void Button::handle_event() {  int x=0,y=0;  if(event.type==SDL_MOUSEMOTION)  {//如果发现了鼠标移动事件,就要得到鼠标当前位置,然后判断其是否在定义的button内  x=event.motion.x;   y=event.motion.y;       if((x>box.x)&&(x<box.x+box.w)&&(y>box.y)&&(y<box.y+box.h))    {//如果鼠标在定义的button内       clip=&Clip[CLIP_MOUSEOVER];    }    else     //鼠标在button外      clip=&Clip[CLIP_MOUSEOUT];  }

 //如果发生了鼠标按键按下事件 if(event.type==SDL_MOUSEBUTTONDOWN)  {   if(event.button.button=SDL_BUTTON_LEFT)   { //如果是左键按下的事件,就要判断按下鼠标的时候鼠标是否处在button区域中,所以要得到鼠标坐标   x=event.button.x;    y=event.button.y;    if((x>box.x)&&(x<box.x+box.w)&&(y>box.y)&&(y<box.y+box.h))    {//如果按下鼠标左键的时候鼠标处在button内    clip=&Clip[CLIP_MOUSEDOWN];    }   }  }  //如果发生了鼠标左键弹起事件,处理方式同鼠标左键按下事件     if(event.type==SDL_MOUSEBUTTONUP)  {   if(event.button.button=SDL_BUTTON_LEFT)   { //如果是左键弹起的事件,就要判断按下鼠标的时候鼠标是否处在button区域中,所以要得到鼠标坐标   x=event.button.x;    y=event.button.y;    if((x>box.x)&&(x<box.x+box.w)&&(y>box.y)&&(y<box.y+box.h))    {//如果按下鼠标左键的时候鼠标处在button内    clip=&Clip[CLIP_MOUSEUP];    }   }  }   } //将当前的鼠标响应的button surface 显示出来void Button::show() {    apply_surface(box.x,box.y,buttonSheet,screen,clip); }

//初始化函数bool init() {  if(SDL_Init(SDL_INIT_EVERYTHING)==-1)   return false;      screen=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);   if(screen==NULL)    return false;   SDL_WM_SetCaption("Button Test",NULL);   return true; } //sprite sheet装载函数bool load_files() {  buttonSheet=load_image("D:/Users/lucy/Documents/Visual Studio 2008/Projects/SDLtest/button.png");  if(buttonSheet==NULL)       return false;   return true; } //销毁工作 void clean_up()  {   SDL_FreeSurface(buttonSheet);   SDL_Quit();  }

int main(int argc, char *args[]) {  bool quit=false;  if(init()==false)   return 1;  if(load_files()==false)   return 1;    Button myButton(170,120,320,240);  set_clips();  while(quit==false)  {   if(SDL_PollEvent(&event))   {  //调用button事件处理函数   myButton.handle_event();    if(event.type==SDL_QUIT)    {     quit=true;    }   }   //黄背景填充屏幕  SDL_FillRect(screen,&screen->clip_rect,SDL_MapRGB(screen->format,255,255,0));   //显示button  myButton.show();      //更新屏幕  if(SDL_Flip(screen)==-1)   {                return 1;   }  }

  //收尾工作  clean_up();   return 0; }

效果图:

总结:

     鼠标键盘是一家,掌握了键盘事件以后鼠标事件就只是多了一个event.button.x/y的位置判断而已了,超级超级的简单,而且事件命名也是同键盘一样用SDL_MOUSEBUTTONDOWN、SDL_BUTTON_LEFT、SDL_MOUSEMOTION来定义的,用到的时候稍微查一下就行了。对了,不要忘了多重判断的条件,鼠标按下+鼠标左键+鼠标位置在button内

ps:写这个程序的时候出了一个坑死爹的错误,我竟然吧等于判断写成赋值,照着教程看来看去都没看出错就是显示不出来,最后发现的时候真想自插双目啊,以后要注意了看起来,竟然被这种低级错误恶心了半个小时.....

转载请注明原文地址: https://www.6miu.com/read-31300.html

最新回复(0)