0

I want to be able to have a sprite shoot in a game for WP7. What I have at the moment is that as long as the shoot button is held down the sprite constantly shoots. How do I sort it that only one bullet is shot from touching the button and not a stream of bullets is released? I want for the player to be able to shoot another bullet, they must tap the button again. This was taken from a DreamInCode tutorial on how to make an asteroids clone for PC.

foreach (TouchLocation location in TouchPanel.GetState())
        {

            if (shootKeyBounds.Contains((int)location.Position.X, 
                                         (int)location.Position.Y))
            {
                FireBullet();

            } 

        }

The fire bullet method

private void FireBullet()
    {
        Sprite newBullet = new Sprite(bullet.Texture);

        Vector2 velocity = new Vector2(
            (float)Math.Cos(ship.Rotation - (float)MathHelper.PiOver2),
            (float)Math.Sin(ship.Rotation - (float)MathHelper.PiOver2));

        velocity.Normalize();
        velocity *= 6.0f;

        newBullet.Velocity = velocity;

        newBullet.Position = ship.Position + newBullet.Velocity;
        newBullet.Create();

        bullets.Add(newBullet);
    }
4
  • I'm not familiar with WP7, but there should be something that detects when a button is pushed down. Commented Jan 23, 2013 at 17:47
  • TouchLocation have a property called state. If the state is release then the location was very recently released. Commented Jan 23, 2013 at 18:19
  • This question is closed, gamedev.stackexchange.com/questions/38703/… , but it relevant. Figure out how to do it with a keyboard, and you can do it with a touchscreen. Commented Jan 23, 2013 at 18:38
  • I do know how to do it with a keyboard, but finding difficulty with a touch screen, thats why i asked here
    – Craig
    Commented Jan 23, 2013 at 19:07

2 Answers 2

2

You can check if the touch is a new press by using TouchLocation.State -property. Example:

foreach(TouchLocation location in TouchPanel.GetState())
{
    // Check if touch is a new press and if touch is inside shootKeyBounds
    if(location.State == TouchLocationState.Pressed && 
         shootKeyBounds.Contains((int)location.Position.X, (int)location.Position.Y)))
    {
        this.FireBullet();
    }
}

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.touch.touchlocationstate.aspx

0
1

Once you have handled a touch by firing a bullet you need to record that you have already reacted to that touch and that you shouldn't on subsequent updates.

Each touch location has a unique Id field that is maintained for as long as the touch remains active, even across frames. A simple approach would be to maintain a list of all the touch Ids you have already handled, and ignore those touches when performing your update.

// member variable to track handled touches
private List<int> handledTouches = new List<int>();

// modify your update to ignore touches already handled
foreach (TouchLocation location in TouchPanel.GetState())
{
  if(!handledTouches.Contains(location.Id) && shootKeyBounds.Contains((int)location.Position.X, (int)location.Position.Y)
  {
    FireBullet();
    handledTouches.Add(location.Id);
  }
}

Obviously you can improve the performance of this example and could remove touch Ids from the list of those tracked when the TouchLocation state is released, but the basic idea of tracking which touches you have handled and ignoring them on subsequent updates is the same.

You could also limit firing a bullet to the initial touch location by simply checking that the touch state is TouchLocationState.Pressed, which should only be true for the first frame in which the touch is active. I haven't used that method myself.

You must log in to answer this question.

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