Невозможно пройти тесты, в окне с вопросами пусто |
Спрайтовая анимация
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 вы можете видеть игровой экран.
Теперь рассмотрим горизонтальный скроллинг фона, использующий различные спрайты для создания эффекта ландшафта.