Компьютерная анимация

 

ВВЕДЕНИЕ


Ни для кого не секрет, что видео игры прочно заняли свою позицию в современной индустрии развлечений. Существуют попытки выделить компьютерные игры как отдельную область искусства, наряду с театром, кино и т.п. Разработка игр может оказаться не только увлекательным, но и прибыльным делом, примеров этому предостаточно в истории. Первые примитивные компьютерные и видео игры были разработаны в 1950-х и 1960-х годах. Они работали на таких платформах, как осциллографы, университетские мейнфреймы и компьютеры EDSAC. Самой первой компьютерной игрой стал симулятор ракеты, созданный в 1942 году Томасом Голдсмитом Младшим (англ. Thomas T. Goldsmith Jr.) и Истл Рей Менном (англ. Estle Ray Mann). Позже, в 1952 году, появилась программа "OXO", имитирующая игру "крестики-нолики", созданная А.С. Дугласом как часть его докторской диссертации в Кембриджском Университете. Игра работала на большом университетском компьютере, известном как EDSAC (Electronic Delay Storage Automatic Calculator). В настоящее время, разработка игры - это многомиллионный процесс, в котором задействована целая команда разработчиков, сложные современные технологии и даже маркетинговые ходы.


1. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ


1.1 Особенности 2D графики в компьютерных играх


Система координат.

Двумерная система координат, предназначенная для представления графики в компьютерных играх, перевернута по отношению к обычной декартовой системе координат. Т.е. начало этой системы координат находится в левом верхнем углу экрана. Такая практика, кстати, была введена еще на этапе становления первых «устройств вывода» типа монитор. Положительная ось Х проходит по верхней кромке экрана слева направо, а положительная ось Y - сверху вниз по левой боковой стороне экрана.

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

Ключевым понятием в двухмерной графике является спрайт.

Спрайт - это простое двухмерное изображение, нарисованное в любом графическом редакторе и сохраненное в одном из графических форматов. Отображая на экране монитора спрайт необходимо понимать следующее условие. Любой спрайт - это изображение, которое заключено в прямоугольник, даже если в исходном изображении у Вас нарисован круг. Рисуя спрайт на экране, его начальной точкой отчета всегда будет оставаться верхний левый угол этого самого прямоугольника. Поэтому если Вы определяете, допустим, столкновения между спрайтами, то Вам необходимо знать ширину и высоту изображения, чтобы прибавить эти значения к начальной точке координат спрайта (левый верхний угол). Соответственно середина спрайта будет находиться в половине ширины и высоты графического изображения.

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

Вектора - это структура данных, которая хранит в себе несколько вещественных чисел, логически связанных между собой. В компьютерной графике повсеместно используются три типа векторов - это Vector2, Vector3 и Vector4. Доступ к отдельным компонентам получается через {x, y}, {x, y, z}, {x, y, z, w} соответственно для каждого из векторов. Vector2, например, дает возможность задавать две координаты по осям X и Y для положения в пространстве в 2д играх, а Vector4 позволяет описать любой цвет в формате RGBA (к примеру, красный цвет описывается, как {255, 0, 0, 255}).


.2 Конвейер контента в проектах на XNA


Контент - целый конвейер по обработке содержимого для игры.

Существует множество различных форматов файлов для обозначения, по сути, одних и тех же вещей. Картинки могут иметь расширение jpg или bmp, png или gif. Музыка может храниться в форматах mp3, wav, ogg, а видео в avi, mkv или mp4. И это лишь капля в море возможных форматов. Из всего этого получается, что для обработки каждого из форматов надо знать конкретно его внутреннюю структуру, принцип записи данных в файле. Соответственно и обработка каждого формата должна производиться индивидуально. Однако XNA исправляет ситуацию введением такого понятия, как конвейер содержимого (Content Pipeline). Суть этого механизма заключается в том, что при использовании XNA вы не работаете напрямую с файлами ресурсов (mp3, wav, jpg и т.д.), а работаете с некоторым абстрактными понятиями, типа «текстура», «модель», «музыка». Визуально схему работы с контентом в XNA можно изобразить следующим образом



Рис. 1 - Схема работы с контентом в XNA


1.3 Контент-импортер и контент-процессор


