Опубликован: 14.08.2012 | Доступ: свободный | Студентов: 881 / 20 | Оценка: 5.00 / 5.00 | Длительность: 09:59:00
Специальности: Программист
Самостоятельная работа 7:

Использование данных о местоположении, другие способы управления

Рассмотрим теперь код основной программы, листинг 13.3.

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;
using Microsoft.Devices;

namespace P7_2
{
    /// <summary>
    /// Это главный тип игры
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        spriteComp gameObject;
        //Для хранения ID касаний
        int gameObjectId;
        //Изображение для вывода
        Texture2D texture;
        //Следует ли перемещать объект
        bool gameObjectMove;
        
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.IsFullScreen = true;
            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
            //Включить обработку жестов - FreeDarag и DoubleTap
            TouchPanel.EnabledGestures = GestureType.FreeDrag | GestureType.DoubleTap;
        }

        /// <summary>
        /// Позволяет игре выполнить инициализацию, необходимую перед запуском.
        /// Здесь можно запросить нужные службы и загрузить неграфический
        /// контент.  Вызов base.Initialize приведет к перебору всех компонентов и
        /// их инициализации.
        /// </summary>
        protected override void Initialize()
        {
            // ЗАДАЧА: добавьте здесь логику инициализации

            base.Initialize();
        }

        /// <summary>
        /// LoadContent будет вызываться в игре один раз; здесь загружается
        /// весь контент.
        /// </summary>
        protected override void LoadContent()
        {
            // Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);
            texture = Content.Load<Texture2D>("rectangle");
            //Создаём игровой объект
            CreateNewObject();
        }

        protected void CreateNewObject()
        {
            gameObject = new spriteComp(this, ref texture,
                new Rectangle(0, 0, 150, 100),
                new Vector2(0, 0));
            Components.Add(gameObject);
        }


        /// <summary>
        /// UnloadContent будет вызываться в игре один раз; здесь выгружается
        /// весь контент.
        /// </summary>
        protected override void UnloadContent()
        {
            // ЗАДАЧА: выгрузите здесь весь контент, не относящийся к ContentManager
        }

        /// <summary>
        /// Позволяет игре запускать логику обновления мира,
        /// проверки столкновений, получения ввода и воспроизведения звуков.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Update(GameTime gameTime)
        {
            // Позволяет выйти из игры
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            //Получаем коллекцию объектов, содержащих информацию о касаниях экрана
            TouchCollection touchLocations = TouchPanel.GetState();
            //Перебираем коллекцию, присваивая объекту координаты касания
            foreach (TouchLocation touchLocation in touchLocations)
            {
                //Если обнаружено касание в области, соответствующей игровому объекту
                if (touchLocation.State == TouchLocationState.Pressed)
                {
                    if (touchLocation.Position.X > gameObject.GetSprPos().X &&
                        touchLocation.Position.X < gameObject.GetSprPos().X + gameObject.GetSprRectangle().Width &&
                        touchLocation.Position.Y > gameObject.GetSprPos().Y &&
                        touchLocation.Position.Y < gameObject.GetSprPos().Y + gameObject.GetSprRectangle().Height)
                    {
                        //Разрешаем перемещать объект
                        gameObjectMove = true;
                        //Запоминаем идентификатор касания
                        gameObjectId = touchLocation.Id;
                        
                    }
                }

                //Если касание окончилось
                if (touchLocation.State == TouchLocationState.Released)
                {
                    //Проверяем ID
                    if (gameObjectId == touchLocation.Id)
                    {
                        //Запрещаем перемещение
                        gameObjectMove = false;
                    }
                }

            }
            //До тех пор, пока разрешена обработка жестов
            while (TouchPanel.IsGestureAvailable)
            {
                //прочитаем жест
                GestureSample gs = TouchPanel.ReadGesture();
                //Если жест - FreeDrag и разрешено перемещение 
                //то есть, пользователь касается объекта на экране
                if (gs.GestureType == GestureType.FreeDrag && gameObjectMove==true)
                {
                    //Начнем перемещать объект со скоростью, заданной параметром Delta
                    //Фактически - чем быстрее был выполнен жест - тем быстрее будет двигаться объект
                    //в направлении жеста
                    gameObject.Move(gs.Delta);
                    
                }
                //Если обнаружен жест двойного касания экрана
                if (gs.GestureType == GestureType.DoubleTap)
                {
                    //Остановим движение объекта
                    gameObject.Move(new Vector2());
                    //Включим вибраацию на 0,1 секунды
                    VibrateController.Default.Start(TimeSpan.FromMilliseconds(100));
                }
         
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// Вызывается, когда игра отрисовывается.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            base.Draw(gameTime);
            spriteBatch.End();
        }
       
    }
}
Листинг 13.3. Код класса Game1

