| Невозможно пройти тесты, в окне с вопросами пусто |
Спрайтовая анимация
17.3. Основа симулятора автогонок
Существует класс двумерных игр, в которых применяется фон со скроллингом. Такой фон позволяет создать имитацию движения объекта. Обычно применяют горизонтальный или вертикальный скроллинг фона. В вертикальном варианте фон перемещается сверху вниз или снизу вверх, имитируя движение в соответствующем направлении. В горизонтальном варианте фон обычно перемещается справа налево, имитируя движение вправо.
Разработаем текстуру, подходящую для фона. В нашем случае это будет полотно дороги, которая и нужна нам для имитации движения. На рис. 17.3 вы можете видеть соответствующее изображение. Мы создали изображение размером 400х600 пикселей – оно будет символизировать дорогу, и соответствующим образом "разметили" его.
Идея скроллинга фона заключается в следующем. Мы будем использовать два игровых объекта, символизирующих фон. Каждый из них в отдельности может выводить спрайт, изображенный на рис. 6.3. Выведем на экран первый объект и будем смещать с необходимой скоростью сверху вниз. Вслед за первым объектом будем смещать сверху вниз второй объект – таким образом, мы получим иллюзию "бегущей" дороги, и неподвижный объект автомобиля, расположенный на этой дороге, будет "двигаться" по ней снизу вверх. Причем, если наделить этот объект возможностью перемещаться – при его перемещении вверх будет создаваться иллюзия ускорения, при перемещении вниз – торможения.
Создадим новый игровой проект, P6_3. Управление спрайтами будет вестись из основной программы, а данные спрайтов будут храниться в отдельных объектах – класс для их хранения будет носить имя sprite.
На рис. 17.4 вы можете видеть окно Обозреватель решений для нашего проекта.
В листинге 17.3 приведен код класса sprite – он хранит данные спрайта.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace P11_3
{
class sprite
{
public Texture2D spTexture;
public Vector2 spPosition;
public sprite(Texture2D newSpTexture, Vector2 newSpPosition)
{
spTexture = newSpTexture;
spPosition = newSpPosition;
}
}
}
Листинг
17.3.
Код класса sprite
В листинге 17.4 приведен код класса Game1, реализующий функциональность по скроллингу фона.
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 P11_3
{
/// <summary>
/// Это главный тип игры
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//объекты для создания скроллингового фона
sprite road1;
sprite road2;
//скорость скроллинга
Vector2 scrolSpeed;
//позиции, на которые устанавливаются обе "дороги"
//в момент начала игры и каждый раз, когда они
//сдвинутся на определенное расстояние
Vector2 road1Start;
Vector2 road2Start;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.IsFullScreen = true;
//Установим параметры заднего буфера, на полный экран
//теперь будет выводить изображение размерами 600х400 пикселей
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 400;
// Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
TargetElapsedTime = TimeSpan.FromTicks(333333);
// Дополнительный заряд аккумулятора заблокирован.
InactiveSleepTime = TimeSpan.FromSeconds(1);
}
/// <summary>
/// Позволяет игре выполнить инициализацию, необходимую перед запуском.
/// Здесь можно запросить нужные службы и загрузить неграфический
/// контент. Вызов base.Initialize приведет к перебору всех компонентов и
/// их инициализации.
/// </summary>
protected override void Initialize()
{
//скорость скроллинга - 5 пикселей по оси Y за один
//проход цикла Update
scrolSpeed = new Vector2(0, 5f);
//первая "дорога" будет изначально установлена в позиции 0,0
//вторая "дорога" - за пределами игрового экрана - в позиции 0,-600
road1Start = new Vector2(0, 0);
road2Start = new Vector2(0, -600);
base.Initialize();
}
/// <summary>
/// LoadContent будет вызываться в игре один раз; здесь загружается
/// весь контент.
/// </summary>
protected override void LoadContent()
{
// Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
spriteBatch = new SpriteBatch(GraphicsDevice);
road1 = new sprite(Content.Load<Texture2D>("road"), road1Start );
road2 = new sprite(Content.Load<Texture2D>("road"), road2Start );
// ЗАДАЧА: используйте здесь this.Content для загрузки контента игры
}
/// <summary>
/// UnloadContent будет вызываться в игре один раз; здесь выгружается
/// весь контент.
/// </summary>
protected override void UnloadContent()
{
road1.spTexture.Dispose();
road2.spTexture.Dispose();
spriteBatch.Dispose();
}
/// <summary>
/// Позволяет игре запускать логику обновления мира,
/// проверки столкновений, получения ввода и воспроизведения звуков.
/// </summary>
/// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
protected override void Update(GameTime gameTime)
{
// Позволяет выйти из игры
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
//если первая "дорога" не спустилась ниже, чем координата 0,600
//то есть все еще видна на экране
//тогда переместить обе "дороги" на дистанцию, задаваемую
//в scrolSpeed
if (road1.spPosition.Y < 600)
{
road1.spPosition += scrolSpeed;
road2.spPosition += scrolSpeed;
}
else
{
//если первая дорога ушла за пределы видимости
//это означает что вторая полностью выведена на экран
//вычислим новую позицию для установки объектов
//для того, чтобы не было скачков при установке
//предварительно вычислим новую позицию
road1Start.Y = road1.spPosition.Y - 600;
road2Start.Y = road2.spPosition.Y - 600;
road1.spPosition = road1Start;
road2.spPosition = road2Start;
}
base.Update(gameTime);
}
/// <summary>
/// Вызывается, когда игра отрисовывается.
/// </summary>
/// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
//выведем первый и второй спрайт на экран
spriteBatch.Draw(road1.spTexture, road1.spPosition, Color.White);
spriteBatch.Draw(road2.spTexture, road2.spPosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Листинг
17.4.
Код класса Game1
На рис. 17.5 вы можете видеть игровой экран.
Теперь рассмотрим горизонтальный скроллинг фона, использующий различные спрайты для создания эффекта ландшафта.


