Невозможно пройти тесты, в окне с вопросами пусто |
Акселерометр
12.2. Отладка приложения, использующих акселерометр, в эмуляторе
Запустим программу в эмуляторе, в панели инструментов эмулятора нажмем на кнопку >>, появится окно Дополнительные инструменты, в котором на вкладке Акселерометр можно, перемещая трехмерную модель телефона, моделировать поведение акселерометра. Так, на рис. 12.4 можно видеть эмулятор, моделирующий альбомную ориентацию устройства, расположенного вертикально. Как видите, данные акселерометра представляют собой вектор (-1, 0, 0).
Перемещать трехмерную модель телефона можно с помощью изменения положения красной точки с помощью мыши. Вот, например (рис. 12.5), как в эмуляторе выглядит положение телефона, похожее на то, в котором было сфотографировано устройство на рис. 12.3.
В поле Ориентация в окне Дополнительные инструменты можно выбирать из нескольких предустановленных ориентаций устройства в пространстве.
В поле Записанные данные можно выбрать набор записанных данных Shake, эмулирующих тряску телефона, и, нажав на Воспроизведение, понаблюдать в окне эмулятора за реакцией программы на эти данные. Изображение телефона при воспроизведении данных не перемещается.
Рассмотрим пример, в котором показания акселерометра используются для управления игровым объектом.
12.3. Управление игровым объектом с помощью акселерометра
Сущность данного примера заключается в следующем. Мы получаем показания акселерометра и используем данные по осям X и Y для управления объектом в двумерной системе координат. Мы используем в этом примере уже известный вам по прошлым практическим занятиям игровой компонент с некоторыми изменениями. Рассмотрим основные особенности этого компонента, листинг 12.2.
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.Media; namespace P6_2 { /// <summary> /// Это игровой компонент, реализующий интерфейс IUpdateable. /// </summary> public class spriteComp : Microsoft.Xna.Framework.DrawableGameComponent { //Изображение private Texture2D sprTexture; //Прямоугольник, ограничивающий спрайт private Rectangle sprRectangle; //Координата спрайта private Vector2 sprPosition; //Границы экрана private Rectangle scrBounds; //Направление движения спрайта private Vector2 sprMove = new Vector2(0, 0); public spriteComp(Game game, ref Texture2D newTexture, Rectangle newRectangle, Vector2 newPosition ) : base(game) { sprTexture = newTexture; sprRectangle = newRectangle; sprPosition = newPosition; //Работаем в портретном режиме, высота - 480, ширина - 800 scrBounds = new Rectangle(0, 0, game.Window.ClientBounds.Height, game.Window.ClientBounds.Width ); } /// <summary> /// Позволяет игровому компоненту выполнить необходимую инициализацию перед\r\запуском. Здесь можно запросить нужные службы и загрузить контент. /// /// </summary> public override void Initialize() { // ЗАДАЧА: добавьте здесь код инициализации base.Initialize(); } /// <summary> /// Позволяет игровому компоненту обновиться. /// </summary> /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param> public override void Update(GameTime gameTime) { //Изменение координат в соответствии с данными, имеющимися в sprMove sprPosition.Y = sprPosition.Y + sprMove.Y; sprPosition.X = sprPosition.X + sprMove.X; //Если вышли за пределы экрана - исправляем //и сбрасываем скорость в направлении, в котором //пересекли границу if (sprPosition.X < scrBounds.Left) { sprPosition.X = scrBounds.Left; sprMove.X = 0; } if (sprPosition.X > scrBounds.Width - sprRectangle.Width) { sprPosition.X = scrBounds.Width - sprRectangle.Width; sprMove.X = 0; } if (sprPosition.Y < scrBounds.Top) { sprPosition.Y = scrBounds.Top; sprMove.Y = 0; } if (sprPosition.Y > scrBounds.Height - sprRectangle.Height) { sprPosition.Y = scrBounds.Height - sprRectangle.Height; sprMove.Y = 0; } base.Update(gameTime); } public override void Draw(GameTime gameTime) { SpriteBatch sprBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); sprBatch.Draw(sprTexture, sprPosition, sprRectangle, Color.White); base.Draw(gameTime); } //Метод для установки направления движения спрайта public void Move(Vector2 move) { //Изменяем вектор, задающий направление и скорость движения спрайта sprMove += move; //Ограничиваем скорость 5-ю пикселями if (sprMove.X > 5) { sprMove.X = 5; } if (sprMove.X < -5) { sprMove.X = -5; } if (sprMove.Y > 5) { sprMove.Y = 5; } if (sprMove.Y < -5) { sprMove.Y = -5; } } } }Листинг 12.2. Код игрового компонента
Здесь мы используем для установки двумерного вектора, задающего направление и скорость перемещения спрайта, метод Move. В этот метод передаются данные, полученные с акселерометра. При поступлении новых данных они прибавляются к двумерному вектору sprMove. Положительные значения увеличивают скорость спрайта, отрицательные – уменьшают. После получения новых значений мы проверяем, не превышают ли они 5 (или не меньше ли они -5) и, если это так – сбрасываем до 5 (или до -5) для того, чтобы ограничить скорость движения спрайта 5-ю пикселями за один шаг.
В процедуре Update мы прибавляем к позиции спрайта данные, хранящиеся в sprMove. Кроме того, мы контролируем пересечение объектом границ экрана. Если объект пересек границу, мы возвращаем его к границе и сбрасываем соответствующий показатель вектора sprMove, устанавливая скорость движения спрайта по соответствующей координате равной 0.