123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- #region File Description
- //-----------------------------------------------------------------------------
- // Game1.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #endregion
- #region Using Statements
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Input.Touch;
- #endregion
- namespace TouchGestureSample
- {
- public class Game1 : Microsoft.Xna.Framework.Game
- {
- private GraphicsDeviceManager graphics;
- private SpriteBatch spriteBatch;
- private SpriteFont font;
- private Texture2D cat;
- // the text we display on screen, created here to make our Draw method cleaner
- private const string helpText =
- "Hold (in empty space) - Create sprite\n" +
- "Hold (on sprite) - Remove sprite\n" +
- "Tap - Change sprite color\n" +
- "Drag - Move sprite\n" +
- "Flick - Throws sprite\n" +
- "Pinch - Scale sprite";
- // a list to hold all of our sprites
- private List<Sprite> sprites = new List<Sprite>();
- // we track our selected sprite so we can drag it around
- private Sprite selectedSprite;
- public Game1()
- {
- graphics = new GraphicsDeviceManager(this);
- graphics.IsFullScreen = true;
- Content.RootDirectory = "Content";
- // Frame rate is 30 fps by default for Windows Phone.
- TargetElapsedTime = TimeSpan.FromTicks(333333);
- }
- protected override void Initialize()
- {
- // enable the gestures we care about. you must set EnabledGestures before
- // you can use any of the other gesture APIs.
- // we use both Tap and DoubleTap to workaround a bug in the XNA GS 4.0 Beta
- // where some Taps are missed if only Tap is specified.
- TouchPanel.EnabledGestures =
- GestureType.Hold |
- GestureType.Tap |
- GestureType.DoubleTap |
- GestureType.FreeDrag |
- GestureType.Flick |
- GestureType.Pinch;
- base.Initialize();
- }
- protected override void LoadContent()
- {
- spriteBatch = new SpriteBatch(GraphicsDevice);
- cat = Content.Load<Texture2D>("cat");
- font = Content.Load<SpriteFont>("Font");
- }
- protected override void Update(GameTime gameTime)
- {
- // Allows the game to exit
- if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
- this.Exit();
- // handle the touch input
- HandleTouchInput();
- // update all of the sprites
- foreach (Sprite sprite in sprites)
- {
- sprite.Update(gameTime, GraphicsDevice.Viewport.Bounds);
- }
- base.Update(gameTime);
- }
- private void HandleTouchInput()
- {
- // we use raw touch points for selection, since they are more appropriate
- // for that use than gestures. so we need to get that raw touch data.
- TouchCollection touches = TouchPanel.GetState();
- // see if we have a new primary point down. when the first touch
- // goes down, we do hit detection to try and select one of our sprites.
- if (touches.Count > 0 && touches[0].State == TouchLocationState.Pressed)
- {
- // convert the touch position into a Point for hit testing
- Point touchPoint = new Point((int)touches[0].Position.X, (int)touches[0].Position.Y);
- // iterate our sprites to find which sprite is being touched. we iterate backwards
- // since that will cause sprites that are drawn on top to be selected before
- // sprites drawn on the bottom.
- selectedSprite = null;
- for (int i = sprites.Count - 1; i >= 0; i--)
- {
- Sprite sprite = sprites[i];
- if (sprite.HitBounds.Contains(touchPoint))
- {
- selectedSprite = sprite;
- break;
- }
- }
- if (selectedSprite != null)
- {
- // make sure we stop selected sprites
- selectedSprite.Velocity = Vector2.Zero;
- // we also move the sprite to the end of the list so it
- // draws on top of the other sprites
- sprites.Remove(selectedSprite);
- sprites.Add(selectedSprite);
- }
- }
- // next we handle all of the gestures. since we may have multiple gestures available,
- // we use a loop to read in all of the gestures. this is important to make sure the
- // TouchPanel's queue doesn't get backed up with old data
- while (TouchPanel.IsGestureAvailable)
- {
- // read the next gesture from the queue
- GestureSample gesture = TouchPanel.ReadGesture();
- // we can use the type of gesture to determine our behavior
- switch (gesture.GestureType)
- {
- // on taps, we change the color of the selected sprite
- case GestureType.Tap:
- case GestureType.DoubleTap:
- if (selectedSprite != null)
- {
- selectedSprite.ChangeColor();
- }
- break;
- // on holds, if no sprite is selected, we add a new sprite at the
- // hold position and make it our selected sprite. otherwise we
- // remove our selected sprite.
- case GestureType.Hold:
- if (selectedSprite == null)
- {
- // create the new sprite
- selectedSprite = new Sprite(cat);
- selectedSprite.Center = gesture.Position;
- // add it to our list
- sprites.Add(selectedSprite);
- }
- else
- {
- sprites.Remove(selectedSprite);
- selectedSprite = null;
- }
- break;
- // on drags, we just want to move the selected sprite with the drag
- case GestureType.FreeDrag:
- if (selectedSprite != null)
- {
- selectedSprite.Center += gesture.Delta;
- }
- break;
- // on flicks, we want to update the selected sprite's velocity with
- // the flick velocity, which is in pixels per second.
- case GestureType.Flick:
- if (selectedSprite != null)
- {
- selectedSprite.Velocity = gesture.Delta;
- }
- break;
- // on pinches, we want to scale the selected sprite
- case GestureType.Pinch:
- if (selectedSprite != null)
- {
- // get the current and previous locations of the two fingers
- Vector2 a = gesture.Position;
- Vector2 aOld = gesture.Position - gesture.Delta;
- Vector2 b = gesture.Position2;
- Vector2 bOld = gesture.Position2 - gesture.Delta2;
- // figure out the distance between the current and previous locations
- float d = Vector2.Distance(a, b);
- float dOld = Vector2.Distance(aOld, bOld);
- // calculate the difference between the two and use that to alter the scale
- float scaleChange = (d - dOld) * .01f;
- selectedSprite.Scale += scaleChange;
- }
- break;
- }
- }
- // lastly, if there are no raw touch points, we make sure no sprites are selected.
- // this happens after we handle gestures because some gestures like taps and flicks
- // will come in on the same frame as our raw touch points report no touches and we
- // still want to use the selected sprite for those gestures.
- if (touches.Count == 0)
- {
- selectedSprite = null;
- }
- }
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice.Clear(Color.CornflowerBlue);
- spriteBatch.Begin();
- // draw all sprites first
- foreach (Sprite sprite in sprites)
- {
- sprite.Draw(spriteBatch);
- }
- // draw our helper text so users know what they're doing.
- spriteBatch.DrawString(font, helpText, new Vector2(10f, 32f), Color.White);
- spriteBatch.End();
- base.Draw(gameTime);
- }
- }
- }
|