Win7 mobile: Sterowanie za pomoca gestow.

0

Hej!

Pisze pierwsza gre na komorke z Win7.

Uzywam XNA.

Chce zrobic sterowanie moim "robocikiem" za pomoca prostych gestow: user przesuwa palcem w jakims kierunku, ja odczytuje ten kierunek.

Ponizszy kod dziala ale jest malo "responsive" i czasem dziala w odwrotnym od zamierzonego kierunku.

Co robie zle?

Pieknie dziekuje!

 
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace Touch_learning
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    /// 

    enum Directions
    {
        left, top, right, bottom, none

    }

    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        GestureSample samplePrev;
        Directions directions;

        Texture2D left;
        Texture2D top;
        Texture2D right;
        Texture2D bottom;
        Rectangle rectangle;
            

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            TouchPanel.EnabledGestures = GestureType.Tap | GestureType.HorizontalDrag | GestureType.VerticalDrag | GestureType.DragComplete;
            rectangle = new Rectangle();

            directions = Directions.none;

            rectangle.X = 100;
            rectangle.Y = 100;

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            left = Content.Load<Texture2D>(@"Textures\robo2");
            top = Content.Load<Texture2D>(@"Textures\robo2");
            right = Content.Load<Texture2D>(@"Textures\robo2");
            bottom = Content.Load<Texture2D>(@"Textures\robo2");

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            //while (TouchPanel.IsGestureAvailable)
            if (TouchPanel.IsGestureAvailable)
            {
                //tu musimy poczekac az user skonczy robic gest

                GestureSample sample = TouchPanel.ReadGesture();

                if (sample.GestureType == GestureType.HorizontalDrag || sample.GestureType == GestureType.VerticalDrag)
                    samplePrev = sample;


                if (sample.GestureType == GestureType.DragComplete)
                {
                    switch (samplePrev.GestureType)
                    {
                        case GestureType.VerticalDrag:
                            if (samplePrev.Delta.Y > 0)
                                directions = Directions.bottom;
                            else
                                directions = Directions.top;

                            break;

                        case GestureType.HorizontalDrag:
                            if (samplePrev.Delta.X > 0)
                                directions = Directions.right;
                            else
                                directions = Directions.left;

                            break;

                    }
                }
            }

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            rectangle.Width = 60;
            rectangle.Height = 60;

            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            switch (directions)
            {
                case Directions.left:
                    rectangle.X -= 15;
                    spriteBatch.Draw(left,rectangle, Color.White); 
                    break;

                case Directions.top:
                    rectangle.Y -= 15;
                    spriteBatch.Draw(top, rectangle, Color.White); 
                    break;

                case Directions.right:
                    rectangle.X += 15;
                    spriteBatch.Draw(right, rectangle, Color.White); 
                    break;

                case Directions.bottom:
                    rectangle.Y += 15;
                    spriteBatch.Draw(bottom, rectangle, Color.White); 
                    break;

                case Directions.none:
                    //tu pozycja sie nie zmienia
                    spriteBatch.Draw(top, rectangle, Color.White);
                    break;

            }

            spriteBatch.End();

            directions = Directions.none;

            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}
0

Obejrzyj sobie ten przykład:
http://go.microsoft.com/fwlink/?LinkId=198870

Nie wiem jak działa twój, ale ten tutaj jest dość dobrze zrobiony.

Zmodyfikuj go, dodając obsługę gestu nie tylko pionowego, ale i poziomego:

w Game1():

            TouchPanel.EnabledGestures =
                GestureType.VerticalDrag | GestureType.Flick | GestureType.HorizontalDrag;

w Update():

                switch (gs.GestureType)
                {
                    case GestureType.VerticalDrag:
                        // move the poem screen vertically by the drag delta
                        // amount.
                        poem.offset.Y -= gs.Delta.Y;
                        break;

                    case GestureType.Flick:
                        // add velocity to the poem screen (only interested in
                        // changes to Y velocity).
                        poem.velocity.Y += gs.Delta.Y;
                        break;

                    case GestureType.HorizontalDrag:
                        poem.offset.X -= gs.Delta.X;
                        break;
                }

Niemniej użycie gestów ma tę wadę, że nie istnieje gest "na skos", więc nie da się w ten sposób odczytać kierunku - trzeba to sobie oprogramować już samemu, ręcznie i bez korzystania z gestów jako takich. Zobacz sobie jeszcze http://msdn.microsoft.com/en-us/library/ff434208.aspx (na samym dole).

I BTW - Windows Phone 7, nie Mobile.

1 użytkowników online, w tym zalogowanych: 0, gości: 1