Game Not Detecting When Player Puts Their Mouse Over Button

I have made a lot of posts recently and I’m sorry for that but, I’m making a game in C++ that uses SDL, SDL Image and SDL Mixer. I’ve made my own game engine that can put stuff on screen, play music and things like that. I’m working on a button system and to start I’m detecting when the player puts their mouse over the button(s) then it’ll detect when the player clicks. I’m currently working on the system that detects when the play puts their mouse over the button(s). A problem arises though, It is meant to print to the console when the player hovers their mouse over the button(s), but it doesn’t print to the console for some reason. I have three files in the program: I have one for loading images, one for playing sound and a main one for basically everything else.

Main File: // Snooping through the files are we?// Compile With: g++ main.cpp loadImage - Pastebin.com
Image Loading File: // Snooping through the files now are we?// Compile With: g++ main.cpp loadI - Pastebin.com
Sound Loading File: // Snooping through the files now are we?// Compile With: g++ main.cpp loadI - Pastebin.com

You only check the mouse pointer against the button(s) when an SDL_MOUSEMOTION event is triggered, which means that you only do the check whenever the mouse pointer is moved.

You should do the mouse-vs-button check outside of the event loop.

Also a tip: if you’re planning on having buttons as squares/rectangles, consider using an SDL_Rect representing your button. There’s functionality in SDL to check if a point is inside an SDL_Rect for example, which can help you a lot.

Below is a code example on how to create a button with an SDL_Rect, and how to check if the mouse pointer is inside it.

View example code
#include <iostream>
#include <SDL.h>

#define WINDOW_WIDTH	(800)
#define WINDOW_HEIGHT	(600)

SDL_Window* pWindow = nullptr;
SDL_Renderer* pRenderer = nullptr;

SDL_Point MousePosition = {0, 0};

SDL_Rect Button = {0, 0, 0, 0};

bool Running = true;
bool MouseInsideButton = false;

int main(int argc, char** argv)
{
	// Define the button. In this case it will be positioned at (200, 200), with a size of (200, 40)
	Button = {200, 200, 200, 40};

	SDL_Event Event;
	while(Running)
	{
		while(SDL_PollEvent(&Event))
		{
			switch(Event.type)
			{
				case SDL_QUIT:
				{
					Running = false;

					break;
				}

				default:
					break;
			}
		}

		SDL_GetMouseState(&MousePosition.x, &MousePosition.y);

		// SDL_PointInRect returns SDL_TRUE if the point is inside the SDL_Rect, SDL_FALSE if it's not
		MouseInsideButton = (SDL_PointInRect(&MousePosition, &Button) == SDL_TRUE);

		if(MouseInsideButton)
			std::cout << "Mouse pointer is inside the button" << std::endl;
		else
			std::cout << "Mouse pointer is outside the button" << std::endl;

		SDL_SetRenderDrawColor(pRenderer, 0, 0, 0, 255);
		SDL_RenderClear(pRenderer);

		// Change the button color when it's hovered
		if(MouseInsideButton)
			SDL_SetRenderDrawColor(pRenderer, 255, 0, 0, 255);
		else
			SDL_SetRenderDrawColor(pRenderer, 255, 255, 255, 255);

		// Render the button rect
		SDL_RenderFillRect(pRenderer, &Button);

		SDL_RenderPresent(pRenderer);
	}

	return 0;
}

You might want to do it inside the event loop, it depends on what behaviour you want.

Note that SDL_GetMouseState gives you the most up-to-date mouse position which is not necessarily the position reported by the mouse motion event (i.e. event.motion.x and event.motion.y).

If you just need the mouse position to determine if the clicks are on the button you can access the position from the mouse button event (i.e. event.button.x and event.button.y).

Your createButton doesn’t work correctly. Note that the ++ operator modifies the variable.

buttonX[0] == NULL; This doesn’t do anything because you’re using == instead of =. In one of your earlier topics I recommended you turn on compiler warnings. This is another thing that warnings would have told you about. Note that NULL is only really meant to be used with pointers. It only works here because the standard library implementation that you’re using defines NULL as 0 but this is not the only possible implementation permitted by the standard.

I do get warnings but just not enough, how can I turn on compiler warnings with g++?

Use the -Wall flag. If you care about being “standard conformant” (writing code that doesn’t rely on compiler specific features) you probably also want to use -pedantic. Then there is also -Wextra which also enables many useful warnings (some of these might be a bit more subjective but you can always turn off specific warnings if you want). For more information, see https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

Thank you for letting me know this exists! It works now!