0
\$\begingroup\$

So hi, I have a problem. I want to show an object (Texture2D) in an area tapped by user. This is my fields :

List<Texture2D> list = new List<Texture2D>();
List<Vector2> list2 = new List<Vector2>();
List<int> list3 = new List<int>();

list, is used to store the object. list2, used to store tapped coordinate. and list3, is used to store object timeout (after 100ms, the shown object vanishes)

This is my update method

protected override void Update(GameTime gameTime)
{
    TouchCollection touchState = TouchPanel.GetState();

    foreach (TouchLocation t in touchState)
    {
        if (t.State == TouchLocationState.Pressed)
        {
            list.Add(Content.Load<Texture2D>("base_grass"));
            list2.Add(new Vector2 { X = t.Position.X, Y = t.Position.Y });
            list3.Add(100);

            System.Console.WriteLine("added : " + t.Position.Y + "," + t.Position.X);
        }
    }

    for (int i = 0; i < list3.Count; i++)
    {
        list3[i]--;

        if (list3[i] <= 0)
        {
            list.RemoveAt(i);
            list2.RemoveAt(i);
            list3.RemoveAt(i);
        }
    }
    base.Update(gameTime);
}

(base_grass is the name of my object. It is a plain rectangle image)

The "for" statement is to remove the object when the time expires.

And this is my draw method

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.White);

    _spriteBatch2.Begin();

    for (int i = 0; i < list.Count; i++)
    {
        _spriteBatch2.Draw(list[i], list2[i], new Rectangle(0, 0, 64, 64),
                Color.White, 0, Vector2.Zero, 1f, SpriteEffects.None, 1);
    }
    _spriteBatch2.End();

    base.Draw(gameTime);
}

Nothing shown when I clicked on the screen.

But if I change the _spriteBatch2.Draw into this

 _spriteBatch2.Draw(list[i], new Vector2((64 * 0),(64 * i)), new Rectangle(0, 0, 64,64), Color.White, 0, Vector2.Zero, 1f, SpriteEffects.None, 1);

It worked, but shown vertically, not on the tapped / clicked coordinate.

Anyone know where my problem is? Thanks

\$\endgroup\$
2
  • \$\begingroup\$ Seems to me you should be using objects to store your grouped data, instead of splitting it into various linked lists. Consider creating a new class, this will simplify your code greatly. \$\endgroup\$
    – jgallant
    May 20, 2013 at 12:47
  • \$\begingroup\$ Yeah true. But this is just a dummy class to test the fungsionality. So it doesn't need to make a new class. In my "real" project, i'll surely make a new class. Btw, do you know why no output shown? \$\endgroup\$ May 20, 2013 at 12:51

2 Answers 2

2
\$\begingroup\$

Despite this being just a proof-of-concept, you should still follow correct programming practices. Create a new class that has the texture, position, and TTL (time-to-live). This will make it much easier for you and others to debug and work with.

Your object class:

public class TapMarker
{
    public TapMarker(Vector2 position)
    {
        Position = position;
        TTL = TimeSpan.FromMilliseconds(100);
        IsComplete = false;
    }

    public Vector2 Position { get; private set; }
    public TimeSpan TTL { get; private set; }
    public bool IsComplete { get; private set; }

    public void Update(GameTime gameTime)
    {
        TTL -= gameTime.ElapsedGameTime;

        if (TTL < TimeSpan.Zero)
            IsComplete = true;
    }

    public void Draw(SpriteBatch _spriteBatch, Texture2D texture)
    {
        _spriteBatch.Draw(texture, Position, Color.White);
    }
}

Your main game code:

    private List<TapMarker> markers;
    private Texture2D grassTexture;

    protected override void Update(GameTime gameTime)
    {
        base.Update(gameTime);

        TouchCollection touchState = TouchPanel.GetState();

        // Add a marker for each touch...
        foreach (TouchLocation t in touchState)
        {
            if (t.State == TouchLocationState.Pressed)
                markers.Add(new TapMarker(t.Position));
        }

        // Iterate backwards...
        for (int i = markers.Count; i >= 0; i--)
        {
            // Update the marker...
            markers[i].Update(gameTime);

            // Remove it if it is complete.
            if(markers[i].IsComplete)
                markers.RemoveAt(i);
        }
    }

    protected override void Draw(GameTime gameTime)
    {
        base.Draw(gameTime);

        GraphicsDevice.Clear(Color.White);

        _spriteBatch2.Begin();

        // Draw each marker
        foreach (var marker in markers)
            marker.Draw(_spriteBatch2, grassTexture);

        _spriteBatch2.End();
    }

As you can see, using a single class is much easier, and doesn't take that long to create.

Your initial draw call was too complicated, so I corrected that. Also, I noticed that your method to decrement the TTL was using the number of updates instead of the actual milliseconds. Make sure you utilize the GameTime parameter in the Update method.

To reduce the number of iterations through a loop, iterate backwards so removing an element will not effect the elements that come before it.

Finally, make sure that your classes can handle themselves. Giving them their own Update and Draw methods will help keep everything organized.

To answer your other question, the reason no output is shown is because Console.WriteLine will not work on Windows Phone 8. There are other alternatives, but I find conditional breakpoints to be easier to use.

\$\endgroup\$
7
  • \$\begingroup\$ First, thank you for your guide. Sorry if it mistaken, but I mean that the Texture is nowhere shown at the screen if I click it, not the console.writeline output. \$\endgroup\$ May 20, 2013 at 15:14
  • \$\begingroup\$ It seems that the t.location.X or Y have both returned infinity. Why is that possible? \$\endgroup\$ May 20, 2013 at 15:18
  • \$\begingroup\$ adding some code into update method just like github.com/mono/MonoGame/issues/1046, and succeed. The apps works just as I want. But, I still don't understand about this matter. Anyone knows? \$\endgroup\$ May 20, 2013 at 15:48
  • 1
    \$\begingroup\$ When you say "adding some code" and "succeed", what does that mean? Did you fix the infinity issue or the sprite not drawing? You need to be clear and concise when you ask for help. The more your explain the easier it will be for others to help. whathaveyoutried.com \$\endgroup\$
    – Jim Buck
    May 20, 2013 at 18:50
  • \$\begingroup\$ Yes I fix that. But I can only post comments for now, so it's surely unclear. \$\endgroup\$ May 20, 2013 at 23:22
0
\$\begingroup\$

I read an article here : https://github.com/mono/MonoGame/issues/1046

and adding this code to the first line of update method

 if (_firstUpdate)
 {
      typeof(Microsoft.Xna.Framework.Input.Touch.TouchPanel).GetField("_touchScale", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static).SetValue(null, Vector2.One);
      _firstUpdate = false;
 }

And voila! It works. The position value is not infinity anymore. Still, although I can make it right, but I still don't know what essentially the problem is. Anyone figured it out?

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .