С чего начать? · Главная · Новости · Скачать · Форум · Мини-Чат · FAQ
Навигация по сайту
Сайт:
Новости:
Скачать:
Дополнительно:
Форум:

Категории раздела
Игры пользователей [61]
Программирование [10]
Литература по созданию игр [18]

Лучшие пользователи
20-ка лучших пользователей:

1 Scorpio
2 PaintKiller
3 MrWolf_
4 DraggonFantasy
5 _JOKER_
6 kiber01
7 TASKET
8 Hagrael
9 Zombi12345
10 Деструктор
11 naruto08
12 Double_Nine
13 Gründer
14 dyatel
15 KpoJIuk
16 g2_
17 TonyStark
18 Stark
19 MrIncrof
20 r_bit

Ссылкообмен
ZiPGames&MGroup
Школа создания онлайн игр
Кольмаристые игры :3
Создание игр, разработка игр, игровые движки, конструкторы игр

 Главная » Скачать » Остальное » Литература по созданию игр » Создание арканойда шаг за шагом в XNA Game Studio

Создание арканойда шаг за шагом в XNA Game Studio
В этом небольшом уроке я покажу вам, как просто создавать игры на XNA Game Studio, итак приступим (Исходники можно скачать тут). Итак, что же такое Microsoft XNA?

Microsoft XNA это набор инструментов и библиотека для разработки мультиплатформенных 2D и 3D игр в управляемой среде Microsoft Managed Runtime Environment. Поддерживаются платформы Windows, Microsoft Xbox 360 и Microsoft Zune. Теоретически писать можно на любом .Net языке, в любой IDE, но оффициально поддерживаются только C# и XNA Game Studio Express и все версии Visual Studio 2005 и выше. XNA также дает возможность портировать игры на поддерживаемые платформы с минимальными изменениями.

Создание проекта

Создадим новый проект – XNA Game Studio 3.1 – Windows Game (3.1)

Мастер создаст скелет игры:

Самый большой интерес для нас представляет файл Game1.cs, в котором определен класс Game1, наследованный от Microsoft.Xna.Framework.Game, где мы и будем разрабатывать нашу игру.
В классе Game1 переопределены следующие методы Game:

void Initialize() – Вызывается единожды, для инициализации ресурсов до начала игры
void LoadContent() – Вызывается единожды, используется для загрузки контента (спрайты и т.д.)
void UnloadContent() – Вызывается единожды, используется для выгрузки контента
void Update(GameTime gameTime) – В этом методе реализуется собственно логика игры, обработка коллизий, обработка событий клавиатуры или джойстика, проигрывание аудио и т.д.
void Draw(GameTime gameTime) – Вызывается для прорисовки игрового поля.

На данный момент скомпилированная игра выглядит вот так

Добавление контента

Добавим игровые ресурсы, в данном случае картинки фона кирпича, ракетки и мячика – Content (Right Click) -> Add -> Existing Item…

Обратите внимание на свойство Asset Name, его мы используем для создания обьекта Texture2D необходимого для дальнейшей анимации.

Рисуем фон игрового поля

Загрузим изображение для фона игрового поля:

Code

private Rectangle _viewPortRectangle; // Границы игрового поля
private Texture2D _background; // Фон игрового поля
   
protected override void LoadContent()
{
  <... skip ...>
  // Границы игрового поля
  _viewPortRectangle = new Rectangle(0, 0,
  graphics.GraphicsDevice.Viewport.Width,
  graphics.GraphicsDevice.Viewport.Height);
   
  _background = Content.Load<Texture2D>(@"background");
  <... skip ...>
}

Отрисовка фона
Code

protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.Clear(Color.CornflowerBlue);
   
  spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
   
  // Рисуем фон
  spriteBatch.Draw(_background, _viewPortRectangle, Color.White);
   
  spriteBatch.End();
   
  base.Draw(gameTime);
}

Метод SpriteBatch.Begin подготавливает графическое устройство к отрисовке спрайтов, SpriteBatch.End завершает процесс отрисовки и возвращает устройство к начальному состоянию. Все методы SpriteBatch.Draw должны быть заключены в SpriteBatch.Begin — SpriteBatch.End.

Создание игрового обьекта

Создадим класс GameObject инкапсулирующий любой из наших игровых обьектов:

Code

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
   
namespace Arkanoid
{
  public class GameObject
  {
  public Texture2D Sprite { get; set; } // Спрайт
   
  public Vector2 Position; // Положение
  public Vector2 Velocity; // Скорость
  public int Width { get { return Sprite.Width; } } // Ширина
  public int Height { get { return Sprite.Height; } } // Высота
  public bool IsAlive { get; set; } // Жив ли обьект
  public Rectangle Bounds // Границы обьекта
  {
  get
  {
  return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
  }
  }
   
