Mouse Input Not Working

Started by
7 comments, last by JoeJ 4 months, 2 weeks ago

Hey all,

I'm trying to make it so when you click on a ball, it disappears (pops). However the mouse input is not working as it should. I'm using Raylib and C++. I've posted the snippet of code I'm having trouble with. If needed I can post more code. Note that when clicking on the ball, nothing happens.

//Inside of an init() method
Yellow_Ball.X_Pos = (float)GetRandomValue(1, MAX_WIDTH);
Yellow_Ball.Y_Pos = (float)GetRandomValue(1, MAX_HEIGHT);
Yellow_Ball.X_Vel = 4.0f;
Yellow_Ball.Y_Vel = 4.0f;
Yellow_Ball.Pos.x = Yellow_Ball.X_Pos;
Yellow_Ball.Pos.y = Yellow_Ball.Y_Pos;
Yellow_Ball.Vel.x = Yellow_Ball.X_Vel;
Yellow_Ball.Vel.y = Yellow_Ball.Y_Vel;
Yellow_Ball.Radius = 20;
Yellow_Ball.Timer_Countdown = 200;
Yellow_Ball.Points = 5;
Yellow_Ball.Popped = false;
Yellow_Ball.Visible = true;

//Inside an update() method
Vector2 MousePos = GetMousePosition();
mx = (int)MousePos.x;
my = (int)MousePos.y;

//issue is here
if ( MousePos.x == Yellow_Ball.Pos.x && MousePos.y == Yellow_Ball.Pos.y && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{
	Yellow_Ball.Popped = true;
	Player.Score += Yellow_Ball.Points;
	Player.Balls_Popped++;
	Player.Yellow_Balls_Popped++;
}

if (Yellow_Ball.Popped == true)
{
	Yellow_Ball.Vel.x = 0;
	Yellow_Ball.Vel.y = 0;
	Yellow_Ball.Timer_Countdown--;

	if (Yellow_Ball.Timer_Countdown == 0)
	{
		Yellow_Ball.Popped = false;
		Yellow_Ball.Vel.x += 4.0f;
		Yellow_Ball.Vel.y += 4.0f;
		Yellow_Ball.Timer_Countdown = 200;
	}
}
Advertisement
//issue is here
if ( MousePos.x == Yellow_Ball.Pos.x && MousePos.y == Yellow_Ball.Pos.y && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))

This condition is checking if the mouse position is exactly on the center of the ball/circle. You need to check if the mouse position is within the radius of the circle, which is, in pseudo-code:

if ( ( length( MousePos - Yellow_Ball.Pos ) ≤ Yellow_Ball.Radius ) && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) )

Thanks, now the ball disappears no-matter where I click on the screen. Maybe the coords are off?

if ((MousePos.x - Yellow_Ball.Pos.x + MousePos.y - Yellow_Ball.Pos.y < Yellow_Ball.Radius) && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{
	Yellow_Ball.Popped = true;
	Player.Score += Yellow_Ball.Points;
	Player.Balls_Popped++;
	Player.Yellow_Balls_Popped++;
}

That's not how you compute distance: See https://en.wikipedia.org/wiki/Distance

It's the square root of the sum of the squared distances.

sqrt( (mouse.x - ball.x) * (mouse.x - ball.x) + (mouse.y - ball.y) * (mouse.y - ball.y) )

EDIT: You may want to swap the button-pressed test and the computation, to avoid computing a distance when the mouse button isn't even pressed.

Thanks, but I think that is making it more complicated than it needs to be.

Another option is to check for the square around the ball:

if (mousePressed && abs(mouse.x - ball.x) <= radius && abs(mouse.y - ball.y) <= radius) { ... }

But that allows a user to click in the corners of the square, since you don't compute the real distance.

Alberth said:

Another option is to check for the square around the ball:

if (mousePressed && abs(mouse.x - ball.x) <= radius && abs(mouse.y - ball.y) <= radius) { ... }

But that allows a user to click in the corners of the square, since you don't compute the real distance.

Thanks the abs one worked.

LeftyGuitar said:
Thanks, but I think that is making it more complicated than it needs to be.

That's what you need to do to know if a point is within a circle or outside. If there would be a simpler way, Pythagoras would have figured it out already. : )

But we can optimize the sqrt away by using squared distance instead distance:

float distX = mouse.x - ball.x;
float distY = mouse.y - ball.y;
float sqdist = distX * distX + distY * distY;
// if (sqrt(sqdist) <= ball.radius) // slow test
if (sqdist <= (ball.radius * ball.radius)) // faster test

This topic is closed to new replies.

Advertisement