• Games
  • TMNT
  • Игры
  • Игры
Главная
Всё для геймера: Обзоры игр, Игровые новости, Читы, Советы и пр.
Всё о компьютерных и консольных играх.
Приветствую Вас Гость
Меню геймера
Разделы каталога
Общие игровые статьи [177]
Игровая аналитика, обзоры серий игр с разных платформ, анализ игр, игровой индустрии и т.д.
Онлайн игры [244]
Статьи и обзоры онлайновых клиентских и браузерных игр
Флэш игры/Flash [11]
2D/3D игры любого жанра на технологии Adobe Flash для игры в плеере или в браузере.
Браузерные онлайн-игры [72]
Браузере игры разных жанров и типов, индивидуальные, а также для социальных сетей и пр.
Разработка игр [103]
Создание игр, программирование, игровые движки, Языки программирования
Моддинг [8]
Модификация игр, перевод, локализация, русификация, ромхакинг
Эмуляция [7]
Эмуляторы и эмуляция компьютеров, консолей, игровых автоматов и прочих систем
Игровые фанфики [2]
Художественная игровая литература, творчество поклонников игр, игровых систем и платформ.
Настольные игры и игрушки [32]
Настольные игры, карточные игры, игрушки и сувениры
Опрос геймеров
Сколько часов в сутки вы играете в игры?
Всего ответов: 17132
Главная » Статьи » Игровые статьи » Разработка игр

Формируем трехмерную сцену [Xbox 360]
Формируем трехмерную сцену

Способов создания полноценных трехмерных сцен очень много. Выбор того или иного способа целиком зависит от игровых задач. В игре «Футбольный стрелок» наша камера статична и находится в одном положении, поэтому для организации сцены был выбран механизм загрузки в игру модели стадиона. Суть этого способа заключается в том, чтобы загрузить в игру модель стадиона и установить камеру под определенным углом, а затем на фоне стадиона развернуть все игровые действия.
Для текущего примера был создан новый проект под названием Plane, который находится на компакт-диске в папке Code\Chapter20\Plane. Начиная с раздела 20.1, мы приступим к его изучению. Дополнительно в папке Code\Chapter20\ имеется еще один проект под названием PlaneMove. В нашей игре нет необходимости перемещаться по полю стадиона, но показать вам, как этот это делается, нужно обязательно. После изучения проекта Plane рассмотрите исходный код примера PlaneMove, думается, что этот пример вам обязательно пригодится в своих собственных играх.

20.1. Позиция камеры

Переходим к работе над игрой и начнем с того, что улучшим код по представлению позиции камеры на экране телевизора. В исходный код класса Game1 проекта Plane добавим новую переменную camera.

Vector3 camera = new Vector3(0.0f, 0.0f, 150.0f);

Эта переменная будет задавать одинаковую позицию просмотра сцены для мячей и футбольного стадиона в методе Draw().

// метод Draw()
view = Matrix.CreateLookAt(camera, Vector3.Zero, Vector3.Up);


А также для вычисления позиции прицела.

// метод GetPickRay()
Ray GetPickRay()
{

view = Matrix.CreateLookAt(camera, Vector3.Zero, Vector3.Up);

}


Таким образом, мы создаем одну переменную и упрощаем возможность обоюдного изменения точки просмотра сцены в двух и более местах исходного кода. Сама точка просмотра трехмерной сцены удаляется на 150 пикселей от центра экрана.
Предложенные значения точки просмотра сцены взяты не с неба, эти значения были сначала опробованы на загружаемой в игру модели стадиона, и только потом был выбран наиболее выгодный ракурс. В этом плане бесплатные модели имеют свою обратную сторону медали. Здесь уже приходится подстраиваться под имеющийся графический контент, вместо того чтобы модельер, делающий модели, подстраивался под ваши требования…

20.2. Загружаем в игру стадион

