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

Анимация, эффекты

После вышеописанной подготовки всё готово к реализации примера, его код приведен в листинге 27.2

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace P20_2
{
    /// <summary>
    /// Это главный тип игры
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        //Для вывода двумерных изображений
        SpriteBatch spriteBatch;
        //Трёхмерная модель
        Model model;
        //Фон
        Texture2D background;
        //Кубическая карта окружающей среды
        TextureCube cubeMap;
        //Показатели, влияющие на наложение карты среды
        //Цвет  
        float amount = 1.0f;
        //Коэффициент Френеля 
        float fresnel = 0.1f;
        //Альфа-фактор
        float specular = 0.3f;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            // Частота кадра на Windows Phone по умолчанию — 30 кадров в секунду.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            // Дополнительный заряд аккумулятора заблокирован.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
            //Параметры экрана
            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;
        }

        /// <summary>
        /// Позволяет игре выполнить инициализацию, необходимую перед запуском.
        /// Здесь можно запросить нужные службы и загрузить неграфический
        /// контент.  Вызов base.Initialize приведет к перебору всех компонентов и
        /// их инициализации.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();
        }

        /// <summary>
        /// LoadContent будет вызываться в игре один раз; здесь загружается
        /// весь контент.
        /// </summary>
        protected override void LoadContent()
        {
            // Создайте новый SpriteBatch, который можно использовать для отрисовки текстур.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            //Фон
            background = Content.Load<Texture2D>("back");
            // Модель
            model = Content.Load<Model>("saucer");
            //Кубическая карта
            cubeMap = Content.Load<TextureCube>("cubemap");

        }

        /// <summary>
        /// UnloadContent будет вызываться в игре один раз; здесь выгружается
        /// весь контент.
        /// </summary>
        protected override void UnloadContent()
        {
            // ЗАДАЧА: выгрузите здесь весь контент, не относящийся к ContentManager
        }

        /// <summary>
        /// Позволяет игре запускать логику обновления мира,
        /// проверки столкновений, получения ввода и воспроизведения звуков.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Update(GameTime gameTime)
        {
            // Позволяет выйти из игры
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            base.Update(gameTime);
        }

        /// <summary>
        /// Вызывается, когда игра отрисовывается.
        /// </summary>
        /// <param name="gameTime">Предоставляет моментальный снимок значений времени.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // Вывод фонового изображения
            spriteBatch.Begin(0, BlendState.Opaque);
            spriteBatch.Draw(background, new Rectangle(0, 0, 480, 800), Color.White);
            spriteBatch.End();

            //// Вычисление матриц для управления камерой
            float time = (float)gameTime.TotalGameTime.TotalSeconds;

            Matrix rotation = Matrix.CreateRotationX(time * 0.3f) *
                              Matrix.CreateRotationY(time);

            Matrix view = Matrix.CreateLookAt(new Vector3(4500, -400, 0),
                                              new Vector3(0, -400, 0),
                                              Vector3.Up);

            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
                                                                    GraphicsDevice.Viewport.AspectRatio,
                                                                    10, 10000);

            Matrix[] transforms = new Matrix[model.Bones.Count];

            model.CopyAbsoluteBoneTransformsTo(transforms);
            //Настройка параметров графического устройства
            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

            //Вывод модели с использованием EnvironmentMapEffect
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (EnvironmentMapEffect effect in mesh.Effects)
                {
                    
                    Matrix world = transforms[mesh.ParentBone.Index] * rotation;
                    //Настройка параметров эффекта
                    effect.World = world;
                    effect.View = view;
                    effect.Projection = projection;
                    effect.EnvironmentMap = cubeMap;
                    effect.EnableDefaultLighting();
                    effect.EnvironmentMapAmount = amount;
                    effect.FresnelFactor = fresnel * 2;
                    effect.EnvironmentMapSpecular = new Vector3(1, 1, 0.5f) * specular;
                }
                mesh.Draw();
            }

            base.Draw(gameTime);
        }
    }
}
Листинг 27.2. Код класса Game1

На рис. 27.7 вы можете видеть игровое окно проекта.

Игровое окно проекта

Рис. 27.7. Игровое окно проекта

27.3. Выводы

В этой лекции мы рассмотрели приёмы скелетной анимации персонажей, создали кубическую карту окружающей среды и ознакомились с применением EnvironmentMapEffect для создания эффекта зеркального объекта, в котором отражается окружающий мир.

27.4. Задание

Найдите или создайте скелетную трехмерную модель и анимируйте её в зависимости от особенностей модели. Самостоятельно изучите возможности эффектов SkinnedEffect, DualTextureEffect, AlphaTestEffect.

Гулич Анна
Гулич Анна
Невозможно пройти тесты, в окне с вопросами пусто
Сашечка Огнев
Сашечка Огнев
Россия, Красноярский край
Андрей Корягин
Андрей Корягин
Россия, Пенза, Вазерская средняя школа, 2001