Первым этапом при добавлении содержимого в нашу игру идет контент-импортер. Это специально написанная библиотека, которая «исследует» входной файл и по описанным правилам его обрабатывает - задает структуру, характерную для необходимого в будущем типа (модель, звук). Так же в контент-импортере, путем использования атрибутов, задается имя контент-процессора, который должен будет использоваться для загрузки и обработки уже скомпилированного бинарного (двоичного) файла формата xnb во время работы игры, и расширения исходных файлов, которые будут обрабатываться данным импортером. Выходным файлом мы получим скомпилированный xnb, готовый для использования на следующем этапе - загрузке контента в игре. Тут в дело вступает характерный контент-процессор, имя которого записано прямо внутри самого xnb файла. Файл полностью самодостаточен и, даже будучи бинарным, может быть открыт на любом компьютере с XNA Frameworkом, в отличие от обычных файлов, за распознавание расширений которых отвечает операционная система. Т.е. контент-процессор отвечает за корректное считывание информации из файла контента и приведение его к внутреннему типу -будь то Model, Texture2D, Effect или как-то другой.


1.4 Понятие компонента в XNA и его использование


Особенностью XNA Framework, которую нельзя не упомянуть, являются «игровые компоненты»:

§Microsoft.Xna.Framework.Game Component

§Microsoft.Xna.Framework.Drawable Game Component.

Смысл компонентов состоит в том, чтобы автоматизировать и стандартизировать вызов обновления (Update), отрисовки (Draw), загрузки контента (Load Content) и инициализации логики (Initia lization) для игровых объектов. Т.е. «облегчить» основной класс игры, внеся логику по работе с каждым объектом внутрь самого объекта и при этом сохранить структуру методов, предлагаемых нам шаблоном XNA. В итоге, просто добавив класс, наследник компонента, в коллекцию компонентов игры один раз, мы можем уже не думать о нем.

Первый компонент призван работать с невидимыми, но постоянно обновляемыми объектами, типа сила и направление ветра или логики искусственного интеллекта (ИИ) компьютерных оппонентов, а второй - для объектов, которые еще должны и выводится на экран, к примеру, счетчик FPS (Frame Per Second) или курсор мыши.


1.5 Компьютерная анимация


Слова «анимация» и «мультипликация» означают одно и то же. На «западный манер» будем использовать первый вариант. Слово animation с английского языка можно перевести как оживление или воодушевление. Когда мы видим обычное рисованное изображение, которое, вдруг начинает двигаться и изменяться, то может действительно показаться, что произошло что-то невероятное, и картинка ожила. Но научное мировоззрение не позволяет нам поверить в это; поэтому обратимся к другому, логичному объяснению.

Если множество похожих изображений (рис. 2) быстро сменять друг за другом, то при определенной скорости смены человек будет воспринимать происходящее как плавное движение (или изменение) объекта на рисунке.


Рис. 2. Ряд изображений, при быстрой смене которых может возникнуть эффект анимации


Оптимальная скорость смены для человека равна 24 изображения (или кадра) в секунду. На самом деле в одном кадре может присутствовать несколько изображений (слоев). Кроме того, может быть всего одно изображение, которое в каждом последующем интервале времени (кадре) будет смещаться на небольшую величину (такую простейшую анимацию можно наблюдать, когда создаются спецэффекты в компьютерной презентации).

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

Компьютерная анимация создается с помощью специальных программ. Их достаточно много. Условно можно выделить два или три вида ПО для создания анимации:

1.Программы, позволяющие создавать анимацию из готовых изображений (различные gif-аниматоры, например, Microsoft GIF Animator).

2.Программные среды, позволяющие создавать 2D анимацию (например, Adobe Flash CS4, Synfig).

3.Программные среды, позволяющие создавать 3D анимацию (например, Autodesk 3ds Max, Blender).

Существенное облегчение труда аниматора гарантируют лишь среды из пунктов 2. и 3, т.к. в случае gif-аниматоров используется уже готовое множество изображений. В профессиональных же средах компьютерной анимации художнику не обязательно прорисовывать каждый кадр или аниматору его фиксировать, программа сама «вычислит» переход изображения из одного положения в другое. Это называется твинингом (tweening) - процесс генерации промежуточных кадров между двумя рисунками, создающий впечатление, что первый рисунок постепенно превращается во второй. Рассмотрим, как это делается.

