# How to create / draw clickable object (such as Button in WinForm) in XNA WP8?

I am developing a 2D (No 3D in every aspect) Windows Phone 8 turn based tactical games for my college project. I use Monogame.

I want to draw an object similar to Button in windows form, that if the object is tapped / touched, then an event / method started. I am looking for a way to create a similar event like "OnClick" attached on an object, so I know which tile is tapped by the user specifically.

The object is not entirely visible, because I used an empty transparent texture2D (In case you wondered)

Thank you.

(Please feel free to ask anything if my question is not clear enough, and sorry for my jumbled language, if any.)

===============================

FURTHER EXPLANATION : In front of every sprite, I want to draw a "transparent object" that can run an event when tapped (so it appear like user tapped the character, but behind-code-ly, the "transparent object" which is tapped, because it the one that can receive tap input).

Why I need this kind of object, because if I get the tapped coordinate, the coordinate fetched is relatively based on the viewport, once the map bigger, then it's so hard to calculate the tapped thing. But with the "transparent object", wherever the tile is, I can get which tile is tapped precisely.

I think this also an attempt to make my code as detached as possible by dividing each action into a separate class.

Here's some code taken from one of my games to get mouse / touch coordinates.

        int x = 0;
int y = 0;
bool isInputPressed = false;
var touchPanelState = TouchPanel.GetState();
var mouseState = Mouse.GetState();
#if ANDROID
if(touchPanelState.Count >= 1)
{
var touch = touchPanelState[0];
x = (int)touch.Position.X;
y = (int)touch.Position.Y;

isInputPressed = touch.State == TouchLocationState.Pressed || touch.State == TouchLocationState.Moved;
}
#else
x = mouseState.X;
y = mouseState.Y;
isInputPressed = mouseState.LeftButton == ButtonState.Pressed;
#endif


Once you have that you can check to see if the coordinates are inside the rectangle of your "transparent object" or button.

var buttonRectangle = new Rectangle(X, Y, Width, Height);

if(isInputPressed && buttonRectangle.Contains(x, y))
OnClick();


As mentioned previously, you may need to scale your input to screen coordinates to and back again. Using a projection is technically the correct way to do it, but ultimately what you are really doing is just scaling your screen size by some ratio.

Generally for 2D games you will work with a "virtual screen size" and scale everything based on that. For example, lets say you make your virtual screen size 800x480 (typical Android screen). You can create a scale vector like this:

var scaleX = (float)GraphicsDevice.Viewport.Width / 800f;
var scaleY = (float)GraphicsDevice.Viewport.Height / 480f;

_screenScale = new Vector3(scaleX, scaleY, 1.0f);


And pass it into your spritebatch draw call to scale the graphics.

_spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend,
SamplerState.PointClamp, DepthStencilState.Default,
RasterizerState.CullNone, null, Matrix.CreateScale(screenScale));


When you are dealing with mouse / touch coordinates you'll want to scale back like so:

x = (int)(x / _screenScale.X);
y = (int)(y / _screenScale.Y);


That way, the rest of your code can deal with coordinates in virtual screen space as if you are always dealing with the same side screen. Good luck! :)

• Thank you, but it seems detecting touch need to handled in separate thread. I tried to use DispatcherTimer, but it said UnauthorizedAccessException when I instantiate the DispatcherTimer. Any idea? – Moses Aprico May 31 '13 at 4:37
• The architecture of a game is quite different to a typical application. You don't need threads because games constantly poll an Update method. Take a look at these tutorials for a basic primer rbwhitaker.wikidot.com/mouse-input (click the 'view complete source code' link at the bottom) – craftworkgames May 31 '13 at 5:20
• This is my complete explanation based on the problem. gamedev.stackexchange.com/questions/56539/…. Maybe u can help. The quick problem explanation is, the input not always detected. – Moses Aprico May 31 '13 at 5:24

This sounds a bit like you're overthinking this (that's not how you should "detach" code or functionality).

You shouldn't have any issue transforming screen coordinates (the clicked/tapped position) into game/world coordinates. Don't introduce extra objects just to catch events, you'll have to do the transformation stuff anyway (to place the transparent objects over actual objects).

I haven't dabbed into XNA 4.0 specifically, but there should be some premade transformation stuff you can use to translate your coordinates in one single line. Just check the accepted answer to this question.

The actual implementation is really based on how you handle input (e.g. creating events or just checking coordinates, etc.).

• With extra object (that's clickable), the implementation is simpler, because I always do my drawing based with array (the environment). – Moses Aprico May 30 '13 at 14:12

There are classes where you can ask the position of the touch/mouseclick. Not sure if you can use Mouse.GetState() on WP, but there are also TouchPanel classes.

When you have the current state (if a touch happend, where it happend), you can check if the touch location is within the buttons location and if so, raise the event.