Создание арканойда шаг за шагом в XNA Game Studio - Остальное - Конструкторы игр, системы разработки игр
Навигация по сайту
Сайт:

Дополнительно:

Файловый архив:

Каталог статей:

Форум:


Категории раздела
Game Maker [27]
Flash [3]
FPS Creator X9, X10 [1]
Scirra Construct [14]
Multimedia Fusion [0]
001 Game Maker, Map 001 [0]
3D RAD [16]
3D Game Studio [1]
Silent Walk FPS Creator [0]
Blender (Блендер) [1]
Game Editor [0]
Остальное [1]
Все остальное, что не попадает ни под одну категорию.

Мини-Опрос
Какой ОС Вы пользуетесь?
Всего ответов: 1209

Партнеры сайта
....

 Главная » Статьи » Конструкторы игр, системы разработки игр » Остальное » Создание арканойда шаг за шагом в XNA Game Studio

Создание арканойда шаг за шагом в XNA Game Studio

20:19
В этом небольшом уроке я покажу вам, как просто создавать игры на 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;
}

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


Категория: Остальное | Просмотров: 4371 | Добавил: MrIncrof (08.10.2012) | Рейтинг: 0.0/0
HTML ссылка на материал:
BB ссылка на материал:
Похожие материалы :
Возможно вам будет интересно:
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Поиск по всему сайту:
Поиск по разделу:

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


Ник:
Пароль:
Запомнить :

Ваш IP: 3.15.229.113

Случайные конструкторы

Случайные движки

Случайные статьи

Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0

На сайте были:

При полном или частичном копировании материалов сайта ссылка на Make-Games.ru обязательна. Make-Games.ru © 2008 - 2024 Хостинг от uCoz
Топ Разработка игр