Last Updated 2/25/06
Now it's time to learn to handle the mouse. This is a simple tutorial that will teach you to handle various mouse events to make a simple button.
//The button class Button { private: //The attributes of the button SDL_Rect box; //The part of the button sprite sheet that will be shown SDL_Rect* clip; public: //Initialize the variables Button( int x, int y, int w, int h ); //Handles events and set the button's sprite region void handle_events(); //Shows the button on the screen void show(); };
Here's the break down of the Button class.
We have a rectangle to define the position and dimentions of the Button. We also have a pointer to the sprite from the sprite sheet being used by the Button.
Then we have the constructor that sets the Button according to the attributes given in the arguments. Then we have our event handler, then the show function.
Button::Button( int x, int y, int w, int h ) { //Set the button's attributes box.x = x; box.y = y; box.w = w; box.h = h; //Set the default sprite clip = &clips[ CLIP_MOUSEOUT ]; }
The constructor for the Button class is pretty straight forward. It gets the Button's attributes, then sets the default sprite.
void Button::handle_events() { //The mouse offsets int x = 0, y = 0; //If the mouse moved if( event.type == SDL_MOUSEMOTION ) { //Get the mouse offsets x = event.button.x; y = event.button.y; //If the mouse is over the button if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) ) { //Set the button sprite clip = &clips[ CLIP_MOUSEOVER ]; } //If not else { //Set the button sprite clip = &clips[ CLIP_MOUSEOUT ]; } }
In the event handler, the first thing we check is if the mouse moved. When the mouse moves, a SDL_MOUSEMOTION event occurs.
If the mouse was moved, we get the mouse offsets from the event structure, then check if the mouse is over the Button. If the mouse is over the Button, we set the Button's sprite to be the mouse over sprite, otherwise it is set to the mouse out sprite.
//If a mouse button was pressed if( event.type == SDL_MOUSEBUTTONDOWN ) { //If the left mouse button was pressed if( event.button.button == SDL_BUTTON_LEFT ) { //Get the mouse offsets x = event.button.x; y = event.button.y; //If the mouse is over the button if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) ) { //Set the button sprite clip = &clips[ CLIP_MOUSEDOWN ]; } } }
Then we check if a mouse button was pressed. When a mouse button is pressed, a SDL_MOUSEBUTTONDOWN event occurs.
We only want the button to react to the left mouse button, so we check if the left mouse button was pressed.
Then we check if the mouse button was pressed over the Button. If it was we set the Button's sprite to be the mouse down sprite.
//If a mouse button was released if( event.type == SDL_MOUSEBUTTONUP ) { //If the left mouse button was released if( event.button.button == SDL_BUTTON_LEFT ) { //Get the mouse offsets x = event.button.x; y = event.button.y; //If the mouse is over the button if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) ) { //Set the button sprite clip = &clips[ CLIP_MOUSEUP ]; } } }
Then we check if the mouse button was released over the button with a SDL_MOUSEBUTTONUP event.
In this program we got the mouse offsets by getting them from the event structure. It would have been more efficient to get the mouse offsets via SDL_GetMouseState(), but.... eh I'm too lazy to go back and change the code.
void Button::show() { //Show the button apply_surface( box.x, box.y, buttonSheet, screen, clip ); }
Then in the show function we show the button's sprite on the screen.
//Clip the sprite sheet set_clips(); //Make the button Button myButton( 170, 120, 320, 240 ); //While the user hasn't quit while( quit == false ) { //Start the frame timer fps.start(); //If there's events to handle if( SDL_PollEvent( &event ) ) { //Handle button events myButton.handle_events(); //If the user has Xed out the window if( event.type == SDL_QUIT ) { //Quit the program quit = true; } } //Fill the screen white SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) ); //Show the button myButton.show(); //Update the screen if( SDL_Flip( screen ) == -1 ) { return 1; } //Cap the frame rate while( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) { //wait } }
Here's a basic demonstration of the button class being used. It's pretty much the same story as with the other main loops.
阅读(1227) | 评论(0) | 转发(0) |