Input system

Dec 10, 2010 at 10:25 AM

Hi,

I'm evaluating this GUI for an amateur project and I'm having a problem: I need a way to prevent my game from receiving a mouse click when the GUI has already processed it, i.e. I have a window with a button. When I click the button the button is pressed but also my game catches the mouse down and makes the character move.

I know the problem is the way I'm processing user inputs:


// pseudo-code
void Game::Update(GameTime gameTime)
{
	MouseState state = Mouse.GetState();
	if (state.buttonPressed() && !lastState.buttonPressed())
		//  mousedown detected
	// ...
}

How am I suppoused to do this in order to achieve the desired behaviour?

Thanks.

Coordinator
Dec 10, 2010 at 5:36 PM

Hi,

I think you could create a GUI control that covers the whole window (like a desktop), then add your windows as children to the desktop. You can register an event handler for the desktop OnMouseDown event, which would tell you when the mouse has been clicked outside of a window.

Does that make sense?

Thanks,

cdmac

Dec 11, 2010 at 9:45 AM

Hi !

Of course it makes sense. I'll give it a try this weekend. Thank you very much.

I've found two additional issues: when a component (i.e. a window) is clipped its textures get stretched. Also, clipping an image component changes it's size. I've made a video where these problems can be clearly seen:


I see you are not using retangle scissors but doing handmade clipping. It's a performance decission ?

Anyway, I like very much your GUI and probably will use it in my game. If so, I'll credit you on credits and send you a video or a working copy.

Regards,
David.


From: [email removed]
To: [email removed]
Date: Fri, 10 Dec 2010 09:36:28 -0800
Subject: Re: Input system [wsx:237845]

From: cdmac

Hi,
I think you could create a GUI control that covers the whole window (like a desktop), then add your windows as children to the desktop. You can register an event handler for the desktop OnMouseDown event, which would tell you when the mouse has been clicked outside of a window.
Does that make sense?
Thanks,
cdmac
Read the full discussion online.
To add a post to this discussion, reply to this email (wsx@discussions.codeplex.com)
To start a new discussion for this project, email wsx@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Coordinator
Dec 12, 2010 at 1:51 AM

Hi David,


Ahh yes I remember that problem. I haven't worked on the C# version of the library for a long time, but did port it to C++ recently and have made some fixes and improvements. I'll try to compare the code between the two versions tomorrow and get back to you with a pseudo-code solution. I guess if the library is getting some use I should at least release new version with a few bug fixes.

Yes I don't use scissor rectangles because it is too slow. Every control must be clipped to it's parent, and every element including labels is a control. Even a simple window can have hundreds of controls. I tried that for a while as well as rendering each control to a render target, but the only efficient way is to do manual clipping. Unfortunately I added that technique pretty late and made a mistake, and didn't do much development after that.
Out of curiosity, what is the game you are working on?

Thanks,
cdmac
Dec 12, 2010 at 5:26 PM

Hi cdmac,

Thanks for replying. I'll take a look at that clipping code to see if I can find out the bugs by myself. Is the C++ version publicly available? Anyway, if you find them before and release a new version or post some sort of solution it would be great.

The game I'm developing is a project for my grade. It's going to be an Action Realtime Strategy game, like DotA, League of Legends or Demigod, but a "little" more humble :) By the moment I'm working on the AI (pathfinding, steering, goal/subgoal system and so). It has to be finished before May 1, 2011 Before christmas I must have 3 demos showing animation system, steering and mouse control. I can record a video of the demos and post them to you if you're still curious.

Thanks again for your replies,
David.



From: [email removed]
To: [email removed]
Date: Sat, 11 Dec 2010 17:53:48 -0800
Subject: Re: Input system [wsx:237845]

From: cdmac
Hi David,


Ahh yes I remember that problem. I haven't worked on the C# version of the library for a long time, but did port it to C++ recently and have made some fixes and improvements. I'll try to compare the code between the two versions tomorrow and get back to you with a pseudo-code solution. I guess if the library is getting some use I should at least release new version with a few bug fixes.
Yes I don't use scissor rectangles because it is too slow. Every control must be clipped to it's parent, and every element including labels is a control. Even a simple window can have hundreds of controls. I tried that for a while as well as rendering each control to a render target, but the only efficient way is to do manual clipping. Unfortunately I added that technique pretty late and made a mistake, and didn't do much development after that.
Out of curiosity, what is the game you are working on?

Thanks,
cdmac
Read the full discussion online.
To add a post to this discussion, reply to this email (wsx@discussions.codeplex.com)
To start a new discussion for this project, email wsx@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com
Coordinator
Dec 13, 2010 at 11:39 PM

I have decided not to make the C++ version available as it relies on my engine, which I hope to use for commercial projects at some point. I'd be interested in knowing how you get on with your demos. What course are you doing?

Anyhoo, I found the relevant bit of clipping code. Unfortunately I don't have time to port it to C# as I'm flying out for Christmas holidays tomorrow. It should be clear enough for you to convert yourself even if you don't know C++. Basically this version modifies the source rectangle by the same percentage as is clipped off the destination rectangle. Let me know if you have any more questions.

