• Advertisement
Sign in to follow this  

c++ sdl button

This topic is 2293 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello again. I feel kinda noobish posting lots of help topics on this forum. But im really having troubles trying to get this button class to work. its the one of lazy foo but im trying to make it so I can put in a graphic when I declare the object, and it compiles fine but the button dosn't show and i cant click on the mouse collision area. Anyways here is the code that i've got.

button class
//button class
class button{

private:
//attributes of the buttons
SDL_Rect box;
SDL_Rect bImg_unh;
SDL_Rect bImg_h;

//button graphic
SDL_Rect* clips;

public:
//initialize varibles
button(int x, int y, int w, int h, SDL_Rect img_unh, SDL_Rect img_h);

//handles events and sets the buttons sprite region
void handle_events();

void show();

};

button::button(int x, int y, int w, int h, SDL_Rect img_unh, SDL_Rect img_h){

//set the buttons attributes
box.x = x;
box.y = y;
box.w = w;
box.h = h;

//set the selected image varibles
bImg_unh = img_unh;
bImg_h = img_h;

//set defualt sprite
clips = &bImg_unh;

}

void button::handle_events(){

//mouse offsets
int x = 0, y = 0;

//if the mouse moved
if(event.type == SDL_MOUSEMOTION){

//get the mouse offsets
x = event.motion.x;
y = event.motion.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
clips = &bImg_h;
}
//if not
else{

//set the button sprite
clips = &bImg_unh;

}
}

//if mouse buttonw as pressed
if(event.type == SDL_MOUSEBUTTONDOWN){

//if the left mouse button was pressed
if(event.button.button == SDL_BUTTON_LEFT){

//get 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)){

//do somthing
starting_screen = false;

}
}
}
}

void button::show(){

//show button
apply_surface(box.x, box.y, surface_tileset_startingScreen_buttons, surface_screen, clips);

}


main function
int main( int argc, char* args[] )
{

//initialize
if(init() == false) {return 1;}

// load files
if(load_files() == false) {return 1;}

//while user hasnt quit. second loop is so we can break out of the first one.
while(running == true){
while(running == true){

//while theres an event to handle
while(SDL_PollEvent(&event)){

starting_screen_inEvent();

// handle events for player
mainPlayer.handle_input();

x_quitCheck(event);

//event while loop end
}

//if the starting screen true then do the starting screen stuff
if(starting_screen == true){

//apply background
apply_surface(0,0,surface_background,surface_screen,NULL);

//show the buttons on screen
apply_surface(325,350,surface_tileset_startingScreen_buttons,surface_screen,&clip[0][1]);
apply_surface(283,392,surface_tileset_startingScreen_buttons,surface_screen,&clip[0][2]);
apply_surface(325,392,surface_tileset_startingScreen_buttons,surface_screen,&clip[0][3]);

}

if(starting_screen = true) {startingScreen_loadButton.show();}

//if starting screen is on flip the screen
if(starting_screen == true) {SDL_Flip(surface_screen);}

//this is for the starting screen loop
if(starting_screen == true) {break;}

////////////////////////////end of starting screen///////////////////////////////////////////////////////
/* */
////////////////////////////////////main game while//////////////////////////////////////////////////////

//move the player
mainPlayer.move();

// fills the screen in white to draw the sprites properly
SDL_FillRect( surface_screen, &surface_screen->clip_rect, SDL_MapRGB( surface_screen->format, 0xFF, 0xFF, 0xFF ) );

//show the player
mainPlayer.display();

// flip screen
if( SDL_Flip( surface_screen ) == -1 )
{
return 1;
}

//main while loop end
}
}

//Quit SDL
cleanup();

return 0;
}


clip varibles
bool load_files()
{
// clip[][] the first brackets are index numbers and the second set are how many sprites
// clip tileset index numbers
/* 0 = surface_startingScreen_buttons*/ clip[0][7];
/////////////////////GRAPHICS//////////////////////////////////
/*general*/
surface_player = load_image( "graphics//bodies//player.bmp" );
surface_background = load_image( "graphics//background.bmp" );
/*start menu*/
surface_tileset_startingScreen_buttons = load_image( "graphics//menus//start_screen//tileset_startingScreen_buttons.bmp");
///////////////////////////////////////////////////////////////
/*************************************************************/
//////////////////////SOUND////////////////////////////////////

///////////////////////////////////////////////////////////////
/*************************************************************/
///////////////////////set clip vars///////////////////////////
/*surface_startingScreen_buttons*/
clip[0][0].x = 0; //load button un-highlighted
clip[0][0].y = 0;
clip[0][0].w = 32;
clip[0][0].h = 32;

clip[0][1].x = 32; //play button un-highlighted
clip[0][1].y = 0;
clip[0][1].w = 32;
clip[0][1].h = 32;

clip[0][2].x = 0; //options button un-highlighted
clip[0][2].y = 32;
clip[0][2].w = 32;
clip[0][2].h = 32;

clip[0][3].x = 32; //close button un-highlighted
clip[0][3].y = 32;
clip[0][3].w = 32;
clip[0][3].h = 32;

clip[0][4].x = 64; //load button highlighted
clip[0][4].y = 0;
clip[0][4].w = 32;
clip[0][4].h = 32;

clip[0][5].x = 96; //play button highlighted
clip[0][5].y = 0;
clip[0][5].w = 32;
clip[0][5].h = 32;

clip[0][6].x = 64; //options button highlighted
clip[0][6].y = 32;
clip[0][6].w = 32;
clip[0][6].h = 32;

clip[0][7].x = 64; //close button highlighted
clip[0][7].y = 32;
clip[0][7].w = 32;
clip[0][7].h = 32;
///////////////////////////////////////////////////////////////
/*************************************************************/
/////////////////////////////CHECKS////////////////////////////
//this functions checks that all the files were laoded properly
if(surface_player == NULL|| surface_background == NULL){

return false;

}

//if everything loaded fine
return true;

///////////////////////////////////////////////////////////////
}


