How to: Create a 2D ButtonField with collision event

Hi,
Today i show you, how you can create a 21x11
Surface Field, with 32x28p Buttons where you can Click or Touch

Lets go:

...
SDL_Window* window = NULL;

SDL_Surface* screenSurface = NULL; 
SDL_Surface* Background = NULL;
SDL_Surface* maus = NULL;

SDL_Surface* hWndButton_Up = NULL;
SDL_Surface* hWndButton_Down = NULL; 
       
SDL_Rect MausPos,hWndFieldPos,pos,NULLpos;

int hWndFieldposX = 150;
int hWndFieldposY = 100; 

int ButtonX = 32; 
int ButtonY = 28; 

int hWndFieldMatrixX = 21;
int hWndFieldMatrixY = 11; 

int TouchposX;
int TouchposY;

int set_menu =1;
//------------------------- 

class draw
{
 public: 
 draw(); 
 int posX;
 int posY;
 void hWndButton(); 
 void hWndButtonEvent(); 
 private: 
};                 

//------------------------
                 
draw::draw() 
{
  pos.x = hWndFieldposX;
  pos.y = hWndFieldposY;
}
 
//--------------------------- 
          
void draw::hWndButton() 
{       
  
 for (int i=0; i<hWndFieldMatrixY; i++) 
  { 
   posX =hWndFieldposX;  //create collisionsfield
   posY +=ButtonY; 
   
   pos.x=hWndFieldposX; //create pos for Surface
   pos.y+=ButtonY; 
   
   for (int j=0; j<hWndFieldMatrixX; j++) 
   {      
    SDL_BlitSurface(hWndButton_Up ,NULL,screenSurface,&pos);
    
    pos.x+=ButtonX; 
    posX+=ButtonX; 
   } 
  }
  
 posY = hWndFieldposY;
 pos.y = hWndFieldposY; 
  
}

//----------------------------


void draw::hWndButtonEvent()
{
  for (int i=0; i<hWndFieldMatrixY; i++) 
  { 
   posX =hWndFieldposX;    
   posY +=ButtonY; 
   
   for (int j=0; j<hWndFieldMatrixX; j++) 
   {      
   
if ((((MausPos.x +9 >= posX ) && (MausPos.x + 9 <= posX+ 32))  ||  
   
((MausPos.x + 9 >= posX) && (MausPos.x + 9<=  posX+ 32)))  &&
    
 (((MausPos.y +9 >= posY) && (MausPos.y +  9 <=  posY+ 28)) ||

((posY+ 28 >= MausPos.y) && (posY + 28 <= MausPos.y+ 9))))
   {
    SDL_BlitSurface(hWndButton_Down, NULL,screenSurface,&NULLpos);    
      
  NULLpos.x  = posX; // make int to Rect Pos
  NULLpos.y =  posY; // for Button Down Surface
   }
    posX+=ButtonX; 
   }
 } 
}       

And in main:

 ...
screenSurface = SDL_GetWindowSurface(window); 
SDL_Surface *s; s=SDL_CreateRGBSurface(0, 960, 540, 32, 0, 0, 0, 0)

maus = SDL_LoadBMP("Maus.bmp");
hWndButton_Up = SDL_LoadBMP("hWnd_blank_up.bmp"); 
hWndButton_Down = SDL_LoadBMP("hwnd_blank_down.bmp");
...

bool quit = false; 
SDL_Event event; 
 
Uint32 start; 
const int FPS = 30; 
start = SDL_GetTicks();
 
 draw mydraw; 
   
while (quit == false)
{
  SDL_FillRect(screenSurface, NULL, SDL_MapRGB(s->format, 0, 0, 150)); 

  while (SDL_PollEvent(&event)) 
  {
   switch(event.type) 
 {
    case SDL_MOUSEMOTION: 
    TouchposX = event.motion.x;
    TouchposY = event.motion.y; 
   MausPos.x =  TouchposX;
   MausPos.y =  TouchposY;
   break;

// case SDL_MOUSEBUTTONDOWN: //for pc
//  copy all from draw::hWndButtonEvent here!
 // break;

    break;
    case SDL_QUIT: 
    quit=true; 
    break;             
   } //end of switch event
 } // end of pollevent
 
// first load your screen,
// then open the pollevent, 
//then draw your buttons 


 if (set_menu == 1)
{ 
  mydraw.hWndButton();
  mydraw.hWndButtonEvent(); 
}

 SDL_BlitSurface(maus ,NULL,screenSurface,&MausPos); 

 MausPos.x += 2;
 
 if (MausPos.x > 800) {
 MausPos.x = 0;
 MausPos.y += 28;
 }


...
 //---------Android Screen event Portrait/Landscape --------------

if (event.type == SDL_WINDOWEVENT &&event.window.event ==       
        SDL_WINDOWEVENT_RESIZED) 
      { 
     screenSurface=SDL_GetWindowSurface(window); //create new size by spin.
     SDL_UpdateWindowSurface(window); 
     }
     
 SDL_UpdateWindowSurface(window); 
 } // end of quit While 
 
SDL_DestroyWindow(window); 
SDL_FreeSurface(screenSurface);
 SDL_FreeSurface(hWndButton_Down);
SDL_FreeSurface(hWndButton_Up); 
SDL_Quit(); 
return 0; 
}

Hope that help Beginers :wink:

IMPORTANT!

  • if you Clone a Surface wih a for loop you need a Class !

  • if you want, that all buttons can be touch , you muss create all in 2 for-loops as like the Buttons
    Draw function

-pointer to SDL_Rect works not correctly so need a bool if you want remove the Clicket button * tutorial coming soon