Представим временную шкалу (киноленту) как дорожку, состоящую из отдельных кадров. Допустим, что в кадре №1 объект должен находиться слева, а в кадре №100 - справа. Эти два кадра отмечаются как ключевые для данного объекта. В них он располагается в начале и конце движения (рис. 3). Все остальные кадры - промежуточные - не требуют фиксации объекта - изображение в них создаст компьютерная программа. Она сама вычислит, где и в какой момент должен находиться объект. Понятно, что если мы ходим сделать передвижение объекта по кривой, то и ключевых кадров придется сделать больше (или использовать специальные средства, предоставляемые программой, для создания траектории).


Рис. 3. Положение объекта в 1-ом кадре киноленты (слева) и в 100-ом (справа).


1.6 Специальные эффекты


Спецэффект, специальный эффект (англ. specialeffect, сокр. SPFX, SFX или FX) - технологический приём в кинематографе, на телевидении и в компьютерных играх, применяемый для визуализации сцен, которые не могут быть сняты обычным способом или не существуют в действительности (например, для визуализации сцен сражения космических кораблей в далёком будущем).

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

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

Методы исполнения спецэффектов также применяются при исполнении монтажных переходов между монтажными кадрами, например, распространённый метод вытеснения изображения.

графика компьютерный анимация контент

2. ПРАКТИЧЕСКАЯ ЧАСТЬ


В разработанной игре используется компьютерная 2D анимация. Она предназначена для анимации движения персонажей в 4 направлениях, для реализации этого используется 4 графических файла формата .png, содержащих по 4 кадра, для каждого персонажа. Примеры файлов представлены на рисунках 4 и 5.


Рис. 4 Анимация движения вниз для главного героя


Рис. 5 Анимация движения влево для противника


Для создания анимации сначала необходимо создать самого персонажа. За все действия, связанные с персонажем отвечает класс Actor. Полный листинг этого класса представлен в Приложении А.

За создание персонажа отвечает конструктор класса. В нем находятся переменные, отвечающие за текстуры, ширину и высоту, направление, количество жизней и скорость персонажей.


public Actor(string textureFolder, ContentManager cont, int countFrames, int hp, int speed, Physics gamePhysics)

{.content = cont;.DownWalk = cont.Load<Texture2D>(textureFolder + @"/downMove");.UpWalk = cont.Load<Texture2D>(textureFolder + @"/upMove");.LeftWalk = cont.Load<Texture2D>(textureFolder + @"/leftMove");.RightWalk = cont.Load<Texture2D>(textureFolder + @"/rightMove");

.countFrames = countFrames;= DownWalk.Width / countFrames; // Ширина= DownWalk.Height; // Высота

= Vector2.Zero;= Vector2.Zero;= new Rectangle(0, 0, Width, Height);.hp = hp;.Speed = speed;

this.gamePhysics = gamePhysics;

// Ни с чем не пересекается= Vector4.Zero;

}


За анимацию персонажей отвечает методы heroAnimation(отвечает за перемещение кадров), MoveUp, MoveDown, MoveLeft, MoveRight - отвечают за движение персонажа в 4 направлениях и DrawMotion(отвечает за анимацию персонажа).

void heroAnimation(float elapsedTime) // Перемещение прямоугольника фрейма

{+= elapsedTime; // Смотрим на секундомер(elapsed >= delay) // Если прошло время

{(frame == countFrames - 1)= 0;++; // Меняем фрейм

= 0; // Сбрасываем секундомер

}.X = frame * Width; // Перемещаем прямоугольник фрейма

}

void MoveUp()

{.Y = -1; // Движение вверх.X = 0; // Меняем вид.Y = -1;(StopMove.Z == 0)

{.Y = 0;.Y -= Speed; // Меняем позицию

}

}void MoveDown()

{.Y = 1; // Движение вниз.X = 0; // Меняем вид.Y = 1;(StopMove.Y == 0)

{.Z = 0;.Y += Speed; // Меняем позицию

}

}void MoveLeft()

{.X = -1; // Движение влево.X = -1; // Меняем вид.Y = 0;(StopMove.W == 0)

{.X = 0;.X -= Speed; // Меняем позицию

}

}void MoveRight()

