Спонсор: Microsoft
Опубликован: 10.04.2009 | Уровень: специалист | Доступ: платный
Самостоятельная работа 17:

Игровой мир, освещение, тени

Аннотация: В этой лабораторной работе мы познакомимся с методиками создания игрового мира.

Примеры к лабораторной работе

Задачи работы

  • Рассмотреть подходы к созданию игрового мира
  • Научиться использовать в качестве игрового мира готовые модели
  • Ознакомиться с управлением освещением и с выводом теней в трехмерных играх

Подходы к созданию игрового мира

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

  1. Игровой мир можно конструировать из отдельных объектов. Например, для того, чтобы создать комнату, можно использовать плоскости для строительства стен, пола и потолка, различные объекты для создания предметов, находящихся в комнате. При таком подходе для обработки взаимодействия игрового объекта и окружения можно применить уже знакомый вам подход проверки столкновений объектов. Этот подход мы использовали в предыдущих проектах – в примере с передвижением объекта среди группы других объектов, в примере, где нужно было щелкать мышью по объектам для того, чтобы не допустить их падения.
  2. Игровой мир можно сконструировать в трехмерном редакторе – например – ту же комнату, или целое здание, или ландшафт – и загрузить в игру в виде отдельной модели.
  3. Мир можно сконструировать средствами XNA

Рассмотрим работу с игровым миром, который представлен в виде отдельной модели, содержащей все его элементы.

Загрузка игрового мира

В качестве объекта игрового мира, который мы использовали для демонстрации, применен готовый игровой объектHouse – взятый с сайта http://www.turbosquid.com.

Создадим новый игровой проект P17_1. На рис. 22.1. вы можете видеть его окно Project Explorer.

Окно Project Explorer проекта P17_1

Рис. 22.1. Окно Project Explorer проекта P17_1

В качестве игрового объекта мы используем модель 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.

Игровой экран проекта P17_1

увеличить изображение
Рис. 22.2. Игровой экран проекта P17_1
Alina Lasskaja
Alina Lasskaja

Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить.....

Дмитрий Кацман
Дмитрий Кацман
Израиль
Андрей Веденин
Андрей Веденин
Россия, Белгород