Создание арканойда шаг за шагом в 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]
Все остальное, что не попадает ни под одну категорию.

Мини-Опрос
Какие языки программирования вы знаете?
Всего ответов: 773

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

 Главная » Статьи » Конструкторы игр, системы разработки игр » Остальное » Создание арканойда шаг за шагом в 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;
}

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


Категория: Остальное | Просмотров: 2330 | Добавил: MrIncrof (08.10.2012) | Рейтинг: 0.0/0
HTML ссылка на материал:
BB ссылка на материал:
Похожие материалы :
Возможно вам будет интересно:
То, что нужно знать всем, кто движется в сфере геймдева. (1)
Borland Assembler (BASM) уроки для начинающих (уроки 1-4) (0)
Задротство - основа MMO игр (7)
Создание наземного врага в платформере (2)
Работа с Сетью в Blitz3D: TCP (0)
Создаем анимацию игрока (0)
PHP - Базовые понятия (0)
Создание рикошета пуль от стены (4)
Инветарь на Game Maker (0)
Урок по PaintNET (1)
Физика (Blitz 3D) (0)
Создание Платформенной Игры Copyright 2001 by Mark Overmars (0)
Уроки по C/C++ (Части с 21 по 40) (0)
Что с чем едят - 3d Rad (0)
Как создать браузерную игру? (0)
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Мы в социальных сетях

Поиск
Поиск по всему сайту:
Поиск по разделу:

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


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

Ваш IP: 54.161.157.73

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

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

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

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

На сайте были:
Конструктор , Filinshein , FireOfSteel , devbond007 , proto1ype , frere , CyberHawk , vicin

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