Переходим к загрузке модели стадиона в игру. В качестве основной игровой модели для формирования сцены в игре мы используем модель стадиона, которая была найдена в закромах ресурса Turbosquid.com (рис. 20.1). Эта модель распространяется на бесплатной основе в формате 3ds и создана модельером, зарегистрированным на Turbosquid.com под именем dwallcott (рис. 20.1).
К сожалению, в комплекте со стадионом текстуры не идут, поэтому я покрасил все элементы стадиона просто в разные цвета, но при желании можно использовать любые текстуры, созданные специально для этих целей.
Итак, перейдем к исходному коду класса Game1 проекта Plane и в области глобальных переменных объявим объект stadium класса ModelClass.

Рис. 20.1. Страница модели стадиона на сайте

private ModelClass stadium;

Затем в конструкторе класса Game1 или в методе Initialize() создаем но-
вый объект stadium.

stadium = new ModelClass();

Переходим к телу метода LoadGraphicsContent() и, используя стандарт-
ные механизмы, загружаем в игру модель.

stadium.Load(content, «Content\\Models\\stadium 1»);

В этом же методе выбираем позицию для стадиона на экране телевизора.

stadium.position = new Vector3(0, 0, 0);

Стадион мы ставим на экран в нулевые координаты, а за счет удаления камеры от центра экрана (см. раздел 20.1) получаем хороший ракурс просмотра всей трехмерной сцены.
Последние установки, связанные с выводом стадиона на экран, происходят в методе Draw().

world = Matrix.CreateTranslation(stadium.position);
stadium.DrawModel(world, view, proj);


Здесь все установки стандартны, а значения матрицы вида и матрицы проекции общие как для мячей, так и для стадиона. Если сейчас запустить проект, то на экране телевизора вы увидите стадион и падающие сверху мячики (рис. 20.2), но прежде нам необходимо сделать еще несколько изменений и нововведений, чтобы трехмерная сцена стала ярче и интереснее.

Рис. 20.2. Стадион в игре


20.3. Падение мячей на поле стадиона

Как вы помните, к выбору скоростей в играх нужно подходить взвешенно и осторожно. К слову сказать, в игре «Футбольный стрелок» значение скорости задано жестко, но можно производить выбор скорости объекта на экране непосредственно с созданием этого объекта и далее на каждом уровне игры, внося элемент случайности (в последней главе книги мы так и поступим).
В исходном коде класса Game1 и методе MoveBall()на этой стадии нас ждут небольшие изменения, которые выглядят следующим образом:

void MoveBall()
{
for (int i = 0; ball.Length > i; i++)
{
if (ball[i].position.Y < -32)
{
ball[i].position.Y = ball[i].position.Y;
}
else
{
ball[i].position.Y -= ball[i].speed;
}
}
}


Мячики в игре, падая сверху вниз, должны в определенный промежуток времени коснуться поверхности поля. Определять пересечение поля стадиона и мячей можно по-разному. Самый простой способ – это выбор числового значения (в данном случае по оси Y), достигнув которого мячи просто останавливаются.

if (ball[i].position.Y < -32)
{
ball[i].position.Y = ball[i].position.Y;
}


Целочисленное значение –32 пикселя по оси Y совпадает с поверхностью футбольного поля. Когда мячики по оси Y достигнут –32 пикселей, то они перестанут двигаться. Такой простой механизм позволяет создать в игре иллюзию остановки мячей на поверхности футбольного поля.

20.4. Небо и тучи

Задний фон за стадионом в игре закрашивается цветом. Сейчас это уже неактуально, и для формирования полноценной сцены необходимо создать небо, тучи и другие элементы пейзажа. Механика представления этих элементов в играх достаточно обширна. Поскольку игра «Футбольный стрелок» имеет статичную камеру и точка просмотра сцены не изменяется, то можно воспользоваться текстурой пейзажа и поставить это изображение за элементами сцены.
В большинстве игр этот механизм используется повсеместно, но если камера в игре двигается, то добавляется более сложный механизм, основанный либо на прокрутке текстуры фона в разных направлениях, либо на использовании кубических текстур для представления небесной оболочки (Sky Box). У нас вся трехмерная сцена попроще, поэтому вполне достаточно простой текстуры с пейзажем, установленной на заднем фоне игры.
Текстура пейзажа была взята с сайта Turbosquid.com. Это графическое изображение в формате JPG распространяется бесплатно. Пейзаж создан художником под именем Hal9000 (рис. 20.3).