The function is PerformClipping() in GuiManager.cs (I've moved it in the C++ version):

 

bool BitmapFont::PerformClipping(GraphicsTypes::Rect& rScissor, GraphicsTypes::Rect& rSource, GraphicsTypes::Rect& rDestination)
{
	// Check if control is within scissor region, if so early out
	if (!rScissor.Contains(rDestination))
	{
		// Do the rectangles at least intersect?
		if (rScissor.Intersects(rDestination))
		{
			float diff;

			// Do the clipping
			if (rDestination.X < rScissor.X)
			{
				diff = (float)rScissor.X - (float)rDestination.X;

				float scale = (float)rSource.Width / (float)rDestination.Width;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Width -= (int32_t)sourceDiff;
				rSource.X += (int32_t)sourceDiff;
				rDestination.Width -= (int32_t)diff;
				rDestination.X += (int32_t)diff;
			}
			else if (rDestination.Right() > rScissor.Right())
			{
				diff = (float)rDestination.Right() - (float)rScissor.Right();

				float scale = (float)rSource.Width / (float)rDestination.Width;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Width -= (int32_t)sourceDiff;
				rDestination.Width -= (int32_t)diff;
			}

			if (rDestination.Y < rScissor.Y)
			{
				diff = (float)rScissor.Y - (float)rDestination.Y;

				float scale = (float)rSource.Height / (float)rDestination.Height;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Height -= (int32_t)sourceDiff;
				rSource.Y += (int32_t)sourceDiff;
				rDestination.Height -= (int32_t)diff;
				rDestination.Y += (int32_t)diff;
			}
			else if (rDestination.Bottom() > rScissor.Bottom())
			{
				diff = (float)rDestination.Bottom() - (float)rScissor.Bottom();

				float scale = (float)rSource.Height / (float)rDestination.Height;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Height -= (int32_t)sourceDiff;
				rDestination.Height -= (int32_t)diff;
			}
		}
		else
		{
			// Control is not visible at all
			return false;
		}
	}

	return true;
}

 

 

Dec 14, 2010 at 9:57 AM

Hi cdmac,

Thank you very much for your help. Don't worry about C++/C# port: it's straight forward and I'll have no problem with it. As soon as I have it implemented and tested in C# I will post it back to you so that you can update your codeplex project (if you want to, of course).

I'm doing last fine tunings to my first delivery of demos: i'll make the presentation next monday. I'll post some videos to you as soon as they are ready.

I'm doing 2nd course Grade on Computer Science. It's my 2nd Grade: first was on Business Administration X,D This one is a lot more fun and interesting ;)

Are you working on game industry ? I plan to do it at some point, but it's quite difficult in Spain where game industry is almost unexistent. If you are curious check out this video of a little game I made last year for a contest at my university:


Again, thank you very much for your help. I hope us to keep contact and please, let me know of your progress on your game engine: I'm very courious too ;)

Best regards and, if we don't write before, happy Christmas holidays.
David.



From: [email removed]
To: [email removed]
Date: Mon, 13 Dec 2010 15:39:38 -0800
Subject: Re: Input system [wsx:237845]

From: cdmac
I have decided not to make the C++ version available as it relies on my engine, which I hope to use for commercial projects at some point. I'd be interested in knowing how you get on with your demos. What course are you doing?
Anyhoo, I found the relevant bit of clipping code. Unfortunately I don't have time to port it to C# as I'm flying out for Christmas holidays tomorrow. It should be clear enough for you to convert yourself even if you don't know C++. Basically this version modifies the source rectangle by the same percentage as is clipped off the destination rectangle. Let me know if you have any more questions.
The function is PerformClipping() in GuiManager.cs (I've moved it in the C++ version):

bool BitmapFont::PerformClipping(GraphicsTypes::Rect& rScissor, GraphicsTypes::Rect& rSource, GraphicsTypes::Rect& rDestination)
{
	// Check if control is within scissor region, if so early out
	if (!rScissor.Contains(rDestination))
	{
		// Do the rectangles at least intersect?
		if (rScissor.Intersects(rDestination))
		{
			float diff;

			// Do the clipping
			if (rDestination.X < rScissor.X)
			{
				diff = (float)rScissor.X - (float)rDestination.X;

				float scale = (float)rSource.Width / (float)rDestination.Width;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Width -= (int32_t)sourceDiff;
				rSource.X += (int32_t)sourceDiff;
				rDestination.Width -= (int32_t)diff;
				rDestination.X += (int32_t)diff;
			}
			else if (rDestination.Right() > rScissor.Right())
			{
				diff = (float)rDestination.Right() - (float)rScissor.Right();

				float scale = (float)rSource.Width / (float)rDestination.Width;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Width -= (int32_t)sourceDiff;
				rDestination.Width -= (int32_t)diff;
			}

			if (rDestination.Y < rScissor.Y)
			{
				diff = (float)rScissor.Y - (float)rDestination.Y;

				float scale = (float)rSource.Height / (float)rDestination.Height;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Height -= (int32_t)sourceDiff;
				rSource.Y += (int32_t)sourceDiff;
				rDestination.Height -= (int32_t)diff;
				rDestination.Y += (int32_t)diff;
			}
			else if (rDestination.Bottom() > rScissor.Bottom())
			{
				diff = (float)rDestination.Bottom() - (float)rScissor.Bottom();

				float scale = (float)rSource.Height / (float)rDestination.Height;
				float sourceDiff = (scale * diff) + 0.5f;

				rSource.Height -= (int32_t)sourceDiff;
				rDestination.Height -= (int32_t)diff;
			}
		}
		else
		{
			// Control is not visible at all
			return false;
		}
	}

	return true;
}


Read the full discussion online.
To add a post to this discussion, reply to this email (wsx@discussions.codeplex.com)
To start a new discussion for this project, email wsx@discussions.codeplex.com
You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.
Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com