1
\$\begingroup\$

I'm working on a Windows phone game and I'm having difficulty with the sprite movement. What I want to do is make the sprite gradually move to the position that is touched on screen, when there is only one quick touch and release. At the minute all I can do is either make the sprite jump instantly to the touch location or move along to the touch location when the touch is held down.

Code for jumping to touch location:

TouchCollection touchCollection = TouchPanel.GetState();
    foreach (TouchLocation tl in touchCollection)
    {
        if ((tl.State == TouchLocationState.Pressed)
             || (tl.State == TouchLocationState.Moved))
        {
            Vector2 newPos = new Vector2(tl.Position.X,tl.Position.Y);

                if (position != newPos)
                {
                    while (position.X < newPos.X)
                    {
                        position.X += (float)theGameTime.ElapsedGameTime.Milliseconds / 10.0f * spriteDirectionRight;
                    }
                }
        }
    }

Code to gradually move along while touch is held:

TouchCollection touchCollection = TouchPanel.GetState();
    foreach (TouchLocation tl in touchCollection)
    {
        if ((tl.State == TouchLocationState.Pressed)
             || (tl.State == TouchLocationState.Moved))
        {
            Vector2 newPos = new Vector2(tl.Position.X,tl.Position.Y);

                if (position != newPos)
                {

                        position.X += (float)theGameTime.ElapsedGameTime.Milliseconds / 10.0f * spriteDirectionRight;

                }
        }
     }

These are in the Update() method of the Sprite class.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

This should move the object to the last touch location, you can change ratio to adapt the speed. (I have developed never for wp7 but I think it should do the job)

EDIT: I didn't know TouchLocation was a struct. So I've changed the code.

bool Active = null;
Vector2 Target;

float ratio = 0.001f;

void Update()
{

    TouchCollection touchCollection = TouchPanel.GetState();
    foreach (TouchLocation tl in touchCollection)
    {
        if ((tl.State == TouchLocationState.Pressed)
        {
             Target =  new Vector2(tl.Position.X, tl.Position.Y);
             Active= true;
        }
    }

    if (Active)
    {

         Vector2 Delta = (Target- position) * ratio;

         if (Delta.Length()<0.001f)
         {
               position = Target;
               Active = false;
         } 
         else 
         {
               position += Delta;
         }
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ TouchLocation Active = null; This was bringing up errors, so I changed the TouchLocation to a bool and changed null to false. When I ran this code the sprite jumps along to the touch location in small increments, but only jumps each time the touch pad is pressed. \$\endgroup\$ Nov 20, 2011 at 1:53
  • \$\begingroup\$ I have changed the code, I did not know that TouchLocation was a struct. The update method must be called every frame, and you can change the ratio to change the speed. \$\endgroup\$
    – Blau
    Nov 20, 2011 at 12:18
0
\$\begingroup\$

I think a good way to do it is to represent the game object you are rendering as a class that has all the require information to update and render. This way you can better manage your object. For example, lets say what you are controlling is your Player class, it might look something like this.

public class Player
{
    public Vector2 Position { get;set; }
    public Vector2 Target { get;set }
    public float Speed { get;set; }
    public float DistanceToTarget { get;set; }
    public Texture2D Texture { get;set; }
    public Rectangle Source { get;set; 
    public bool IsMoving { get;set; }
    private Vector2 movementVector = new Vector2();

    public void Update(GameTime gameTime) 
    {
         DistanceToTarget = Vector2.Distance(Position,Target);
         if(Position != Target && IsMoving)
         {
             if(DistanceToTarget < (Speed * movementVector)) // to avoid your character getting stuck in a loop due to speed etc
             {
                  Position = Target;
             }
             else 
             {
                  movementVector = Target - Position;
                  movementVector.Normailze();
                  Position += movementVector * Speed;
             }
         }
    }

Where you are handling your input you might want to use something like.

if (gest.GestureType == GestureType.Tap)
{
     myPlayer.Target = gest.Position  // assuming your world only existing within your screen
     myPlayer.IsMoving = true;
}

Regarding handling of input, please see the Game State Management example on the AppHub education resources for a good way to handle input state on the Windows Phone platform and how to best use Gestures. (Look for the InputState class)

You could do away with the bool of IsMoving but I think it helps with readability and you might want to know this elsewhere for something else.

Hope this helped.

\$\endgroup\$

You must log in to answer this question.

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