Touch release event not detected XNA

Jun 16, 2012 at 10:33 PM

Hello,

I've implemented the XNA Ad Rotator on my game and noticed that the release touchstate was not always detectedwhen my game was displaying MobFox or Inneractive ads. AdDuplex and Pubcenter seems to work fine.

I'll try to reproduce the issue on a newly created app and directly using the sdk from mobfox and inneractive to ensure that it's connected to AdRotator.

Regards

Jun 17, 2012 at 9:25 AM

Inneractive and Mobfox like the HouseAD implement a local web ad provisioning system because those providers do not offer XNA versions for their networks.

The components just sample the touchstates to detect if the user has "tapped", which is the normal way of handling this.

 

Only issue in the past i've seen is that the phone only supports so many samples per update of the touch screen, if this really is the case we may consider an update to the XNA component to accept a touch externally instead of looking or one it'self (a subscriber model).

Let us know how your tests go on.

Jun 17, 2012 at 2:12 PM

After testing it in an empty app containing only AdRotator I was able to reproduce the issue. As you stated Inneractive and Mobfox do not provide XNA version so I was not able to test it independently.

Regarding the test I've just put a line in console when release state is detected like this :

TouchCollection l_col = TouchPanel.GetState();
            foreach(TouchLocation l_loc in l_col)
            {
                if (l_loc.State == TouchLocationState.Released)
                {
                    System.Diagnostics.Debug.WriteLine("RELEASED " + gameTime.TotalGameTime.TotalSeconds);
                }
            }

Without adrotator gamecomponent the line appear each time I release the mouse button / finger on device, with the gamecomponent  configured to display only inneractive and mobfox ads, it's detected around one over 3 times.

Jun 17, 2012 at 3:07 PM

Ok got a bit confused when you were mentioning using the "Released" state, as we don't use that in adrotoator, we just test any event that occurs within the banner region.  If you look at the source within each component we test like this

 

 

                   foreach (var item in TouchState)
                    {
                        if (BannerRect.Contains(new Point((int)item.Position.X, (int)item.Position.Y)))
                        {
                            try
                            {
                                WebBrowserTask wb = new WebBrowserTask();
                                wb.Uri = AdUrl;
                                wb.Show();
                            }
                            catch { }
                            finally
                            {
                                if (AdClicked != null)
                                {
                                    AdClicked(AdUrl, new EventArgs());
                                }
                                Clicked = true;
                            }
                        }
                    }

 

So as you see we don't use states.

But as I said, we use 

var TouchState = TouchPanel.GetState();

To get the state of the touchpad and there have been issues in the past with WP7 if the touchpad state is queried too many times, however if it is working everytime for PubCenter and AdDupex then there must be something else going on.

Jun 17, 2012 at 5:15 PM

After further investigation I can reproduce it with an empty gamecomponent, the touchreleased event will be randomly detected either by the main game or the gamecomponent, I'll try to find more infos about this issue.

Also it means that it also occurs with pubcenter and adduplex, so I checked again and yes in the end the bug is present everywhere my bad.

Finally if I may suggest an improvement, it would be great to check if the component is currently visible before handling events, in my game I currently set the ad component visible only during game, but right now if I touch the ad area while it's not visible it will still launch the browser.

Anyway thanks for this awesome lib, I use it both in XNA and silverlight, and even if it's not yet complete it's still a great job!

Jun 17, 2012 at 6:19 PM
Edited Jun 17, 2012 at 6:23 PM

It's me again, 

Update regarding adduplex and pubcenter, I think it was not working because I was calling the GetState() from their update method (for debug purpose), without this call (as it is right now in AdRotator) it's working fine.

I found an explanation regarding the issue here :

http://forums.create.msdn.com/forums/t/53292.aspx

That is the correct behavior. When you call GetState, we update the touch state accordingly. So if a touch was Moved and now is missing from the hardware, it gets marked as Released. If you call GetState and a touch is marked as Released, we remove it from our collection. Basically you should try to only call GetState once per frame and use those results everywhere for that frame because of this.

So I guess the solution will be to not call GetState() and find an other way to detect input in the gamecomponent, I'm investigating this atm but didn't find a solution, I've looked at gesture but supported gestures must be setup in the game itself...

Jun 17, 2012 at 9:44 PM

Thats what I tried to allude to above, it's a known issue.  However fixing it for AdMob / Inneractive / Mobfox and House Ads would not resolve it for PubCenter and AdDuplex.

So would you prefer a dis-seperate solution (accepting a "state" as a parameter to the control) or a fixed solution having all controls with the same way?

Jun 17, 2012 at 10:09 PM

Not sure to see what you mean here regarding your solutions. Once again AdDuplex and Pubcenter are working fine as they do not call TouchPanel.GetState().

On my side I temporally fixed it locally by adding a Touchcollection static member to the AdRotator lib that I update manually from my game update method, the only place where I call TouchPanel.GetState() anymore.

I also added a if(Visible) test in all the update methods of the various AdProviderComponents.

Jun 18, 2012 at 12:18 AM

AdDuplex / PubCenter and Smaato are XNA versions of their own control, they like AdRotator implement XNA components to function and are self contained.  SO all we do in AdRotator is expose those XNA components and all other functions are handled internally by them

The rest of the AdProviders we handle, by downloading Ad's as they become available and test the device touchscreen manually (by currently using GetState).

So we can use the method you suggest by allowing the game consuming AdRotator to provide the touchstate instead of querying it manually.  However this will not affect how the providers we don't manage.

As the only way to determine when a part of the screen is touched is GetState they are probably implementing it.

 

As for the "Visible" check this is completely valid and we'll include it in the next update.

Jul 6, 2012 at 10:18 AM
Edited Jul 6, 2012 at 8:25 PM

Hi guys,

First of all great job, it was a big relieve finding your project. Thank you.

Up to the current issue I used a decompiler tool (JustDecompiler) to examine AdDuplex Update method and find out that they utilize Mouse.GetState() instead. It seems that Mouse.GetState() should be enough for resolving a single touch. Thus I changed the AddInteractiveComponent.Update() as shown below and this fixed the issue for me.

Have a nice day and happy coding. :)

 

        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here
            var TouchState = Mouse.GetState();  
            if (TouchState.LeftButton == ButtonState.Pressed)
            {
                if (!Clicked)
                {
                    if (BannerRect.Contains(new Point(TouchState.X - 80, TouchState.Y)))
                        {
Jul 8, 2012 at 9:58 AM

That is an excellent discovery, wasn't even aware that the Mouse library was functioning on WP7 (granted never tried).

Will get that implemented as soon as there's time.

Jul 24, 2012 at 6:08 AM

If you use only one Mouse.GetState() method, you get ad click instantly when you touch ads and this may bother users. So here is solution when you get ad click only when you release touch. Also why you need subtract 80 at x touch positon? This will move touch position at wrong place. 

private MouseState currState;
private MouseState prevState;

public override void Update(GameTime gameTime)
{
      // TODO: Add your update code here
      prevState = currState;
      currState = Mouse.GetState();  
      if (currState.LeftButton == ButtonState.Released && prevState.LeftButton == ButtonState.Pressed)
      {
           if (!Clicked)
          {
               if (BannerRect.Contains(new Point(TouchState.X, TouchState.Y)))
               {

Jul 24, 2012 at 10:50 AM

Excellent Tip ButcherBoliz

This is more along the lines of what I would have implemented as it's a standard pattern in XNA for handling a "Tap" rather than a touch.

 

As for the 80px thing, that's already been explained as a bit of rogue code that will be summarily taken out and shot in the next release :D