Thanks for reading.

Share this post


Link to post
Share on other sites
Advertisement
I can see that you are trying to move from one gamestate to other when user clicks a button, why are you so bragging so much. It is very use, Why are you using booleans to move from state to other state. You can use a enumerations of gamestates and then use switch/ case statements to move from one state to other, It is just very easy.
You have to understand it, just store a Enum of all the gamestate's and in the game loop switch the current type and handle events in all the gamestates and move from one to other state if needed.
Next in the Game logic just switch the current state and Draw and Blit all the surfaces being used.
You can hop on to gamestates by this method, But if there are many gamestates, i would make a class for it and change the current state, for lesser gamestates its easy, because the code is less and you dont wanna stuff everything in the main loops handling events. it would be a mess.

As a mock up, I would do something like this,

/*Its tested and it works*/
#include <sdl.h>
#include <iostream>
#include <ctime>
#include <cstdlib>
const Uint8 Button = SDL_BUTTON_LEFT; /*We know that we are going to use this button only*/

/*A boolean to check if the object intersects with the mouse*/
bool intersects( int objectX, int objectY, int objectW, int objectH, int mouseX, int mouseY )
{
if( mouseX < objectX || mouseY < objectY )
{
return false;
}
else if( mouseX > objectX + objectW || mouseY > objectY + objectH )
{
return false;
}
/*Returns true only if the mouse is hovering the object*/
return true;
}

/*enum of gamestates*/
enum gamestate
{
Intro,
Main,
Exit,
};

int main( int, char** )
{
std::srand(std::time(NULL));

if(SDL_Init(SDL_INIT_VIDEO) < 0 )
{
std::cout << "Failed to initialize" << SDL_GetError() << std::endl;
return 1;
}
std::atexit(&SDL_Quit);
SDL_Surface *screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
if(!screen)
{
std::cout << "Failed to set screen" << SDL_GetError() << std::endl;
return 2;
}
SDL_Surface *button = SDL_LoadBMP("newgame.bmp");
SDL_Rect cButton;
cButton.x = 220;
cButton.y = screen->h/2;
cButton.w = button->w;
cButton.h = button->h;
/*Set the current gamestate, in this case its Intro*/
gamestate current = Intro;
while( current != Exit ) /*Game Loop*/
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(current) /*Switch the current state*/
{
case Intro:
if(event.type == SDL_QUIT )
{
current = Exit;
}
/*Here we check if the mouse is being clicked on the button*/
if(( event.button.button &Button ) == Button && intersects(cButton.x,cButton.y,cButton.w,cButton.h,event.button.x,event.button.y))
{
current = Main; /*If it is true we change the current state*/
}
break;
case Main:
if(event.type == SDL_QUIT)
{
current = Exit;
}
break;
}
}
switch(current)
{
case Intro:
SDL_FillRect(screen, &screen->clip_rect, 000000);
SDL_BlitSurface(button, NULL, screen, &cButton ); /*We draw the icon*/
break;
case Main:
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF,0xFF,0xFF));
break;
}
SDL_Flip(screen);
}
return 0;
}


Implement this method with your code, It's easy.
Hope it helps.

.

Share this post


Link to post
Share on other sites
Thanks for the game state idea which I will work on implementing. But you missed the point entirely. The thing that's wrong is that the the button object startingScreen_loadButton won't show up on the screen.

Share this post


Link to post
Share on other sites
Well firstly, what happens in init() and applysurface? Also, where is the definition for startingScreen_loadButton?
On a unrelated note, you probably didn't want to have a single equals in
if(starting_screen = true) {startingScreen_loadButton.show();}
[font="Arial"]as this actually sets starting_screen to [/font][font="Arial"]true and makes the code in the braces always run.[/font]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement