|
Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить..... |
Игровой мир, освещение, тени
Задачи работы
- Рассмотреть подходы к созданию игрового мира
- Научиться использовать в качестве игрового мира готовые модели
- Ознакомиться с управлением освещением и с выводом теней в трехмерных играх
Подходы к созданию игрового мира
Для создания игрового мира трехмерной игры используют несколько подходов.
- Игровой мир можно конструировать из отдельных объектов. Например, для того, чтобы создать комнату, можно использовать плоскости для строительства стен, пола и потолка, различные объекты для создания предметов, находящихся в комнате. При таком подходе для обработки взаимодействия игрового объекта и окружения можно применить уже знакомый вам подход проверки столкновений объектов. Этот подход мы использовали в предыдущих проектах – в примере с передвижением объекта среди группы других объектов, в примере, где нужно было щелкать мышью по объектам для того, чтобы не допустить их падения.
- Игровой мир можно сконструировать в трехмерном редакторе – например – ту же комнату, или целое здание, или ландшафт – и загрузить в игру в виде отдельной модели.
- Мир можно сконструировать средствами XNA
Рассмотрим работу с игровым миром, который представлен в виде отдельной модели, содержащей все его элементы.
Загрузка игрового мира
В качестве объекта игрового мира, который мы использовали для демонстрации, применен готовый игровой объект – House – взятый с сайта http://www.turbosquid.com.
Создадим новый игровой проект P17_1. На рис. 22.1. вы можете видеть его окно Project Explorer.
В качестве игрового объекта мы используем модель ball.fbx, для построения игрового мира применим модель дома house1.x и плоскость plane.fbx. В этом проекте мы используем уже знакомый вам по предыдущим проектам класс modCls – он применяется для вывода моделей.
В листинге 22.1. вы можете видеть код класса Game1.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace P17_1
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
//Матрицы
Matrix viewMatrix;
Matrix projMatrix;
//Модели
Model ball, house, plane;
// Позиция объекта, поворот
Vector3 avatarPosition = new Vector3(0, 0, -10);
float avatarlRotation;
// Положение камеры
Vector3 cameraReference = new Vector3(0, 0, 10);
Vector3 thirdPersonReference = new Vector3(0, 20, 100);
// Скорости поворота и движения
float rotationSpeed = 1f / 60f;
float forwardSpeed = 10f / 60f;
//Поле зрения камеры
float viewAngle = MathHelper.ToRadians(45.0f);
//Расстояние от камеры до переднего и заднего плана
float nearClip = 1.0f;
float farClip = 2000.0f;
//Объекты
modCls ballObj;
modCls mHouse;
modCls mPlane;
//Соотношение сторон экрана
float aspectRatio;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
//Загрузка моделей
ball = Content.Load<Model>("ball");
house = Content.Load<Model>("house1");
plane = Content.Load<Model>("plane");
aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /
(float)graphics.GraphicsDevice.Viewport.Height;
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
//обновить положение объекта
UpdateAvatarPosition();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
UpdateCameraThirdPerson();
//вывести объекты сцены
DrawScene();
base.Draw(gameTime);
}
//Обновляем состояние объекта
void UpdateAvatarPosition()
{
KeyboardState keyboardState = Keyboard.GetState();
//Поворот влево
if (keyboardState.IsKeyDown(Keys.Left))
{
avatarlRotation += rotationSpeed;
}
//Поворот вправо
if (keyboardState.IsKeyDown(Keys.Right))
{
avatarlRotation -= rotationSpeed;
}
//Движение вперед
if (keyboardState.IsKeyDown(Keys.Up))
{
Matrix forwardMovement = Matrix.CreateRotationY(avatarlRotation);
Vector3 v = new Vector3(0, 0, -forwardSpeed);
v = Vector3.Transform(v, forwardMovement);
avatarPosition.Z += v.Z;
avatarPosition.X += v.X;
}
//Движение назад
if (keyboardState.IsKeyDown(Keys.Down))
{
Matrix forwardMovement = Matrix.CreateRotationY(avatarlRotation);
Vector3 v = new Vector3(0, 0, forwardSpeed);
v = Vector3.Transform(v, forwardMovement);
avatarPosition.Z += v.Z;
avatarPosition.X += v.X;
}
//Движение вверх
if (keyboardState.IsKeyDown(Keys.W))
{
Matrix forwardMovement = Matrix.CreateRotationY(avatarlRotation);
Vector3 v = new Vector3(0, forwardSpeed, 0);
v = Vector3.Transform(v, forwardMovement);
avatarPosition.Y += v.Y;
}
//Движение вниз
if (keyboardState.IsKeyDown(Keys.S))
{
Matrix forwardMovement = Matrix.CreateRotationY(avatarlRotation);
Vector3 v = new Vector3(0, -forwardSpeed, 0);
v = Vector3.Transform(v, forwardMovement);
avatarPosition.Y += v.Y;
}
//Уменьшение угла обзора камеры
if (keyboardState.IsKeyDown(Keys.R))
{
viewAngle -= MathHelper.ToRadians(1.0f);
}
//Увеличение угла обзора камеры
if (keyboardState.IsKeyDown(Keys.F))
{
viewAngle += MathHelper.ToRadians(1.0f);
}
//Если новый угол обзора вышел за дозволенные пределы
//изменяем его
if (viewAngle > MathHelper.ToRadians(180.0f)) viewAngle = MathHelper.ToRadians(179.9f);
if (viewAngle < MathHelper.ToRadians(0.0f)) viewAngle = MathHelper.ToRadians(0.1f);
}
//Обновляем положение камеры при выбранном виде от третьего лица
void UpdateCameraThirdPerson()
{
//Поворот камеры
Matrix rotationMatrix = Matrix.CreateRotationY(avatarlRotation);
// Направление камеры
Vector3 transformedReference = Vector3.Transform(thirdPersonReference, rotationMatrix);
// Позиция камеры
Vector3 cameraPosition = transformedReference + avatarPosition;
//Матрица вида
viewMatrix = Matrix.CreateLookAt(cameraPosition, avatarPosition, new Vector3(0.0f, 1.0f, 0.0f));
//Проецкионная матрица
projMatrix = Matrix.CreatePerspectiveFieldOfView(viewAngle, aspectRatio, nearClip, farClip);
}
//Вывод объектов сцены
void DrawScene()
{
//очистить коллекцию компонентов
Components.Clear();
//Вывести дом
mHouse = new modCls(this, house, graphics);
mHouse .WorldMatrix = Matrix.CreateTranslation(0, 0, -5)*Matrix .CreateScale (5f);
mHouse .ViewMatrix = viewMatrix;
mHouse .ProjectMatrix = projMatrix;
Components .Add (mHouse );
//выведем игровой объект
ballObj = new modCls(this, ball, graphics);
ballObj.WorldMatrix = Matrix.CreateRotationY(avatarlRotation) * Matrix.CreateTranslation(avatarPosition);
ballObj.ViewMatrix = viewMatrix;
ballObj.ProjectMatrix = projMatrix;
Components.Add(ballObj);
//Вывести плоскость
mPlane = new modCls(this, plane, graphics);
mPlane.WorldMatrix = Matrix.CreateScale(700) * Matrix.CreateRotationY(MathHelper.ToRadians(90)) *
Matrix.CreateRotationZ(MathHelper.ToRadians(90)) *
Matrix.CreateTranslation(0, -2, 0);
mPlane.ViewMatrix = viewMatrix;
mPlane.ProjectMatrix = projMatrix;
Components.Add(mPlane);
}
}
}
Листинг
22.1.
Код класса Game1
На рис. 22.2. вы можете видеть игровой экран проекта P17_1.