Рис. 20.3. Страница изображения hallake001

Графическое изображение этого пейзажа оказалось очень большим по ширине (3000 пикселей), поэтому пришлось обрезать его по бокам, укоротив изображение по ширине до 1500 пикселей.
Для добавления фона в игру объявим новую переменную background.

private Texture2D background;

Изображение фона статично, поэтому можно обойтись и без объекта класса Sprite. После объявления объекта background в методе LoadGraphicsContent() загружаем пейзаж в игру.

background = content.Load(«Content\\Textures\\hallake001»);

А затем в методе Draw() рисуем его на экране телевизора.

spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(background, new Vector2(0, -50), Color.White);
spriteBatch.End();


При этом само изображение фона мы рисуем самым первым, не забывайте, что
каждый последующий рисуемый элемент графики всегда накладывается поверх предыдущего!
Изображение hallake001 по высоте равно 500 пикселям. По оси Y мы сместили изображение вверх на 50 пикселей. Сделано это просто для красоты. То есть после того как изображение было загружено, а игра запущенна на приставке, было подобрано оптимальное местоположение фона, исходя из общей картинки на экране телевизора.
В листинге 20.1 вы найдете полный исходный код текущего примера, где все нововведения выделены жирным шрифтом. Сам проект располагается на компакт-диске в папке Code\Chapter20\Plane.

//=========================================================================
///

/// Листинг 20.1
/// Проект: Plane
/// Класс: Game1
/// Трехмерная сцена
///

//=========================================================================


#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
namespace Plane
{
public class Game1 : Microsoft.Xna.Framework.Game
{
private enum CurentGameState
{

}
CurentGameState gameState = CurentGameState.GameScreen;
GraphicsDeviceManager graphics;
ContentManager content;
int screenWidth, screenHeight;
Matrix view;
Matrix proj;
Matrix world;
static float aspectRatio;
static float FOV = MathHelper.PiOver4;
static float nearClip = 1.0f;
static float farClip = 1000.0f;
private ModelClass[] ball = new ModelClass[3];
Random rand = new Random();
SpriteBatch spriteBatch;
Sprite cursor;
public BoundingSphere[] bb = new BoundingSphere[3];
Vector3 camera = new Vector3(0.0f, 0.0f, 150.0f);
private ModelClass stadium;
private Texture2D background;
///
/// Конструктор
///
public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
screenWidth = graphics.PreferredBackBufferWidth;
screenHeight = graphics.PreferredBackBufferHeight;
for (int i = 0; ball.Length > i; i++)
{
ball[i] = new ModelClass();
}
cursor = new Sprite();
stadium = new ModelClass();
}
///
/// Инициализация
///
protected override void Initialize()
{
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
aspectRatio = (float)screenWidth / (float)screenHeight;
base.Initialize();
}
///
/// Загрузка компонентов игры
///
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
ball[0].Load(content, «Content\\Models\\Soccerball»);
ball[1].Load(content, «Content\\Models\\SoccerballGreen»);
ball[2].Load(content, «Content\\Models\\SoccerballRed»);
for (int i = 0; ball.Length > i; i++)
{
ball[i].position.X = rand.Next(-(rand.Next(0, 60)),
rand.Next(0, 60));
ball[i].position.Y = rand.Next(50, 80);
ball[i].position.Z = -(rand.Next(20, 100));
}
cursor.Load(content, «Content\\Textures\\cursor»);
cursor.spritePosition = new Vector2(400, 300);
stadium.Load(content, «Content\\Models\\stadium 1»);
stadium.position = new Vector3(0, 0, 0);
background = content.Load(«Content\\Textures\\hallake001»);
}
}
///
/// Освобождаем ресурсы
///
protected override void UnloadGraphicsContent(bool unloadAllContent)
{

}
///
/// Обновляем состояние игры
///
protected override void Update(GameTime gameTime)
{

}
///
/// Рисуем на экране
///
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(new Color(159, 147, 207));
switch (gameState)
{
case CurentGameState.SplashScreen:
{
break;
}
case CurentGameState.MenuScreen:
{
break;
}
case CurentGameState.AboutScreen:
{
break;
}
case CurentGameState.GameScreen:
{
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(background, new Vector2(0, -50), Color.White);
spriteBatch.End();
graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;
view = Matrix.CreateLookAt(camera, Vector3.Zero, Vector3.Up);
proj = Matrix.CreatePerspectiveFieldOfView(FOV, aspectRatio,
nearClip, farClip);
for (int i = 0; ball.Length > i; i++)
{
world = Matrix.CreateTranslation(ball[i].position);
ball[i].DrawModel(world, view, proj);
}
world = Matrix.CreateTranslation(stadium.position);
stadium.DrawModel(world, view, proj);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
cursor.DrawSprite(spriteBatch);
spriteBatch.End();
break;
}
case CurentGameState.GameOverScreen:
{
break;
}
case CurentGameState.VictoryScreen:
{
break;
}
}
base.Draw(gameTime);
}
///
/// Движение мячей
///
void MoveBall()
{
for (int i = 0; ball.Length > i; i++)
{
if (ball[i].position.Y < -32)
{
ball[i].position.Y = ball[i].position.Y;
}
else
{
ball[i].position.Y -= ball[i].speed;
}
}
}
///
/// Прицел
///
void GamePadClick()
{

}
///
/// Преобразовываем координаты
///
Ray GetPickRay()
{

}
}
}

