| Невозможно пройти тесты, в окне с вопросами пусто |
Акселерометр
Рассмотрим основной игры, листинг 12.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.Sensors;
namespace P6_2
{
/// <summary>
/// Это главный тип игры
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
spriteComp gameObject;
Texture2D texture;
//Показатели акселерометра
Vector3 accVector;
//Акселерометр
Accelerometer accelerometer;
//Блокировка
object accLock = new object();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
//Задаем параметры экрана
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 480;
//Фиксируем положение экрана
graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
//Отображение игрового окна на полный экран, без строки состояния
graphics.IsFullScreen = true;
// Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
TargetElapsedTime = TimeSpan.FromTicks(333333);
// Дополнительный заряд аккумулятора заблокирован.
InactiveSleepTime = TimeSpan.FromSeconds(1);
}
/// <summary>
/// Позволяет игре выполнить инициализацию, необходимую перед запуском.
/// Здесь можно запросить нужные службы и загрузить неграфический
/// контент. Вызов base.Initialize приведет к перебору всех компонентов и
/// их инициализации.
/// </summary>
protected override void Initialize()
{
accelerometer = new Accelerometer();
accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(20);
accelerometer.CurrentValueChanged += new EventHandler<SensorReadingEventArgs
<AccelerometerReading>>(accelerometer_CurrentValueChanged);
try
{
accelerometer.Start();
}
catch
{
}
base.Initialize();
}
void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
lock (accLock)
{
accVector = e.SensorReading.Acceleration;
}
}
///// <summary>
/// LoadContent будет вызываться в игре один раз; здесь загружается
/// весь контент.
/// </summary>
protected override void LoadContent()
{
// Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
spriteBatch = new SpriteBatch(GraphicsDevice);
Services.AddService(typeof(SpriteBatch), spriteBatch);
texture = Content.Load<Texture2D>("BallandBats");
CreateNewObject();
}
protected void CreateNewObject()
{
gameObject = new spriteComp(this, ref texture,
new Rectangle(18, 9, 17, 88), new Vector2(100, 150));
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();
lock (accLock)
{
gameObject.Move(new Vector2(-accVector.Y, -accVector.X));
}
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();
}
}
}
Листинг
12.3.
Код класса Game1
Этот код похож на тот, который мы рассматривали в предыдущем примере. Здесь мы, однако, внесли некоторые изменения. Так, в конструкторе класса мы, используя команды graphics.PreferredBackBufferWidth = 800 и graphics.PreferredBackBufferHeight = 480 в явном виде задали ширину и высоту игрового экрана, кроме того, мы зафиксировали положение экрана в левосторонней ландшафтной ориентации командой graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft. Результат этой команды заключается в том, что при повороте экрана не меняется автоматически его ориентация.
Код работы с акселерометром в данном примере тот же, что и в предыдущем. Главная разница заключается в том, что в методе Update мы вызываем метод Move() игрового объекта и передаем ему последние измеренные значения по осям X и Y, полученные с акселерометра.
На рис. 12.6 вы можете видеть результат запуска программы в эмуляторе.
12.4. Выводы
В этой лабораторной работе была рассмотрена методика получения и обработки показаний акселерометра, который является одним из обязательных сенсоров, присутствующих в устройствах, работающих под управлением Windows Phone.
12.5. Задание
Реализуйте управление экранным объектом с использованием акселерометра. Если у вас есть устройство под управлением Windows Phone, изучите на практике поведение показаний акселерометра при различных положениях устройства в пространстве и перемещениях.
