При выполнении в лабораторной работе упражнения №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" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Windows Forms и XNA 3.0
Визуализация объекта, использующего эффект
Визуализация примитивов, использующих эффект, начинается с вызова метода effect.Begin() объекта эффекта. Далее приложение должно перебрать все проходы текущей техники (коллекция effect.CurrentTechnique.Passes ) и вызвать метод pass.Begin() для каждого прохода. Внутри прохода нужно визуализировать примитивы с использованием метода device.DrawUserPrimitives(). Визуализацию прохода нужно закончить вызовом метода pass.End(). По окончанию визуализации всего эффекта приложение должно вызвать метод effect.End().
- Через контекстное меню перейдите в режим View Designer формы, выделите на ней объект xnaPanel1 и откройте панель Properties в режиме Events
- Найдите событие Paint объекта xnaPanel1 и двойным щелчком на его поле справа создайте обработчик, который заполните так
private void xnaPanel1_Paint(object sender, PaintEventArgs e) { if (closing) return; try { if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.Lost) throw new DeviceLostException(); if (device.GraphicsDeviceStatus == GraphicsDeviceStatus.NotReset) device.Reset(presentParams); // Очищаем область экрана device.Clear(XNAGraphics.Color.CornflowerBlue); device.RenderState.CullMode = CullMode.None; device.VertexDeclaration = decl; // Задаем координаты вершин из установленного в группе панелей цвета vertices[0] = new VertexPositionColor(new Vector3(0.0f, 0.8f, 0.0f), new XNAGraphics.Color( vertex1Color.BackColor.R, vertex1Color.BackColor.G, vertex1Color.BackColor.B)); vertices[1] = new VertexPositionColor(new Vector3(0.8f, -0.8f, 0.0f), new XNAGraphics.Color( vertex2Color.BackColor.R, vertex2Color.BackColor.G, vertex2Color.BackColor.B)); vertices[2] = new VertexPositionColor(new Vector3(-0.8f, -0.8f, 0.0f), new XNAGraphics.Color( vertex3Color.BackColor.R, vertex3Color.BackColor.G, vertex3Color.BackColor.B)); effect.Begin(); foreach(EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length / 3); pass.End(); } effect.End(); device.Present(); } catch (DeviceNotResetException) { Invalidate(); } catch (DeviceLostException) { closing = true; // Больше не выполнять OnPaint() string title = "Сбой графического устройства"; string message = "Работа программы будет завершена.\n" + "Закройте все ненужные программы\n" + "и повторите запуск этого приложения"; MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Stop); Application.Idle += new EventHandler(Application_Idle); return; } catch (Exception ext) // Все другие исключения { closing = true; MessageBox.Show(ext.Message); Application.Idle += Application_Idle; } }
- Выделите на форме объект xnaPanel1 и через панель Properties в режиме Events создайте обработчик события Resize, который заполните так
private void xnaPanel1_Resize(object sender, EventArgs e) { // Устанавливаем размеры заднего буфера по клиентской области панели presentParams.BackBufferWidth = xnaPanel1.ClientSize.Width; presentParams.BackBufferHeight = xnaPanel1.ClientSize.Height; // Сбрасываем устройство и применяем к нему новые параметры // Если окно не минимизировано if (this.WindowState != FormWindowState.Minimized) device.Reset(presentParams); }
- Выделите саму форму щелчком на ее заголовке и через панель Properties в режиме Events создайте обработчик события FormClosed, который заполните так
private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; }
- Осторожно (чтобы не создать обработчик) выделите все три кнопки на форме (удерживая клавишу Ctrl ) и через панель Properties в режиме Events создайте обработчик события Click с именем vertexColor_Click, который заполните так
private void vertexColor_Click(object sender, EventArgs e) { Button button = (Button)sender; colorDialog1.Color = button.BackColor; if (colorDialog1.ShowDialog() == DialogResult.OK) { button.BackColor = colorDialog1.Color; xnaPanel1.Invalidate(); } }
- В панели Solution Explorer выделите узел проекта Application2 и через контекстное меню сделайте проект стартовым. Запустите приложение - должен получиться такой результат
Запускающее приложение
Если вы все делали так как описано, то исполнимые сборки для упражнений 1 и 2 должны находиться относительно папки решений FormsXNA в подпапках:
FormsXNA\Application1\bin\Debug\Application1.exe FormsXNA\Application2\bin\Debug\Application2.exe
В этом разделе, для тренировки, мы добавим к проекту простое приложение, запускающее сборки с выполненными упражнениями, чтобы легче было их демонстрировать.
- Добавьте к решению новый проект с именем StartForm и сделайте его стартовым
- Переименуйте файл формы Form1.cs в StartForm.cs и откройте его в режиме View Designer и поместите на форму два экземпляра компонента LinkLabel
- Создайте для них обработчики события LinkClicked и заполните их следующим кодом
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; namespace StartApp { public partial class StartForm : Form { System.Diagnostics.Process exe = new System.Diagnostics.Process(); String path; // Путь к папке с решением public StartForm() { InitializeComponent(); path = Directory.GetCurrentDirectory();// Получаем путь к сборке StartForm int pos = path.LastIndexOf(@"\bin\"); path = path.Substring(0, pos);// Убираем 2 последних секции пути pos = path.LastIndexOf(@"\"); path = path.Substring(0, pos);// Убираем еще одну секцию } private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { Directory.SetCurrentDirectory(path + @"\Application1\bin\Debug");// Путь к сборке exe.StartInfo.FileName = "Application1.exe"; System.Diagnostics.Debug.WriteLine(path); // Для отладки в окно Output exe.Start(); } private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { Directory.SetCurrentDirectory(path + @"\Application2\bin\Debug");// Путь к сборке exe.StartInfo.FileName = "Application2.exe"; System.Diagnostics.Debug.WriteLine(path); // Для отладки в окно Output exe.Start(); } } }
Код будет работать при условии, что сборка стартовой формы находится в своем каталоге bin дерева решения.