| 
         При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Xna.Framework.Graphics; 
 namespace Application1 { public partial class MainForm : Form { // Объявим поле графического устройства для видимости в методах GraphicsDevice device; 
 public MainForm() { InitializeComponent(); 
 // Подпишемся на событие Load формы this.Load += new EventHandler(MainForm_Load); 
 // Попишемся на событие FormClosed формы this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed); } 
 void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; } 
 void MainForm_Load(object sender, EventArgs e) { // Создаем объект представления для настройки графического устройства PresentationParameters presentParams = new PresentationParameters(); // Настраиваем объект представления через его свойства presentParams.IsFullScreen = false; // Включаем оконный режим presentParams.BackBufferCount = 1; // Включаем задний буфер // для двойной буферизации // Переключение переднего и заднего буферов // должно осуществляться с максимальной эффективностью presentParams.SwapEffect = SwapEffect.Discard; // Устанавливаем размеры заднего буфера по клиентской области окна формы presentParams.BackBufferWidth = this.ClientSize.Width; presentParams.BackBufferHeight = this.ClientSize.Height; 
 // Создадим графическое устройство с заданными настройками device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle, presentParams); } 
 protected override void OnPaint(PaintEventArgs e) { device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue); 
 base.OnPaint(e); } } } Выбрасывается исключение: Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема?  | 
Компьютерная графика 3D в XNA
Добавление экранных заставок
В самом начале построения приложения мы в методах LoadContent() и Draw() с помощью оператора switch заложили несколько состояний игры, определенных в перечислении GameState
- AboutScreen, // Экран с информацией об игре
 - GameOverScreen, // Экран проигрыша
 - GameScreen, // Экран игрового процесса
 - HelpScreen, // Инструкция о правилах
 - MenuScreen, // Меню игры
 - SplashScreen, // Первая игровая заставка
 - VictotyScreen, // Экран выигрыша
 
До сих пор мы реализовали только одно из них - саму игру. В этом разделе закодируем еще три состояния: SplashScreen, AboutScreen, HelpScreen. Смену режимов закрепим за клавишами Enter и Esc.
Экран игровой заставки SplashScreen
Первой будет появляться игровая заставка, из которой по клавише Enter попадем в меню, а по клавише Esc выйдем из игры. Игровая заставка будет состоять из нескольких отдельных компонентов:
- Фоновый рисунок splash.png
 - Вехний заголовок игры title.png
 - Нижняя подсказка enter.png
 - Изображение пулевого отверстия hole.png, которое мы разбросаем по экрану заставки случайным образом в 30 экземплярах
 - Модели вращающегося мяча Soccerball.x посередине экрана на переднем плане заставки
 
Прежде всего нужно скопировать в проект эти компоненты заставки.
- 
В панели Solution
      Explorer    вызовите контекстное меню для каталога проекта Textures   и дабавьте
    командой Add/Existing Item  из прилагаемого каталога Source  файлы
    с рисунками splash.png, title.png, enter.png, hole.png
 
Код игровой заставки упакуем в класс SplashScreen.
- 
Командой Project/Add Class   меню
  оболочки добавьте к проекту файл SplashScreen.cs  и
  скопируйте в него все инструкции using  из файла StartGame3D
 - 
Заполните файл SplashScreen.cs  следующим
    кодом 
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.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
    
namespace Game3D
{
    class SplashScreen
    {
        #region Поля класса
        Texture2D splash, title, enter, hole;   // Объекты рисунков 
        Vector2[] posHole = new Vector2[30];    // Массив позиций рисунка пули
        Random rand = new Random();             // Генератор случайных чисел
    
        ModelClass ball = new ModelClass();     // Объект мяча
        float aspectRatio;                      // Коэффициент искажения проекции
        float FOV = MathHelper.PiOver4;         // Ракурс камеры 45 градусов
        float nearClip = 1.0f;                  // Ближняя отсекающая плоскость
        float farClip = 1000.0f;                // Дальняя отсекающай плоскость
        float angle = 0;                        // Угол поворота
        Matrix world, view, proj;               // Матрицы преобразований
        #endregion
    
        // Инициализация объектов
        // content - контент экземпляра основного класса игры
        // width - текущаяя ширина экрана
        // height - текущая высота экрана
        public void InitializeSplashScreen(ContentManager content, int width, int height)
        {
            // Загружаем в объекты изображения и модель мяча
            splash = content.Load<Texture2D>("Textures\\splash");
            title = content.Load<Texture2D>("Textures\\title");
            enter = content.Load<Texture2D>("Textures\\enter");
            hole = content.Load<Texture2D>("Textures\\hole");
            ball.Load(content, "Models\\Soccerball");
            ball.Position = new Vector3(0, 0, 0);// В центре экрана, где начало мировой системы координат
    
            // Разбрасываем по экрану пулевые отверстия
            for (int i = 0; i < posHole.Length; i++)
            {
                posHole[i].X = rand.Next(20, width - 60);
                posHole[i].Y = rand.Next(100, height - 60);
            }
    
            // Коэффициент искажения проекции
            aspectRatio = (float)width / height;
        }
    
        // Вывод заставки на экран
        // spriteBatch - объект рисования спрайтов
        // graphics - объект графического устройства GDI
        // width - текущаяя ширина экрана
        // height - текущая высота экрана
        // gameTime - длительность одного такта игры
        public void DrawScreen(SpriteBatch spriteBatch, GraphicsDeviceManager graphics,
            int width, int height, GameTime gameTime)
        {
            // Очищаем экран своим цветом
            graphics.GraphicsDevice.Clear(Color.DarkGreen); 
    
            // Рисуем в GDI плоские компоненты относительно центра экрана и в Z-последовательности
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(splash, new Vector2(width / 2 - splash.Width / 2,
                height / 2 - splash.Height / 2), Color.White);
            spriteBatch.Draw(title, new Vector2(width / 2 - title.Width / 2, 
                30), // Чуть опустили
                Color.White);
            spriteBatch.Draw(enter, new Vector2(width / 2 - enter.Width / 2,
                height - enter.Height - 30), // Чуть приподняли
                Color.White);
            for (int i = 0; i < posHole.Length; i++)
                spriteBatch.Draw(hole, posHole[i], Color.White);
            spriteBatch.End();
    
            // Рисуем объемный мяч на переднем плане
            graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;// Включаем буфер глубины
            view = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 150.0f), Vector3.Zero, Vector3.Up);
            proj = Matrix.CreatePerspectiveFieldOfView(FOV, aspectRatio, nearClip, farClip);
            world = Matrix.CreateTranslation(ball.Position);
            angle += (float)(gameTime.ElapsedGameTime.TotalSeconds * 2.0f);// Увеличиваем угол вращения мяча
            world *= Matrix.CreateRotationY(angle);
            ball.DrawModel(world, view, proj);
        }
    }
}- 
Для тестирования разработанного
  класса SplashScreen  введите временно следующие изменения в
  основной класс игры 
public class StartGame3D : Microsoft.Xna.Framework.Game
    {    
        #region Поля класса 
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        int screenWidth, screenHeight;  // Размеры экрана
        KeyboardState keyboardState;    // Буфер клавиатуры 
        //GameState gameState = GameState.GameScreen;   // Переменная состояния игры
        GameState gameState = GameState.SplashScreen;   // Переменная состояния игры
    
        Matrix world;                   // Мировая матрица
        Matrix view;                    // Матрица вида
        Matrix proj;                    // Проекционная матрица
        float aspectRatio;              // Коэффициент искажения проекции
        float FOV = MathHelper.PiOver4; // Ракурс
        float nearClip = 1.0f;          // Ближняя отсекающая плоскость перспективы
        float farClip = 1000.0f;        // Дальняя отсекающая плоскость перспективы
        //Vector3 camera = new Vector3(0.0f, 0.0f, 150.0f);
        Vector3 camera = new Vector3(0.0f, 20.0f, 250.0f);
        //ModelClass ball;   
        ModelClass[] ball = new ModelClass[3];  
        MouseState mouseState;                  
        Random rand = new Random();   
    
        // Создание объекта курсора-прицела
        Game2D.Sprite cursor = new Game2D.Sprite();
    
        // Создание объекта модели стадиона
        ModelClass stadium = new ModelClass();
    
        // Создание объекта для рисунка пейзажа
        Game2D.Sprite background = new Game2D.Sprite();
    
        // Создание объектов для других состояний экранов
        SplashScreen splash = new SplashScreen();
        #endregion
    
        protected override void LoadContent()
        {
            ....................................................
    
            // Загружаем рисунок заднего фона
            background.Load(this.Content, "Textures\\hallake001");
            // Чуть приподнимем вверх экрана 
            background.spritePosition = new Vector2(0, -50);
    
            // Инициализация объектов других состояний экранов
            splash.InitializeSplashScreen(this.Content, screenWidth, screenHeight);
        }
      
        protected override void Update(GameTime gameTime)
        {
            // Читать буфер клавиатуры 
            keyboardState = Keyboard.GetState();
    
            switch (gameState)
            {
                case GameState.AboutScreen:
                    break;
                case GameState.GameOverScreen:
                    break;
                case GameState.GameScreen:
                    // Выход из игрового процесса
                    if (keyboardState.IsKeyDown(Keys.Escape))
                        this.Exit();
    
                    MoveBalls();
                    MouseClick();
                    break;
                case GameState.HelpScreen:
                    break;
                case GameState.MenuScreen:
                    break;
                case GameState.SplashScreen:
                    // Выход из игрового процесса
                    if (keyboardState.IsKeyDown(Keys.Escape))
                        this.Exit();
    
                    break;
                case GameState.VictotyScreen:
                    break;
            }
    
            base.Update(gameTime);
        }
    
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
    
            switch (gameState)
            {
                case GameState.AboutScreen:
                    break;
                case GameState.GameOverScreen:
                    break;
                case GameState.GameScreen:
                    .......................................................
    
                    break;
                case GameState.HelpScreen:
                    break;
                case GameState.MenuScreen:
                    break;
                case GameState.SplashScreen:
                    splash.DrawScreen(this.spriteBatch, this.graphics, screenWidth, screenHeight, gameTime);
                    break;
                case GameState.VictotyScreen:
                    break;
            }
    
            base.Draw(gameTime);
        }
    }- 
Запустите приложение
    и убедитесь, что код класса SplashScreen  работает нормально в основном
    цикле игры. Получится картинка, приведенная ниже, с вращающимся в центре
    мячом 
Экран с информацией об игре AboutScreen
Код этой заставки мы спроектируем на основе только что созданного класса SplashScreen, внеся в него незначительные коррективы. Эти изменения будет связаны в основном с тем, что вместо одного мяча, вращающегося в центре экрана, мы введем три мяча, которые будут вращаться как и прежде - относительно оси y, и одновременно - относительно оси z. В итоге получим сложное вращение мячей в плоскости экрана относительно его центра.
- 
Загрузите в папку Textures     проекта
    файлы изображений about.png  и esc.png  из прилагаемого к работе каталога Source
 - 
В панели Solution
        Explorer сделайте копию файла SplashScreen.cs  и переименуйте
      ее в файл AboutScreen.cs
 - 
Модифицируйте файл AboutScreen.cs  так,
    чтобы он выглядел следующим образом 
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.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
    
namespace Game3D
{
    class AboutScreen
    {
        #region Поля класса
        Texture2D about, title, esc, hole;      // Объекты рисунков 
        Vector2[] posHole = new Vector2[30];    // Массив позиций рисунка пули
        Random rand = new Random();             // Генератор случайных чисел
    
        ModelClass [] ball = new ModelClass[3]; // Объекты мячей 
        float aspectRatio;                      // Коэффициент искажения проекции
        float FOV = MathHelper.PiOver4;         // Ракурс камеры 45 градусов
        float nearClip = 1.0f;                  // Ближняя отсекающая плоскость
        float farClip = 1000.0f;                // Дальняя отсекающай плоскость
        float angle = 0;                        // Угол поворота
        Matrix world, view, proj;               // Матрицы преобразований
        #endregion
    
        // Инициализация объектов
        // content - контент экземпляра основного класса игры
        // width - текущаяя ширина экрана
        // height - текущая высота экрана
        public void InitializeSplashScreen(ContentManager content, int width, int height)
        {
            // Создаем объекты для мячей 
            for (int i = 0; i < ball.Length; i++)
                ball[i] = new ModelClass();
    
            // Загружаем в объекты изображения и модель мяча
            about = content.Load<Texture2D>("Textures\\about");
            title = content.Load<Texture2D>("Textures\\title");
            esc = content.Load<Texture2D>("Textures\\esc");
            hole = content.Load<Texture2D>("Textures\\hole");
            ball[0].Load(content, "Models\\Soccerball");
            ball[0].Position = new Vector3(-30, 40, -30);
            ball[1].Load(content, "Models\\SoccerballGreen");
            ball[1].Position = new Vector3(50, 30, -50);
            ball[2].Load(content, "Models\\SoccerballRed");
            ball[2].Position = new Vector3(-50, -30, 40);
    
            // Разбрасываем по экрану пулевые отверстия
            for (int i = 0; i < posHole.Length; i++)
            {
                posHole[i].X = rand.Next(20, width - 60);
                posHole[i].Y = rand.Next(100, height - 60);
            }
    
            // Коэффициент искажения проекции
            aspectRatio = (float)width / height;
        }
    
        // Вывод заставки на экран
        // spriteBatch - объект рисования спрайтов
        // graphics - объект графического устройства GDI
        // width - текущаяя ширина экрана
        // height - текущая высота экрана
        // gameTime - длительность одного такта игры
        public void DrawScreen(SpriteBatch spriteBatch, GraphicsDeviceManager graphics,
            int width, int height, GameTime gameTime)
        {
            // Очищаем экран своим цветом
            graphics.GraphicsDevice.Clear(Color.DarkGreen); 
    
            // Рисуем в GDI плоские компоненты относительно центра экрана и в Z-последовательности
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(about, new Vector2(width / 2 - about.Width / 2,
                height / 2 - about.Height / 2), Color.White);
            spriteBatch.Draw(title, new Vector2(width / 2 - title.Width / 2, 
                30), // Чуть опустили
                Color.White);
            spriteBatch.Draw(esc, new Vector2(width / 2 - esc.Width / 2,
                height - esc.Height - 30), // Чуть приподняли
                Color.White);
            for (int i = 0; i < posHole.Length; i++)
                spriteBatch.Draw(hole, posHole[i], Color.White);
            spriteBatch.End();
    
            // Рисуем мячи на переднем плане
            graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;// Включаем буфер глубины
            view = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 260.0f), Vector3.Zero, Vector3.Up);
            proj = Matrix.CreatePerspectiveFieldOfView(FOV, aspectRatio, nearClip, farClip);
            angle += (float)(gameTime.ElapsedGameTime.TotalSeconds * 1.0f);
            Matrix rotationMatrixY = Matrix.CreateRotationY(angle);
            Matrix rotationMatrixZ = Matrix.CreateRotationZ(angle);
            for (int i = 0; i < ball.Length; i++)
            {
                world = Matrix.CreateTranslation(ball[i].Position);
                ball[i].DrawModel(rotationMatrixY * world * rotationMatrixZ, view, proj);
            }
        }
    }
}- 
Для тестирования
    разработанного класса AboutScreen  введите временно следующие изменения
    в основной класс игры 
public class StartGame3D : Microsoft.Xna.Framework.Game
    {    
        #region Поля класса 
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        int screenWidth, screenHeight;  // Размеры экрана
        KeyboardState keyboardState;    // Буфер клавиатуры 
        GameState gameState = GameState.AboutScreen;   // Переменная состояния игры
    
        Matrix world;                   // Мировая матрица
        Matrix view;                    // Матрица вида
        Matrix proj;                    // Проекционная матрица
        float aspectRatio;              // Коэффициент искажения проекции
        float FOV = MathHelper.PiOver4; // Ракурс
        float nearClip = 1.0f;          // Ближняя отсекающая плоскость перспективы
        float farClip = 1000.0f;        // Дальняя отсекающая плоскость перспективы
        //Vector3 camera = new Vector3(0.0f, 0.0f, 150.0f);
        Vector3 camera = new Vector3(0.0f, 20.0f, 250.0f);
        //ModelClass ball;   
        ModelClass[] ball = new ModelClass[3];  
        MouseState mouseState;                  
        Random rand = new Random();   
    
        // Создание объекта курсора-прицела
        Game2D.Sprite cursor = new Game2D.Sprite();
    
        // Создание объекта модели стадиона
        ModelClass stadium = new ModelClass();
    
        // Создание объекта для рисунка пейзажа
        Game2D.Sprite background = new Game2D.Sprite();
    
        // Создание объектов для других состояний экранов
        SplashScreen splash = new SplashScreen();
        AboutScreen about = new AboutScreen();
        #endregion
    
        ..............................................................
    
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
    
            //ball.Load(this.Content, "Models\\Soccerball");            
            // Загружаем модели мячей
            ball[0].Load(this.Content, "Models\\Soccerball");           
            ball[1].Load(this.Content, "Models\\SoccerballGreen");      
            ball[2].Load(this.Content, "Models\\SoccerballRed");   
    
            // Загружаем трехмерную модель стадиона
            stadium.Load(this.Content, "Models\\stadium 1");
    
            // Устанавливаем начальную позицию объектов 
            BeginPosition();    
    
            // Загружаем рисунок курсора-прицела 
            cursor.Load(this.Content, "Textures\\cursor");
    
            // Загружаем рисунок заднего фона
            background.Load(this.Content, "Textures\\hallake001");
            // Чуть приподнимем вверх экрана 
            background.spritePosition = new Vector2(0, -50);
    
            // Инициализация объектов других состояний экранов
            splash.InitializeSplashScreen(this.Content, screenWidth, screenHeight);
            about.InitializeSplashScreen(this.Content, screenWidth, screenHeight);
        }
    
        ..............................................................
    
        protected override void Update(GameTime gameTime)
        {
            // Читать буфер клавиатуры 
            keyboardState = Keyboard.GetState();
    
            switch (gameState)
            {
                case GameState.AboutScreen:
                    // Выход из игрового процесса
                    if (keyboardState.IsKeyDown(Keys.Escape))
                        this.Exit();
                    break;
                case GameState.GameOverScreen:
                    break;
                case GameState.GameScreen:
                    // Выход из игрового процесса
                    if (keyboardState.IsKeyDown(Keys.Escape))
                        this.Exit();
    
                    MoveBalls();
                    MouseClick();
                    break;
                case GameState.HelpScreen:
                    break;
                case GameState.MenuScreen:
                    break;
                case GameState.SplashScreen:
                    // Выход из игрового процесса
                    if (keyboardState.IsKeyDown(Keys.Escape))
                        this.Exit();
                    break;
                case GameState.VictotyScreen:
                    break;
            }
    
            base.Update(gameTime);
        }
    
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
    
            switch (gameState)
            {
                case GameState.AboutScreen:
                    about.DrawScreen(this.spriteBatch, this.graphics, screenWidth, screenHeight, gameTime);
                    break;
                case GameState.GameOverScreen:
                    break;
                case GameState.GameScreen:
                    ..............................................................
    
                    break;
                case GameState.HelpScreen:
                    break;
                case GameState.MenuScreen:
                    break;
                case GameState.SplashScreen:
                    splash.DrawScreen(this.spriteBatch, this.graphics, screenWidth, screenHeight, gameTime);
                    break;
                case GameState.VictotyScreen:
                    break;
            }
    
            base.Draw(gameTime);
        }
    
        ..............................................................
    
    }- 
Запустите приложение
    и убедитесь, что код класса AboutScreen  работает нормально в основном
    цикле игры. Получится картинка, приведенная ниже, с вращающимися в плоскости
    экрана относительно его центра мячами 
                             