<< Назад
Категория: Разработка игр | Добавил: G-GURU (19.10.2011)
Просмотров: 2845 | Рейтинг: 5.0/1 |
Вы можете отправить сообщение на e-mail друга:

Интересное геймерам:

Смотрите другие материалы по темам: Xbox 360, Разработка игр, GameDev, Формируем сцену, Xbox, 3D.

Также вам предлагаются схожие с «Формируем трехмерную сцену [Xbox 360]» материалы:

Если понравился материал «Формируем трехмерную сцену [Xbox 360]» и вы можете обсудить его ниже.

Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск информации
Игровые братья
Создание игр, Конструкторы игр, Игровые движки Перевод консольных игр Разработка игр в СНГ Пранк - телефонные шутки
10 новых описаний
Satan Claus [SMD]
Покупка купонов, игровых валют для Nintendo Switch, Twitch и пр.
Краткий обзор популярной онлайн игры Palworld
Увеличьте доходы от рекламы с помощью оптимизации контента
Для чего вам нужен виртуальный номер телефона
Обзор новой экшен РПГ «Zenless Zone Zero» от miHoYo
Игра «Alien Fish Finger» v1.31 на Amiga
Обзор смартфона Xiaomi 14
Игровая индустрия ориентируется уже на всех
Где покупать и/или продавать свои скины CS2, Dota 2, RUST?
Повысьте качество обслуживания пользователей и прибыль
Решающее значение для сайта - Domain Authority (DA)
Компания MAN-MADE показала компьютер, вдохновленный игрой «Метро 2033»
Почему ПО для колл-центров востребовано компаниями
Сколько стоит предметная съёмка товаров для интернет-магазина
Все права сохранены за сайтом GFAQ.ru © 2024. Games Frequently Asked Questions
Полные прохождения, Секреты, Коды, Пароли, Советы, Уловки, Читы, Описания для Компьютерных и Консольных Игр. Хостинг от uCoz
Обращаем особое внимание на то, что при цитировании и размещении данных текстовых материалов, обязательно прикрепляйте ссылку на официальный сайт "GFAQ.ru".