  // Разворачивание движения по горизонтальной оси
  public void ReflectHorizontal()
  {
  Velocity.Y = -Velocity.Y;
  }
   
  // Разворачивание движения по вертикальной оси
  public void ReflectVertical()
  {
  Velocity.X = -Velocity.X;
  }
   
  public GameObject(Texture2D sprite)
  {
  Sprite = sprite;
  IsAlive = true;
  Position = Vector2.Zero;
  Velocity = Vector2.Zero;
  }
  }
}

Отрисовка и анимация ракетки

Сначала создадим обьект представляющий ракетку и расположим его в середине игрового поля чуть повыше от его нижнего края

Code

private GameObject _paddle; // Ракетка
   
protected override void LoadContent()
{
  <... skip ...>
   
  // Создание ракетки, начальное положение в середине игрового поля, повыше нижнего края
  _paddle = new GameObject(Content.Load<Texture2D>(@"paddle"));
  _paddle.Position = new Vector2((_viewPortRectangle.Width - _paddle.Width) / 2,
  _viewPortRectangle.Height - _paddle.Height - 20);
   
  <... skip ...>
}

Отрисовка ракетки на экране
Code

protected override void Draw(GameTime gameTime)
{
  <... skip ...>
   
  spriteBatch.Draw(_paddle.Sprite, _paddle.Position, Color.White);
   
  <... skip ...>
}

На данном этапе, если скомпилировать приложение, получим что-то вроде этого:

Неплхо было бы заставить реагировать ракетку на нажатие клавиш, для этого добавим в метод Update следующий код
Code

protected override void Update(GameTime gameTime)
{
  <... skip ...>
   
  KeyboardState keyboardState = Keyboard.GetState();
   
  // Двигаем ракетку вправо
  if (keyboardState.IsKeyDown(Keys.Right))
  _paddle.Position.X += 6f;
   
  // Двигаем ракетку влево
  if (keyboardState.IsKeyDown(Keys.Left))
  _paddle.Position.X -= 6f;
   
  // Ограничиваем движение ракетки игровым полем
  _paddle.Position.X = MathHelper.Clamp(_paddle.Position.X, 0, _viewPortRectangle.Width - _paddle.Width);
   
  <... skip ...>
}

Отрисовка кирпичей

Создадим массив GameObject представляющий кирпичи которые собственно и будем разбивать

Code

private int _brickPaneWidth = 10; // Сколько кипричей рисовать в ширину
private int _brickPaneHeight = 5; // Сколько кипричей рисовать в высоту
private Texture2D _brickSprite; // Спрайт кирпича
private GameObject[,] _bricks; // Массив кирпичей

Добавим следующий код в метод LoadContent()
Code

protected override void LoadContent()
{
  <... skip ...>
   
  // Создание массива кирпичей
  _brickSprite = Content.Load<Texture2D>(@"brick");
  _bricks = new GameObject[_brickPaneWidth,_brickPaneHeight];
   
  for (int i = 0; i < _brickPaneWidth; i++)
  {
  for (int j = 0; j < _brickPaneHeight; j++)
  {
  _bricks[i, j] = new GameObject(_brickSprite)
  {
  Position = new Vector2(i * 55 + 120, j * 25 + 100)
  };
  }
  }
   
  <... skip ...>
}

Отрисовка массива кирпичей, отисовка производится если кирпич “жив”, т.е. не разбит мячем
Code

protected override void Draw(GameTime gameTime)
{
  <... skip ...>
   
  // Рисуем кирпичи
  foreach (var brick in _bricks)
  if (brick.IsAlive)
  spriteBatch.Draw(brick.Sprite, brick.Position, Color.White);
   
  <... skip ...>
}

На данном этапе игровое поле выглядит следующим образом

Отрисовка мячика

Создаем обьект мячика

Code

private GameObject _ball; // Мячик
   
protected override void LoadContent()
{
  <... skip ...>
   
  // Создание мячика, начальное положение в середине на ракетке,
  // начальное направление - вправо, вверх
  _ball = new GameObject(Content.Load<Texture2D>(@"ball"));
  _ball.Position = new Vector2((_viewPortRectangle.Width - _ball.Width) / 2,
  _viewPortRectangle.Height - _paddle.Height - _ball.Height - 20);
  _ball.Velocity = new Vector2(3,-3);
  <... skip ...>
}

