Вторник, 16 Октября 2018, 00:46

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [312]
Статьи об общих понятиях связанных с созданием игр.
Программирование [69]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [123]
Статьи о программах для создания игр, уроки и описания.
Софт [27]
Различные программы, в том числе в помощь игроделам.
2D-графика [11]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [10]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [5]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [94]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [69]
Статьи, которые не вошли в определённые разделы.
Наш опрос
Какой ЯП вы знаете?
Всего ответов: 27308
Главная » Статьи » Создание игр

XNA для начинающих: рисование спрайтов, анимация и бег. Часть первая.


Вступительное слово:

Здравствуйте уважаемые пользователи портала GcUp.Ru! В этой статье я расскажу Вам, как нарисовать свой спрайт и сделать для него анимацию в XNA GameStudio, а так же познакомлю Вас с перемещениями спрайтов в двухмерном пространстве. Весь приведенный ниже код проверен, и отлично функционирует в версии 3.1. Но, так же он должен работать и в других версиях (3.0 и 4.0; на счет 2.0 не уверен). Перед знакомством с этим уроком рекомендую прочитать мою первую статью, так как этот урок является ее продолжением, а это значит, что Вам понадобятся те знания, которые Вы получили из первой статьи.

Так же перед прочтением данного урока Вы должны обладать базовыми знаниями языка программирования C#, и иметь программу Microsoft Visual C# Express необходимой Вам версии (для XNA 3.1 - Microsoft Visual C# Express 2008, а для XNA 4.0 - Microsoft Visual C# Express 2010) с установленной библиотекой XNA GameStudio.

Итак, если Вы имеете все вышеприведенное, тогда приступим!

Часть 1. Рисование спрайта.

Немного теории:

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

Т.е., как Вы, наверное, догадались, и принцип рисования спрайтов будет схож с принципом рисования фона. Но, в этой статье мы усовершенствуем отрисовку спрайтов и создадим новый класс.

Но, есть еще один важный момент, который я хотел бы рассмотреть именно в этом разделе статьи. Для каждого спрайта мы будем задавать позицию на экране монитора. Чтобы это сделать, есть два способа (хотя, может, есть и больше, но чаще всего применяются только два). Можно просто указать позицию левого верхнего угла спрайта, а можно нарисовать прямоугольник, который охватит полностью весь спрайт, и задать его координаты. Т.е. получится так, что куда бы прямоугольник ни переместился, спрайт последует за ним.
У каждого из способов есть свои плюсы и минусы. Указывать позицию угла спрайта проще, а указывать прямоугольник более практично. В статье мы поговорим о двух этих способах задания координат. Для начала разберемся с более простым (задание координат угла спрайта) способом, а затем перейдем к способу посложнее (создание прямоугольника).

Итак, приступим!

Создание класса для рисования спрайта:


Для начала давайте создадим новый проект (как это сделать, подробно описывалось в моей предыдущей статье) и назовем его DrawSprite.

Теперь нажмите правой кнопкой на название проекта (в обозревателе решений) и выберите команду: Добавить -> Создать элемент -> Класс:



Давайте назовем его Sprites:



После создания наш класс имеет такой вид:

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DrawSprite
{
  class Sprites
  {
  }
}


Как Вы понимаете, это самый стандартный класс для проекта на языке программирования C#, т.е. пространств имен XNA здесь нет. Так как я их наизусть не помню (да и, наверное, ни один программист их все не запоминает), мы будем добавлять их «по ходу дела». Например, создали мы переменную для текстуры (Texture2D, если кто не помнит), а компилятор сообщает, что не хватает одного пространства имен (так же он пишет его название). Вот тогда-то мы его и добавим.

Итак, теперь давайте вспомним, как же мы добавляли наш фон в игру.

Мы создали переменные для текстур, загрузили сами текстуры в методе LoadContent() и нарисовали их в методе Draw(). Т.е., чтобы создать отдельный класс и в нем нарисовать спрайт (точнее, в нем обработать спрайт, а нарисуем мы его в Game1), нам нужно создать в нем (в нашем новом классе) переменную, создать метод для загрузки текстур (по типу метода LoadContent()) и создать метод для рисования текстур (по типу метода Draw()).

Теперь можно приступать к редактированию нашего нового класса. Как Вы знаете, весь код класса пишется в блоке (между фигурных скобок) класса. Поэтому сразу после:

Code
class Sprites
  {


Запишем:

Code
Texture2D


Как Вы видите, если поставить курсор на «Texture2D», то последний симфол подчеркивается:



В нашем случае это означает, что не хватает простанства имен. Нажмем сочетание клавишь «Alt+Shift+F10» и выберем самое первое. Оно добавиться:



Если все сделали правильно, то вверху экрана появится надпись:

Code
using Microsoft.Xna.Framework.Graphics;


А «Texture2D» изменит свой цвет.

Итак, продолжим. Замените «Texture2D» на:

Code
public Texture2D spriteTexture;


Теперь давайте создадим конструктор. Сейчас он нам не понадобится, оставим его пустым:

Code
public Sprites()
{

}


Переменная создана, конструктор готов. Теперь перейдем к загрузке изображения. Давайте создадим метод LoadContent() сразу после конструктора. В его параметрах нужно записать два объекта. Один объект будет класса ContentManager (кстати, здесь тоже не хватает пространства имен, добавим его), а второй класса String. Первый позволит нам вызвать метод Load, для загрузки изображения, а второй позволит прописать путь к этому изображению. И так, вот как выглядит метод LoadContent():

Code
public void LoadContent(ContentManager Content, String texture)
{
  spriteTexture = Content.Load<Texture2D>(texture);  
}


Как Вы видите, спрайт загружается так же, как и фон. Только, теперь в классе Game1 Вам нужно будет вписать лишь слово Content и путь к текстуре. Остальное уже написано.

Так, теперь перейдем к следующему (и последнему) методу – Draw(). Единственный параметр, который ему нужно передать, это spriteBatch. Теперь остается только нарисовать спрайт известным нам способом (точно так же, как мы рисовали фон). Единственное, здесь не нужно вызывать методы spriteBatch.Begin() и spriteBatch.End(), потому, что чтобы не вызывать эти методы для каждого спрайта отдельно, мы их вызовем один раз (в классе Game1). И так, вот как выглядит наш метод Draw():

Code

public void Draw(SpriteBatch spriteBatch)
{
  spriteBatch.Draw(spriteTexture, , Color.White);
}


Как Вы заметили, второй аргумент (после spriteTexture) мы не записали. Это сделано потому что, координаты мы еще не задали.
И так, теперь переходим к той проблеме, которую я описывал вначале. Сейчас мы будем использовать простой способ, и зададим координаты левого верхнего угла спрайта. Для этого сразу после строки

Code
public Texture2D spriteTexture;


(в самом начале класса)

Запишем «Vector2» и добавим необходимое пространство имен. Так же напишем название позиции:

Code
public Vector2 spritePosition;


И теперь в методе Draw() запишем второй аргумент.

Вот так теперь выглядит метод Draw():

Code
public void Draw(SpriteBatch spriteBatch)
{
  spriteBatch.Draw(spriteTexture, spritePosition, Color.White);
}


А вот так выглядит весь наш класс:

Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

namespace DrawSprite
{
  class Sprites
  {
  public Texture2D spriteTexture;
  public Vector2 spritePosition;
   

  public Sprites()
  {

  }

  public void LoadContent(ContentManager Content, String texture)
  {
  spriteTexture = Content.Load<Texture2D>(texture);
  }

  public void Draw(SpriteBatch spriteBatch)
  {
  spriteBatch.Draw(spriteTexture, spritePosition, Color.White);
  }
  }
}


Редактирование класса Game1:

Итак, теперь давайте отредактируем класс Game1 в соответствии с классом Sprites.

Для начала давайте создадим объект класса Sprites. Назовем его hero.

Code
Sprites hero;


Теперь в конструкторе Game1 инициализируем объект:

Code
hero = new Sprites();


После этого в методе LoadContent() загрузим изображение. Предварительно в папке Content создайте папку Textures и добавьте в нее изображение Вашего героя (все это описывается в моей первой статье) (я назвал его idle). И так, в методе LoadContent() напишем:

Code
hero.LoadContent(Content, "Textures//idle");


Тем самым мы вызвали метод «LoadContent» из класса Sprites и приписывам в него аргументы.

Ну что, мы на «финишной прямой». Осталось перейти в метод Draw() и вызвать там spriteBatch.Begin(), hero.Draw и spriteBatch.End(). Как Вы поняли, hero.Draw мы будем вызывать из класса Sprites, т.е. в него нужно прописать только один аргумент – spriteBatch (остальное прописано в классе Sprites). Вот так выглядит метод Draw() класса Game1:

Code
protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.Clear(Color.CornflowerBlue);

  spriteBatch.Begin();
  hero.Draw(spriteBatch);
  spriteBatch.End();

  // TODO: Add your drawing code here

  base.Draw(gameTime);
}


Теперь давайте запустим игру (F5), и посмотрим, что у нас вышло. У меня получилось такое изображение:



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



То на экране монитора, как я уже говорил, координаты перевернуты, т.е. система координат берет свое начало в левом верхнем углу:



Это значит, что координаты (0, 0) (по X и Y) будут находиться в левом верхнем углу.

Теперь давайте изменим наш код, и запишем свои координаты. Каждое деление координатной шкалы равно одному пикселю. Т.е., если у Вас размер экрана 600x600 пикселей, то точка 300x300 будет серединой Вашего экрана.

Итак, давайте нарисуем наш спрайт в центре экрана. Для начала давайте изменим размеры игрового окна (это подробно описанно в моей первой статье). Для этого в конструктор класса Game1 впишем:

Code
graphics.PreferredBackBufferHeight = 600; //Ширина экрана
graphics.PreferredBackBufferWidth = 600; //Высота экрана


 Все, теперь мы можем задавать координаты. В методе Initialize() введите:
Code
hero.spritePosition = new Vector2(300, 300);


Тем самым мы инициализировали объект spritePosition и присвоили его координатам значения 300 по осям X и Y.

 Теперь давайте запустим игру. У меня получилось так: 



Как Вы видите, спрайт нарисован не совсем в центре экрана, но можете быть уверены, что его левый верхний угол (здесь он прозрачен) нарисован ровно в центре. Таким образом можно поэксперементировать и создать героя ровно в центре игрового окна. И так, на этом я завершу эту часть статьи. В следующей части мы с Вами разберемся, как создать анимацию своему спрайту.
Категория: Создание игр | Добавил: Stalker_Shooter (06 Августа 2011) | Автор: Максим
Просмотров: 20366 | Комментарии: 17 | Рейтинг: 4.6/10 |
Теги: 2d, Vector2, C#, Программирование, пространства имен, Позиция, Класс, XNA Game Studio, координаты, спрайт
Дополнительные опции:
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

Игровые объявления и предложения:
Если вас заинтересовал материал «XNA для начинающих: рисование спрайтов, анимация и бег. Часть первая.», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

Всего комментариев: 17
+0-
14 Grievous   (27 Ноября 2012 22:51)
GrievousУ меня возникла проблема.
Когда я пытаюсь загрузить текстуру врага мне подчеркивает эту строку:
spriteTexture = Content.Load<Texture2D>(texture);
И пишет, что файл не найден.
Что делать? cry

+0-
15 Stalker_Shooter   (28 Ноября 2012 15:30)
Stalker_ShooterЗначит Вы либо указали неправильно имя/расположение файла в методе LoadContent (класса Game1), либо Ваш файл действительно отсутствует в проекте...

+0-
16 Grievous   (29 Ноября 2012 19:03)
GrievousЯ уже перепроверял... Имя правильно, файл существует, а оно все равно не работает.(

+0-
17 Grievous   (02 Декабря 2012 18:37)
GrievousЯ нашел проблему.
Просто не заходит в папку с текстурами. Переместил все в папку с кодом- работает. Немного не аккуратно, но... biggrin

+0-
12 kepa_15   (11 Ноября 2012 18:26)
kepa_15Вот только,когда начал реализовывать ее на компьютере,то у меня выбивает 3 ошибки..

+0-
13 Stalker_Shooter   (12 Ноября 2012 15:15)
Stalker_ShooterОтветил в ЛС.

+0-
11 kepa_15   (11 Ноября 2012 18:25)
kepa_15Статья очень хорошая)

+0-
10 kepa_15   (11 Ноября 2012 18:12)
kepa_15Хорошая статья,только когда начал реализовывать ее на своем компьютере,возникло 3 ошибки...((

+1-
8 JustLee   (09 Августа 2011 18:02)
JustLeeнемного еще непонятно мне с кодами, учусь, а так Статья Класс =)

+0-
9 Stalker_Shooter   (10 Августа 2011 11:21)
Stalker_ShooterБлагодарю! Если не понятно что-то с кодом классов XNA(описанных в статьях), то нашишите мне в ЛС. Все расскажу и покажу happy . Если же у Вас проблемы с C# в целом, тогда Вам поможет только хороший учебник!

+3-
3 nilrem   (08 Августа 2011 07:37)
nilremИ так статья.
И так читал.
Итак ниче так, только и так.
Итак?

+0-
4 Stalker_Shooter   (08 Августа 2011 09:54)
Stalker_ShooterИзвините, немного не понял намека...

+1-
5 nilrem   (08 Августа 2011 10:48)
nilremПосчитай количество словосочетаний "и так" wacko в своих статьях, и сделай так, чтоб их было раз в 10 меньше.

+0-
6 Stalker_Shooter   (08 Августа 2011 11:24)
Stalker_ShooterА, ну да. Извнияюсь, привычка такая... Благодарю за то, что указали на ошибку. В будущем постараюсь ее не повторить!

+0-
7 Stalker_Shooter   (08 Августа 2011 11:28)
Stalker_ShooterА ошибку "И_так" я исправил. Оно и вправду вместе пишется. Больше такого не повторится!

+3-
1 Amri   (07 Августа 2011 15:41)
AmriОтличная статья!

+4-
2 Stalker_Shooter   (07 Августа 2011 17:00)
Stalker_ShooterБлагодарю за отзыв! happy

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск по сайту
10 случ. движков
  • RuneSword
  • Vizard
  • O.H.R.RPG.C.E
  • Quest 3D
  • Neobook
  • RPG Maker MV
  • Android FPS Maker
  • Golden T Game Engine
  • Ren'Py
  • ezRPG
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    Все права сохранены. GcUp.ru © 2008-2018 Рейтинг