{.X = 1; // Движение вверх.X = 1; // Меняем вид.Y = 0;(StopMove.X == 0)

{.W = 0;.X += Speed; // Меняем позицию

}

}

void DrawMotion(SpriteBatch spriteBatch)

{layer = 0.8f + (Position.Y + Height) / 5400;scale = 1;zeroRec = new Rectangle(0, 0, Width, Height);(Move.Y < 0) // Идет вверх.Draw(UpWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if (Move.Y == 0 && View.Y < 0) // Смотрит вверх.Draw(UpWalk, Position, zeroRec, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);

if (Move.Y > 0) // Идет вниз.Draw(DownWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if ((Move.Y == 0 && View.Y > 0) || (View.X == 0 && View.Y == 0)) // Смотрит вниз.Draw(DownWalk, Position, zeroRec, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, layer);


else if (Move.X > 0) // Если движется вправо

spriteBatch.Draw(RightWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if (Move.X == 0 && View.X > 0) // Смотрит вправо.Draw(RightWalk, Position, zeroRec, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, layer);


else if (Move.X < 0) // Если движется влево

spriteBatch.Draw(LeftWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if (Move.X == 0 && View.X < 0) // Смотрит влево.Draw(LeftWalk, Position, zeroRec, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, layer);(Bullet b in listBullet) // Рисуем пули

{ b.DrawBullet(spriteBatch); }

}


Для создания игрового окна используется класс Game1. Листинг класса представлен в Приложении Б. На рисунке 6 представлено игровое окно.


Рис. 6 Запущенная игра



ЗАКЛЮЧЕНИЕ


Анимация в играх очень важный элемент без которого не обходится ни одна игра. Она отвечает за передвижение персонажей, взаимодействие их с окружающим миром. Также компьютерная анимация (последовательный показ слайд-шоу из заранее подготовленных графических файлов, а также компьютерная имитация движения с помощью изменения и перерисовки формы объектов или показа последовательных изображений с фазами движения, подготовленных заранее или порождаемых во время анимации) может применяться в мультимедийных приложениях (например, энциклопедиях), а также для «оживления» отдельных элементов оформления, например, веб-страниц и рекламы (анимированные баннеры <#"justify">СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ


1.Бубнов А.Е. Компьютерный дизайн. Основы, Мн: Знание, 2008 г.

2.Кричалов А.А. Компьютерный дизайн. Учебное пособие, Мн.: СТУ МГМУ, 2008 г.

.Стоянов П.Г. Работа с цветом и графикой, Мн.: БГУИР, 2008 г.



ПРИЛОЖЕНИЕ A


Класс Actor

System.Collections.Generic;Microsoft.Xna.Framework;Microsoft.Xna.Framework.Content;Microsoft.Xna.Framework.Graphics;Microsoft.Xna.Framework.Input;

Game1

{Actor

{Texture2D DownWalk { get; set; }Texture2D RightWalk { get; set; }Texture2D LeftWalk { get; set; }Texture2D UpWalk { get; set; }

int intersect;

Vector2 Position; // Положение в пространстве

List<Bullet> listBullet = new List<Bullet>(); // Пульки

int countFrames; //Количество кадров анимации


public int Width; // Ширинаint Height; // ВысотаVector2 Move; // Вектор направлениеVector2 View; // Вектор взгляда

int Speed; //скорость

Vector4 StopMove; //Остановление направления

Rectangle sourceRect; //Прямоугольник одного фрейма

float elapsed;float delay = 200f;int frame = 0; //номер фреймаint hp;

content;gamePhysics;

Rectangle zBounds // Z - Границы обьекта

{{ return new Rectangle((int)Position.X, (int)Position.Y, Width, Height); }

}

Rectangle shadow // Границы шага обьекта

{ get { return new Rectangle((int)Position.X, (int)Position.Y + Height / 2, Width, Height / 2); } }

Point pointN

{ get { return new Point(shadow.Center.X, shadow.Top); } }

Point pointS

{ get { return new Point(shadow.Center.X, shadow.Bottom); } }

Point pointW

{ get { return new Point(shadow.Left, shadow.Center.Y); } }

Point pointE

{ get { return new Point(shadow.Right, shadow.Center.Y); } }

Point pointNE

{ get { return new Point(shadow.Right, shadow.Top); } }

Point pointNW

{ get { return new Point(shadow.Left, shadow.Top); } }

Point pointSE

{ get { return new Point(shadow.Right, shadow.Bottom); } }

Point pointSW

{ get { return new Point(shadow.Left, shadow.Bottom); } }

Actor(string textureFolder, ContentManager cont, int countFrames, int hp, int speed, Physics gamePhysics)

{.content = cont;.DownWalk = cont.Load<Texture2D>(textureFolder + @"/downMove");.UpWalk = cont.Load<Texture2D>(textureFolder + @"/upMove");.LeftWalk = cont.Load<Texture2D>(textureFolder + @"/leftMove");.RightWalk = cont.Load<Texture2D>(textureFolder + @"/rightMove");

.countFrames = countFrames;= DownWalk.Width / countFrames; // Ширина= DownWalk.Height; // Высота

= Vector2.Zero;= Vector2.Zero;= new Rectangle(0, 0, Width, Height);.hp = hp;.Speed = speed;.gamePhysics = gamePhysics;

// Ни с чем не пересекается

StopMove = Vector4.Zero;

}


public void heroAnimation(float elapsedTime) // Перемещение прямоугольника фрейма

{

elapsed += elapsedTime; // Смотрим на секундомер

if (elapsed >= delay) // Если прошло время

{(frame == countFrames - 1)= 0;++; // Меняем фрейм

= 0; // Сбрасываем секундомер

}.X = frame * Width; // Перемещаем прямоугольник фрейма

}

void MoveUp()

{.Y = -1; // Движение вверх.X = 0; // Меняем вид.Y = -1;(StopMove.Z == 0)

{.Y = 0;.Y -= Speed; // Меняем позицию

}

}void MoveDown()

{.Y = 1; // Движение вниз.X = 0; // Меняем вид.Y = 1;(StopMove.Y == 0)

{.Z = 0;.Y += Speed; // Меняем позицию

}

}void MoveLeft()

{.X = -1; // Движение влево.X = -1; // Меняем вид.Y = 0;(StopMove.W == 0)

{.X = 0;.X -= Speed; // Меняем позицию

}

}void MoveRight()

{.X = 1; // Движение вверх.X = 1; // Меняем вид.Y = 0;(StopMove.X == 0)

{.W = 0;.X += Speed; // Меняем позицию

}

}

void DrawMotion(SpriteBatch spriteBatch)

{layer = 0.8f + (Position.Y + Height) / 5400;scale = 1;zeroRec = new Rectangle(0, 0, Width, Height);(Move.Y < 0) // Идет вверх.Draw(UpWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if (Move.Y == 0 && View.Y < 0) // Смотрит вверх.Draw(UpWalk, Position, zeroRec, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);

if (Move.Y > 0) // Идет вниз.Draw(DownWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if ((Move.Y == 0 && View.Y > 0) || (View.X == 0 && View.Y == 0)) // Смотрит вниз.Draw(DownWalk, Position, zeroRec, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, layer);

if (Move.X > 0) // Если движется вправо

spriteBatch.Draw(RightWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if (Move.X == 0 && View.X > 0) // Смотрит вправо.Draw(RightWalk, Position, zeroRec, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, layer);

if (Move.X < 0) // Если движется влево

spriteBatch.Draw(LeftWalk, Position, sourceRect, Color.White, 0, Vector2.Zero, scale, SpriteEffects.None, layer);if (Move.X == 0 && View.X < 0) // Смотрит влево.Draw(LeftWalk, Position, zeroRec, Color.White, 0f, Vector2.Zero, scale, SpriteEffects.None, layer);

(Bullet b in listBullet) // Рисуем пули

{ b.DrawBullet(spriteBatch); }

}

void Shoot(List<Bullet> listBullet)

{

// Рисуем пулюnewBullet = new Bullet(content.Load<Texture2D>(@"Textures/fireball"), this); // Устанавливаем текстуруH


// Задаем координаты(View.X == 0 && View.Y == 0).Velocity = new Vector2(0, 7);.Velocity = View * 7f;(View.X > 0)

{.Position.X = Position.X + Width;.Position.Y = Position.Y + Height / 2;

}if (View.X < 0)

{.Position.X = Position.X;.Position.Y = Position.Y + Height / 2;

}if (View.Y > 0 || View.X == View.Y)

{.Position.X = Position.X + Width / 2; ;.Position.Y = Position.Y + Height;

}if (View.Y < 0)

{.Position.X = Position.X + Width / 2;.Position.Y = Position.Y;

}

// Добавляем пульку.Add(newBullet);

}

moveBullet(List<Bullet> listBullet, Decor dekor, List<Actor> listActor)

{(Bullet b in listBullet) // Для каждой пульки

{

b.Position += b.Velocity; // Направление и скорость пули

if (Vector2.Distance(b.Position, Position) > 400).isAlive = false;(gamePhysics.contactBulletDekor(b, dekor)).isAlive = false;.contactBulletActor(b, listActor);

}(int i = 0; i < listBullet.Count; i++)

{(!listBullet[i].isAlive && listBullet[i].isVisible)

{.RemoveAt(i);-;

}

}

}

void hunt(Actor a)

{

}

}

}



ПРИЛОЖЕНИЕ Б


Класс Game1

System;System.Collections.Generic;System.IO;System.Linq;Microsoft.Xna.Framework;Microsoft.Xna.Framework.Audio;Microsoft.Xna.Framework.Content;Microsoft.Xna.Framework.GamerServices;Microsoft.Xna.Framework.Graphics;Microsoft.Xna.Framework.Input;Microsoft.Xna.Framework.Media;

Game1

{

/// <summary>

/// This is the main type for your game

/// </summary>class Game1 : Microsoft.Xna.Framework.Game

{Menu menu;

Physics physics;ContentManager contentManager;

GraphicsDeviceManager graphics;SpriteBatch spriteBatch;Rectangle _viewPortRectangle; // Границы игрового поля

Physics gamePhysics = new Physics();

Actor Hero; // Герой

Field[] level = new Field[5];int currentLevel = 1;

KeyboardState pastKey; //Отпускаемая кнопка

GameState gameState = GameState.Menu;

int[,] Layer;

Texture2D hp;Texture2D hp1;

Game1()

{= new GraphicsDeviceManager(this);.RootDirectory = "Content";.PreferredBackBufferWidth = 1080; // ширина экрана.PreferredBackBufferHeight = 640; // высота экрана

//graphics.IsFullScreen = true;

}


/// <summary>

/// Allows the game to perform any initialization it needs to before starting to run.

/// This is where it can query for any required services and load any non-graphic

/// related content. Calling base.Initialize will enumerate through any components

/// and initialize them as well.

/// </summary>override void Initialize()

{= new Menu();newGame = new MenuItem("Start Game");resumeGame = new MenuItem("Resume Game");exitGame = new MenuItem("Exit");

.Active = false;

.Click += new EventHandler(newGame_Click);.Click += new EventHandler(resumeGame_Click);.Click += new EventHandler(exitGame_Click);

.Items.Add(newGame);.Items.Add(resumeGame);.Items.Add(exitGame);

.Initialize();

}

void exitGame_Click(object sender, EventArgs e)

{.Exit();

}void resumeGame_Click(object sender, EventArgs e)

{= GameState.Game;

}

void newGame_Click(object sender, EventArgs e)

{.Items[1].Active = true;= GameState.Game;= new Actor("Hero", Content, 4, 2, 3, gamePhysics);

(int i = 1; i < 5; i++)

{[i] = new Field(gamePhysics, Hero);[i].LoadField(Content, "level" + i.ToString());

}

}


/// <summary>

/// LoadContent will be called once per game and is the place to load

/// all of your content.

/// </summary>override void LoadContent()

{

// Create a new SpriteBatch, which can be used to draw textures.= new SpriteBatch(GraphicsDevice);

= Content.Load<Texture2D>(@"Textures/hp");= Content.Load<Texture2D>(@"Textures/hp1");


// Границы игрового поля

_viewPortRectangle = new Rectangle(0, 0,.GraphicsDevice.Viewport.Width,.GraphicsDevice.Viewport.Height);

.LoadContent(Content);

}


/// <summary>

/// UnloadContent will be called once per game and is the place to unload

/// all content.

/// </summary>override void UnloadContent()

{

}


/// <summary>

/// Allows the game to run logic such as updating the world,

/// checking for collisions, gathering input, and playing audio.

/// </summary>

/// <param name="gameTime">Provides a snapshot of timing values.</param>override void Update(GameTime gameTime)

{(gameState == GameState.Game)(gameTime);menu.Update();.Update(gameTime);

}void UpdateGameLogic(GameTime gameTime)

{

(level[currentLevel].fieldEmpty() == true)

{.Position.X = MathHelper.Clamp(Hero.Position.X, -Hero.Width,

_viewPortRectangle.Width + Hero.Width);.Position.Y = MathHelper.Clamp(Hero.Position.Y, -Hero.Height,

_viewPortRectangle.Height + Hero.Height);

(currentLevel == 1)

{= 1;

}

/*1-->2



*/(Hero.Position.X > 1080 && currentLevel == 1)

{= 3;.Position.X = 0;

}

/*1-->2



*/(Hero.Position.X < -Hero.Width + 10 && currentLevel == 3)

{= 1;.Position.X = 1080 - Hero.Width;

}

/*1-->2



*/(Hero.Position.Y > 640 && currentLevel == 1)

{= 4;.Position.Y = 0;

}

/*1-->2



*/(Hero.Position.Y < -Hero.Height + 10 && currentLevel == 4)

{= 1;.Position.Y = 640 - Hero.Height;

}

/*1-->2



*/(Hero.Position.X > 1080 && currentLevel == 4)

{= 2;.Position.X = 0;

}

/*1-->2



*/(Hero.Position.X < -Hero.Width + 10 && currentLevel == 2)

{= 4;.Position.X = 1080 - Hero.Width;

}

/*1-->2



*/(Hero.Position.Y > 640 && currentLevel == 3)

{= 2;.Position.Y = 0;

}

/*1-->2



*/(Hero.Position.Y < -Hero.Height + 10 && currentLevel == 2)

{= 3;.Position.Y = 640 - Hero.Height;

}

}

{.Position.X = MathHelper.Clamp(Hero.Position.X, 0, _viewPortRectangle.Width - Hero.Width);.Position.Y = MathHelper.Clamp(Hero.Position.Y, 0, _viewPortRectangle.Height - Hero.Height);

}

[currentLevel].UpdateField(gameTime); //Обновеляем комнату(); //Смотрим движение по клавишам


if (Hero.hp == 0)

gameState = GameState.Menu;

}


/// <summary>

/// This is called when the game should draw itself.

/// </summary>

/// <param name="gameTime">Provides a snapshot of timing values.</param>override void Draw(GameTime gameTime)

{.Clear(Color.Black);

(gameState == GameState.Game)();menu.Draw(spriteBatch);

.Draw(gameTime);

}

void DrawGame()

{.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);[currentLevel].DrawField(spriteBatch); //Рисуем комнату(Hero.hp == 2).Draw(hp, new Vector2(50, 50), null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 1);if (Hero.hp == 1).Draw(hp1, new Vector2(50, 50), null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 1);.End();

}

void control()

{(Keyboard.GetState().IsKeyDown(Keys.Escape))= GameState.Menu;

(Keyboard.GetState().IsKeyUp(Keys.W) || Keyboard.GetState().IsKeyUp(Keys.S)).Move.Y = 0;

(Keyboard.GetState().IsKeyUp(Keys.D) || Keyboard.GetState().IsKeyUp(Keys.A)).Move.X = 0;

(Keyboard.GetState().IsKeyDown(Keys.D)) //Вправо

{.MoveRight();

}

(Keyboard.GetState().IsKeyDown(Keys.A)) //Влево

{.MoveLeft();

}

(Keyboard.GetState().IsKeyDown(Keys.W)) //Вверх

{.MoveUp();

}

(Keyboard.GetState().IsKeyDown(Keys.S)) //Вниз

{.MoveDown();

}

(Keyboard.GetState().IsKeyDown(Keys.E) && pastKey.IsKeyUp(Keys.E)) //W - стрелять.Shoot(Hero.listBullet);

(Keyboard.GetState().IsKeyDown(Keys.Q) && pastKey.IsKeyUp(Keys.Q))

{.hp--;= null;

}

(Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))

{[currentLevel].AddEnemy();

}

= Keyboard.GetState();

}

enum GameState

{,

}

}

}


ВВЕДЕНИЕ Ни для кого не секрет, что видео игры прочно заняли свою позицию в современной индустрии развлечений. Существуют попытки выделить компьютерные и

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