Командой TouchPanel.EnabledGestures = GestureType.FreeDrag | GestureType.DoubleTap; мы включаем обработку жестов и указываем, с какими именно жестами собираемся работать. В нашем случае это FreeDrag и DoubleTap.

Мы хотим реализовать следующий функционал. Когда пользователь касается игровой объект на экране и проводит пальцем по экрану (жест FreeDrag), объект начинает перемещаться в направлении, в котором пользователь провёл пальцем, причем, скорость перемещения объекта задаётся скоростью перемещения пальца. Если пользователь коснётся точки, которая не принадлежит объекту, тот реагировать не будет – за это отвечает код, который, прежде чем разрешить движение объекта, проверяет точку касания.

Для этого используется обычная, уже знакомая вам, обработка касания. Объект в нашем примере напоминает лёгкую пластинку, которая плавает по поверхности прямоугольной ёмкости, наполненной жидкостью. Если пользователь приведет объект в движение – тот будет двигаться с заданными параметрами до тех пор, пока не упрётся в границу экрана. Для того, чтобы остановить движение объекта, мы применяем жест DoubleTap. Этот жест напоминает двойной щелчок мыши. Когда пользователь выполнит этот жест, объект останавливается и на 0,1 секунды включается вибрация телефона.

Мы используем здесь параметр жеста FreeDrag Delta для реализации управления объектом, если, например, использовать координаты касания (они постоянно обновляются при перемещении пальца по экрану), можно организовать управление объектом, подобное перемещению объекта по плоской поверхности, когда его можно "придавить" пальцем и переместить в нужную позицию.

На рис. 13.4 вы можете видеть игровой экран приложения

Игровой экран приложения

Рис. 13.4. Игровой экран приложения

13.3. Другие возможности

В предыдущих практических работах мы разобрали различные способы управления игровым процессом с использованием сенсорной панели, акселерометра, GPS-приёмника. Этими устройствами не ограничиваются возможности по управлению игрой. Так, весьма полезен может быть гироскоп, который регистрирует углы поворота устройства. Можно пользоваться данными, которые поставляет электронный компас.

Кроме того, различные устройства можно комбинировать – именно так поступают разработчики многих современных игр. Например, если речь идёт о симуляторе автогонок Need For Speed Hot Pursuit, управление автомобилем осуществляется с помощью поворотов экрана, дополнительное ускорение можно включить, выполнив жест, судя по всему, являющийся жестом VerticalDrag (проведя пальцем вдоль правой части экрана в ландшафтной ориентации), а задействовать тормоза – коснувшись левой части экрана.

Обилие способов управления игровым процессом даёт огромный простор для творчества. Разрабатывая систему управления игрой, обратите внимание на Combined Motion API (пространство имён Microsoft.Device.Sensors), класс Motion. Это API позволяет получать данные от гироскопа, акселерометра и электронного компаса и предоставляет полезные инструменты для применения этих данных в управлении игровым процессом.

13.4. Выводы

В этой лабораторной работе была рассмотрена методика работы с географическими координатами, методика обработка жестов, работа с виброзвонком, дан обзор дополнительных возможностей по управлению программами с помощью встроенных сенсоров телефона.

13.5. Задание

Реализуйте распознавание различных жестов в XNA-программе, изучите особенности распознавания жестов, посмотрите, распознавание каких видов жестов может накладываться друг на друга, используя отладочные механизмы.

Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто