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

Компьютерная графика 3D в XNA

Экран с инструкцией о правилах HelpScreen

Код этой заставки мы спроектируем на основе только что созданного класса AboutScreen, внеся в него вместо загрузки файла about.png загрузку файла help.png. Здесь получится немного нерационально, потому что остальной код класса будет неизменным. Было бы проще добавить в конструктор класса AboutScreen параметр с именем загружаемого файла. Но учитывая, что у нас подобных заставок будет всего две, просто повторим этот код еще раз.

  • Загрузите в папку Textures проекта файл изображений help.png из прилагаемого к работе каталога Source
  • В панели Solution Explorer сделайте копию файла AboutScreen.cs и переименуйте ее в файл HelpScreen.cs
  • Перейдите в режим редактирования файла HelpScreen.cs, вызовите комбинацией клавиш Ctrl-H окно замены редактора кода и замените все вхождения about на help документа. После этого файл должен стать таким
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 HelpScreen
    {
        #region Поля класса
        Texture2D help, 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();
    
            // Загружаем в объекты изображения и модель мяча
            help = content.Load<Texture2D>("Textures\\help");
            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(help, new Vector2(width / 2 - help.Width / 2,
                height / 2 - help.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);
            }
        }
    }
}
  • Для тестирования разработанного класса HelpScreen введите временно следующие изменения в основной класс игры
public class StartGame3D : Microsoft.Xna.Framework.Game
    {    
        #region Поля класса 
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        int screenWidth, screenHeight;  // Размеры экрана
        KeyboardState keyboardState;    // Буфер клавиатуры 
        GameState gameState = GameState.HelpScreen;   // Переменная состояния игры
    
        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();
        HelpScreen help = new HelpScreen();
        #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);
            help.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:
                    // Выход из игрового процесса
                    if (keyboardState.IsKeyDown(Keys.Escape))
                        this.Exit();
                    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:
                    help.DrawScreen(this.spriteBatch, this.graphics, screenWidth, screenHeight, gameTime);
                    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);
        }
    
        .............................................................
    
    }
  • Запустите приложение и убедитесь, что код класса HelpScreen работает нормально в основном цикле игры. Получится картинка, приведенная ниже, с вращающимися в плоскости экрана относительно его центра мячами

Алексей Бабушкин
Алексей Бабушкин

При выполнении в лабораторной работе упражнения №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" или один из зависимых от них компонентов. Не удается найти указанный файл.

Делаю все пунктуально. В чем может быть проблема?

Иван Циферблат
Иван Циферблат
Россия, Таганрог, 36, 2000