Для анимации мячика добавим новый метод UpdateBall(), и его вызов в в метод Update(). Данный метод нам понадобится в дальнейшем для обработки столкновений мячика с кирпичами и ракеткой
Code

private void UpdateBall()
{
  _ball.Position += _ball.Velocity;
}
   
protected override void Update(GameTime gameTime)
{
  <... skip ...>
   
  // Двигаем мячик
  UpdateBall();
   
  <... skip ...>
}

Для отрисовки мячика добавим следующий код в метод Draw()
Code

protected override void Draw(GameTime gameTime)
{
  <... skip ...>
   
  // Рисуем мячик
  spriteBatch.Draw(_ball.Sprite, _ball.Position, Color.White);
   
  <... skip ...>
}

На данный момент, мы имеем почти полностью готовое игровое поле, но без обработки столкновений мячик сразу же вылетает за пределы игрового поля. Добавим обработку столкновений мячика с игровым полем, кирпичами и ракеткой

Обработка столкновений

Создадим новый метод определяющий место столкновения обьектов и меняющий направление полета мяча.

Code

// Определение стороны столкновения и отражение направления полета мячика
public void Collide(GameObject gameObject, Rectangle rect2)
{
   
  // Обьект столкнулся сверху или снизу, отражаем направление полета по горизонтали
  if (rect2.Left <= gameObject.Bounds.Center.X && gameObject.Bounds.Center.X <= rect2.Right)
  gameObject.ReflectHorizontal();
   
  // Обьект столкнулся слева или справа, отражаем направление полета по вертикали
  else if (rect2.Top <= gameObject.Bounds.Center.Y && gameObject.Bounds.Center.Y <= rect2.Bottom)
  gameObject.ReflectVertical();
}

Добавим следующий код в метод UpdateBall()
Code

private void UpdateBall()
{
  // Будущее положение мяча, нужно для предотвращения "залипания" мяча на поверхности обьекта
  Rectangle nextRect = new Rectangle((int)(_ball.Position.X + _ball.Velocity.X),
  (int)(_ball.Position.Y + _ball.Velocity.Y),
  _ball.Width, _ball.Height);
   
  // Столкновение с верхним краем игрового поля
  if (nextRect.Y <= 0)
  _ball.ReflectHorizontal();
   
  // При сталкивании мяча с нижним краем игрового поля, мячик "умирает"
  if (nextRect.Y >= _viewPortRectangle.Height - nextRect.Height)
  {
  _ball.IsAlive = false;
  }
   
  // Столкновение мячика с левым или правым краем игрового поля
  if ((nextRect.X >= _viewPortRectangle.Width - nextRect.Width) || nextRect.X <= 0)
  {
  _ball.ReflectVertical();
  }
   
  // Столкновение мячика с ракеткой
  if (nextRect.Intersects(_paddle.Bounds))
  Collide(_ball, _paddle.Bounds);
   
  // Столкновение мячика с кирпичами
  foreach (var brick in _bricks)
  {
  if (nextRect.Intersects(brick.Bounds) && brick.IsAlive)
  {
  brick.IsAlive = false;
  Collide(_ball, brick.Bounds);
  }
  }
   
  _ball.Position += _ball.Velocity;
}

Итак, что получилось

Конечно физика в игре, мягко говоря, никакая, мячик иногда залипает при столкновении с движущейся ракеткой. Но, повторюсь, смысл данной статьи знакомство со средой Microsoft XNA Game Studio, и, надо сказать, она отлично справляется с рутиной, освобождая время разработчика для фокусировки внимания на логике игры.
Категория: Литература по созданию игр | Добавил: MrIncrof
Просмотров: 1035 | Загрузок: 0 | Комментарии: 1 | Рейтинг: 3.0/2 |
Всего комментариев: 1
0  
1 KHABA   (02.03.2011 17:16)
СПС biggrin biggrin biggrin biggrin biggrin biggrin smile smile smile smile smile smile surprised surprised surprised

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Поиск по сайту:

Поиск по модулю:

Панель пользователя
Здравствуйте, Гость


E-mail:
Пароль:

Ваш IP: 38.107.179.243


Сейчас на сайте
Онлайн всего: 5
Гостей: 5
Пользователей: 0
Сегодня новых: 1

На сайте были
Конструктор , Hagrael , DraggonFantasy , demon_net , АБВ[ZiP] , Filinshein , Кольмар , Темно-Ледяной_Феникс , toxic , blood , Стрелок8369 , Borgius

Помощь
Помощь пользователю Filinshein:

Copyright Make-Games.ru © 2004 - 2012 Создать сайт бесплатно
Рейтинг@Mail.ru Game's TOP-100 Counter Топ100 - Игры