Навигация
· XNA FAQ
· С чего начать
· Конкурсы
· Обратная связь
· XNA Блоги
Сейчас на сайте
· Гостей: 1

· Пользователей: 0

· Всего пользователей: 3,684
· Новый пользователь: headron
Последние фото
Эх, чуть не проспал закрытие.
Эх, чуть не проспал ...
Альбом: XNA Engine

GB
GB
Альбом: XNA Engine

South Park Coon & Friends
South Park Coon & Fr...
Альбом: XNA Games

Блоги
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
dampirik
» Реклама,статистик...
Chort
» XNA и StartCoroutine
Chort
» Curve Class
dampirik
» Реклама, статисти...
dampirik
» Увеличение скорос...
dampirik
» Реклама, статисти...
general
» Распаковка DxtCom...
general
» Как работать с XN...
Поддержка
microsoft.com
1gb.ru - Дом для вашего сайта
Статистика посещений:

Работа с файлами

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

Цель работы

  • Научиться работать с файлами


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

  • Освоить файловые операции в XNA
  • Освоить сериализацию объектов
  • Организовать загрузку и сохранение игры

Файловые операции в XNA

Создадим новый проект P10_1. Реализуем в нем демонстрацию следующих операций с файлами:

  1. Создание нового файла.
  2. Открытие файла и чтение информации из него.
  3. Копирование файла.
  4. Переименование файла.
  5. Просмотр директории.
  6. Удаление файла.

Для работы с файлами в XNA нужно выполнить следующие шаги: 

  • Во-первых – получить объект типа IAsyncResult – как результат запроса о выборе устройства хранения информации.
  • Во-вторых – переменная типа IAsyncResult используется для создания переменной типа StorageDevice, которая представляет устройство для хранения данных.
  • В-третьих – переменная типа StorageDevice используется при создании объекта StorageContainer, который используется для доступа к месту хранения файлов. В случае с Windows-играми это – папка SavedGames, расположенная в папке Мои Документы текущего пользователя.

На рис. 10.1. вы можете видеть данную папку для проекта P10_1.


Рис. 10.1. Папка для сохранения игры

В листинге 10.1. вы можете найти код класса Game1.

Листинг 10.1. Код класса Game1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
 
//Классы для работы с устройствами ввода-вывода
using System.IO;
 
namespace P10_1
{
 
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        //Для информации об используемом устройстве хранения информации
        StorageDevice sDev;
        //Для хранения результата асинхронной операции доступа к устройству
        IAsyncResult res;
 
        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()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
 
            // TODO: use this.Content to load your game content here
        }
 
 
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
        //Процедура для создания нового файла
        void FileCreate(StorageDevice device)
        {
         //Массив байтов для записи в файл
            byte[] a = new byte[10];
            for (byte i = 0; i < 10; i++)
            {
                a[i] = i;
            }
            //Открываем контейнер для хранения файлов
            //В случае с Windows-играми это - папка с соответствующим
            //именем в папке Мои документы текущего пользователя
            StorageContainer container =
                device.OpenContainer("P10_1");
            //Соединяем имя файла и имя контейнера
            string filename = Path.Combine(container.Path, "savegame.sav");
            //Создаем новый файл
 
            if (!File.Exists(filename))
            {
 
                FileStream file = File.Create(filename);
                //Записываем в файл массив байтов, сгенерированный выше
                file.Write(a, 0, 10);
                //закрываем файл
                file.Close();
                this.Window.Title = "Файл создан";
            }
            else
            {
                this.Window.Title = "Файл уже создан";
            }
 
            //Уничтожаем контейнер - только после этого файл будет 
            //сохранен
            container.Dispose();
 
        }
 
        //Процедура для открытия существующего файла
        void FileOpen(StorageDevice device)
        {
            StorageContainer container =
                device.OpenContainer("P10_1");
            string filename = Path.Combine(container.Path, "savegame.sav");
 
            if (File.Exists(filename))
            {
 
                FileStream file = File.Open(filename, FileMode.Open);
                //Выведем данные, считанные из файла, в заголовок игрового окна
                this.Window.Title = "Содержимое файла: ";
                for (int i = 1; i < file.Length + 1; i++)
                    this.Window.Title = this.Window.Title + file.ReadByte().ToString();
                file.Close();
            }
            else
            {
                this.Window.Title = "Отсутствует файл для чтения";
            }
            container.Dispose();
        }
        //Процедура для копирования файла
        void FileCopy(StorageDevice device)
        {
            StorageContainer container =
                device.OpenContainer("P10_1");
            string filename = Path.Combine(container.Path, "savegame.sav");
 
            if (File.Exists(filename))
            {
                string copyfilename = Path.Combine(container.Path, "copysave.bak");
                File.Copy(filename, copyfilename, true);
                this.Window.Title = "Файл скопирован";
            }
            else
            {
                this.Window.Title = "Файл не существует";
            }
            container.Dispose();
 
        }
        //Процедура для переименования файла
        void FileRename(StorageDevice device)
        {
              StorageContainer container =
                device.OpenContainer("P10_1");
            //Старое имя файла
            string oldfilename = Path.Combine(container.Path, "copysave.bak");
            //Новое имя файла
            string newfilename = Path.Combine(container.Path, "rencopysave.sav");
            //Если в папке нет файла с новым именем файла и есть файл 
            //со старым именем - переименовываем
 
            if (!File.Exists(newfilename)&File .Exists (oldfilename ))
            {
                File.Move(oldfilename, newfilename);
                this.Window.Title = "Скопированный файл переименован";
            }
            else
            {
                this.Window.Title = "Такой файл уже есть или отсутствует файл для переименования";
            }
 
            container.Dispose();
 
        }
        //Просмотр содержимого папки
        void FileEnumerate(StorageDevice device)
        {
            StorageContainer container =
                device.OpenContainer("P10_1");
            string FNForComp="";
            //Получить список файлов
            ICollection<string> FileList = Directory.GetFiles(container.Path);
            //Для каждого имени файла проверим, соответствует ли оно
            //заданному имени, предположим, что папка не содержит заданного файла
            this.Window.Title = "Папка не содержит файл rencopysave.sav";
            foreach (string filename in FileList)
            {
                //Извлечем из строки с полным путем к файлу
                //имя файла
                FNForComp = Path.GetFileName(filename);
                //Если имя файла равно искомому - выведем 
                //соответствующее сообщение
                if (FNForComp == "rencopysave.sav")
                {
                    this.Window.Title = "Папка содержит файл rencopysave.sav"; 
                }
            }
            container.Dispose();
        }
        //удаление файла
        void FileDelete(StorageDevice device)
        {
 
            StorageContainer container =
                device.OpenContainer("P10_1");
            string filename = Path.Combine(container.Path, "rencopysave.sav");
 
            //Удаляем файл если он существует
            if (File.Exists(filename))
            {
                File.Delete(filename);
                this.Window.Title = "Файл rencopysave.sav удален";
            }
            container.Dispose();
        }
 
 
        protected override void Update(GameTime gameTime)
        {
 
            KeyboardState kb = Keyboard.GetState();
            //Инициируем процедуру выбора устройства, в случае с Windows
            //автоматически выбирается папка SavedGames в папке Мои документы
            //текущего пользователя
            res = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One, null, null);
            //Сохраняем найденное устройство - позже мы используем его 
            //в процедурах работы с файлами
            sDev = Guide.EndShowStorageDeviceSelector(res);
            //При нажатии на клавишу Q вызываем процедуру сохранения файла
            if (kb.IsKeyDown(Keys.Q))
            {
                FileCreate(sDev);
            }
            //При нажатии на W вызываем процедуру открытия файла
            if (kb.IsKeyDown(Keys.W))
            {
                FileOpen(sDev);
            }
            //При нажатии на E вызываем процедуру копирования файла
            if (kb.IsKeyDown(Keys.E))
            {
                FileCopy(sDev);
            }
            //При нажатии на A вызываем процедуру переименования файла
            if (kb.IsKeyDown(Keys.A))
            {
                FileRename(sDev);
            }
            //При нажатии на S вызываем процедуру просмотра каталога
            if (kb.IsKeyDown(Keys.S))
            {
                FileEnumerate(sDev);
            }
            //При нажатии D вызываем процедуру удаления файла
            if (kb.IsKeyDown(Keys.D))
            {
                FileDelete(sDev);
            }
            base.Update(gameTime);
        }
 
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
 
            // TODO: Add your drawing code here
 
            base.Draw(gameTime);
        }
    }
}

 

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

Сериализация объектов: сохранение и загрузка игры

Сериализация объектов - это, другими словами – сохранение объекта в виде файла. Сериализованный объект можно восстановить в ходе операции десериализации. В случае с компьютерными играми сериализацию удобно использовать для сохранения игровой информации. Для того, чтобы эффективно использовать инструменты сериализации в играх, нужно заранее уяснить, какие именно объекты будут сериализованы. Желательно выделить для сериализации особые объекты, которые будут содержать лишь ту информацию, сохранение которой необходимо для успешного продолжения игрового процесса при десериализации соответствующего объекта, то есть – загрузке игры.

Игра, предусматривающая возможность сохранения игрового состояния, должна предусматривать как минимум два режима работы. Первый – когда игра начинается сначала – в таком случае поля класса, предназначенного для сериализации, заполняются некоторыми заранее заданными значениями. В ходе игры поля класса меняются, отражая изменения, произошедшие в ходе игрового процесса. Далее, после того, как объект сериализован, игра может либо начинаться сначала, либо – восстанавливать свое состояние на момент сериализации. Рассмотрим пример сохранения и восстановления состояния игры на примере проекта P10_2.

Игровой процесс приводимого здесь проекта заключается в том, что пользователь должен кликать мышью по плиткам, которые исчезают после щелчка по ним. Задача – создать механизм, который позволит сохранять состояние игрового экрана в файле и восстанавливать это состояние. Мы не будем приводить здесь разработку игровой логики, меню и других подсистем игры. Сосредоточимся на сохранении и загрузке игры.

На рис. 10.2. вы можете видеть окно Project Explorer для проекта P10_2.

Рис. 10.2. Окно Project Explorer для проекта P10_2

  • Класс Game1 – это стандартный игровой класс.
  • GameData – класс, содержащий игровые данные и предназначенный для сериализации.
  • gBaseClass, Wall – классы для визуализации игровых объектов.

В листинге 10.2. вы можете видеть код класса GameData.

Листинг 10.2. Код класса GameData
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Text;
 
namespace P10_2
{
    //Атрибут, указывающий на то, что класс может быть сериализован
    [Serializable]
    class GameData
    {
        //Поле класса, которое содержит важные игровые данные
        public byte [,] array;
        //Конструктор класса
        public GameData (byte [,] arr)
        {
            //array = new byte [8,10];
            array = arr;
        }
    }
}

Обратите внимание на атрибут Serializable – он указывает на то, что класс может быть сериализован. От набора полей этого класса и от данных, хранящихся в них, зависит размер файла, в котором будет храниться игровая информация. В нашем случае класс содержит массив типа Byte, который будет представлять собой состояние игрового окна на момент сохранения игры.

Рассмотрим классы gBaseClass и Wall (листинг 10.3., 10.4.) Эти классы мы уже использовали в проекте P5_1. Класс gBaseClass содержит механизмы для рисования компонента и расположения его на экране, а класс Wall – потомок класса gBaseClass – используется для управления поведением объекта.

Листинг 10.3. Код класса gBaseClass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
 
namespace P10_2
{
    public class gBaseClass : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Texture2D sprTexture;
        public Vector2 sprPosition;
        public Rectangle sprRectangle;
        public gBaseClass(Game game, ref Texture2D _sprTexture,
            Vector2 _sprPosition, Rectangle _sprRectangle)
            : base(game)
        {
            sprTexture = _sprTexture;
            //Именно здесь производится перевод индекса элемента массива
            //в координаты на игровом экране
            sprPosition = _sprPosition * 64;
            sprRectangle = _sprRectangle;
        }
 
        public override void Initialize()
        {
            base.Initialize();
        }
 
 
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            SpriteBatch sprBatch =
                (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            sprBatch.Draw(sprTexture, sprPosition, Color.White);
            base.Draw(gameTime);
        }
    }
}
Листинг 10.4. Код класса Wall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
 
namespace P10_2
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Wall : gBaseClass
    {
        public Wall(Game game, ref Texture2D _sprTexture,
            Vector2 _sprPosition, Rectangle _sprRectangle)
            : base(game, ref _sprTexture, _sprPosition, _sprRectangle)
        {
 
        }
    }
}
 

 

Механизмы сериализации и игровая логика реализованы в коде класса Game1. Его вы можете видеть в листинге 10.5.

Листинг 10.5. Код класса Game1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
 
//Классы для работы с устройствами ввода-вывода
using System.IO;
 
//Классы для работы механизмов сериализации
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace P10_2
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        //Для текстуры стены
        Texture2D txtWall;
        //Прямоугольник для создания объектов Wall
        Rectangle recSprite = new Rectangle(0, 0, 64, 64);
        //Массив объектов Wall
        Wall [,] arrayOfWalls;
        //Объект, хранящий игровые данные и подлежащий сериализации
        //Массив в этом объекте используется при загрузке игры и 
        //при сохранении игры, в игровом процессе используется
        //массив объектов Wall
        GameData MyObj;
        //Переменная для хранения состояния мыши
        MouseState mouse;
        //устройство для хранения информации
        StorageDevice sDev;
        //результат операции доступа к устройству
        IAsyncResult res;
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
 
        protected override void Initialize()
        {
            //Разрешение экрана 640х512
            graphics.PreferredBackBufferWidth = 640;
            graphics.PreferredBackBufferHeight = 512;
            graphics.ApplyChanges();
            //Сделать указатель мыши видимым
            this.IsMouseVisible = true;
            base.Initialize();
        }
 
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);
            txtWall = Content.Load<Texture2D>("wall");
            //В этом массиве лишь единицы - это значит
            //что при запуске все игровое поле заполнено
            //изображениями стен
            byte [,] arrayForGame  = new byte[8, 10] { 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            };
            //Новый массив стен
            arrayOfWalls = new Wall[8, 10];
            //Создаем объект для хранения данных,
            //передавая ему массив
            MyObj = new GameData(arrayForGame);
            //вызываем процедуру создания и 
            //вывода на экран игровых объектов
            AddSprites ();
        }
        //Создание игровых объектов
        void AddSprites()
        {
            //Просматриваем массив array в объекте типа GameData
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    if (MyObj.array[i, j] == 1)
                    {
                        //Если в массиве единица - создаем новый объект в текущей ячейке
                        //массива arrayOfWalls и добавляем в список игровых компонентов
                        arrayOfWalls[i, j] = new Wall(this, ref txtWall, new Vector2(j, i), recSprite);
                        Components.Add(arrayOfWalls[i, j]);
                    }
                }
            }
        }
        //Процедура очистки массива игровых компонентов
        void ClearAll()
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    if (arrayOfWalls[i, j] != null)
                    {
                        arrayOfWalls[i, j].Dispose();
                        arrayOfWalls[i, j] = null;
                    }
                }
            }
 
        }
        //Процедура проверки массива игровых компонентов и отражения
        //его состояния в массиве объекта типа GameData
        //в нашем случае, если ячейка массива игровых компонентов содержит
        //объект, в массив объекта GameData записывают 1, если нет - 0
        void SetWallToArray()
        {
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    if (arrayOfWalls[i, j] == null)
                    {
                        MyObj.array[i, j] = 0;
                    }
                    else
                    {
                        MyObj.array[i, j] = 1;
                    }
                }
            }
        }
        //Процедура сериализации объекта
        void serializ()
        {
            //Контейнер для хранения данных
            StorageContainer container = sDev.OpenContainer("P10_2");
            //Полное имя файла - комбинация адреса контейнера и имени
            string filename = Path.Combine(container.Path, "savegame.sav");
            //Объект, предназначенный для сериализации и десериализации других объектов
            IFormatter formatter = new BinaryFormatter();
            //Создаем новый поток для записи файла
            Stream stream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
            //Сериализуем объект MyObj в поток stream
            formatter.Serialize(stream, MyObj);
            //Закрываем поток
            stream.Close();
            //Уничтожаем контейнер
            container.Dispose();
            //выводим сообщение в заголовок игрового окна
            this.Window.Title = "Игра сохранена";
        }
        //Процедура десериализации объекта
        //похожа на процедуру десериализации
        //при десериализации файл открывают для чтения и 
        //десериализуют в объект
        void deserializ()
        {
            StorageContainer container = sDev.OpenContainer("P10_2");
            string filename = Path.Combine(container.Path, "savegame.sav");
            IFormatter formatter = new BinaryFormatter();
            //Новый поток для чтения файла
            Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
            //Получаем данные из потока и приводим их к типу MyObj
            MyObj = (GameData)formatter.Deserialize(stream);
            stream.Close();
            container.Dispose();
            this.Window.Title = "Игра загружена";
        }
 
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
 
 
        protected override void Update(GameTime gameTime)
        {
            //получим состояние клавиатуры
            KeyboardState kb = Keyboard.GetState();
            //Сохраняем игру при нажатой клавише A
            if (kb.IsKeyDown(Keys.A))
            {
                //Отразим состояние игровго окна в массиве объекта типа GameData
                SetWallToArray();
                //Получим устройство для хранения данных
                res = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One, null, null);
                sDev = Guide.EndShowStorageDeviceSelector(res);
                //Вызовем процедуру сериализации
                serializ ();
            }
            //Загружаем игру при нажатой клавише W
            if (kb.IsKeyDown (Keys .W ))
            {
                //Очищаем игровой экран
                ClearAll();
                //Получим устройство для хранения данных
                res = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One, null, null);
                sDev = Guide.EndShowStorageDeviceSelector(res);
                //Десериализуем объект из файла
                deserializ();
                //Сконструируем игровой экран на основе десериализованного 
                //объекта MyObj
                AddSprites();
            }
            //Работа с мышью
            mouse = Mouse.GetState();
            if (mouse.LeftButton == ButtonState.Pressed)
            {
                for (int i = 0; i < 8; i++)
                {
                    for (int j = 0; j < 10; j++)
                    {
                        //Если в текущей ячейке массива есть "стена"
                        //проверим, находился ли указатель мыши в пределах объекта
                        //соответствующего текущей ячейке. Если да - уничтожим объект
                        if (arrayOfWalls[i, j] != null)
                        {
                            if (arrayOfWalls[i, j].sprPosition.X + arrayOfWalls[i, j].sprRectangle.Width > mouse.X &&
                                arrayOfWalls[i, j].sprPosition.X < mouse.X &&
                                arrayOfWalls[i, j].sprPosition.Y + arrayOfWalls[i, j].sprRectangle.Height > mouse.Y &&
                                arrayOfWalls[i, j].sprPosition.Y < mouse.Y)
                            {
                                arrayOfWalls[i, j].Dispose();
                                arrayOfWalls[i, j] = null;
                            }
                        }
                    }
                }
            }
            base.Update(gameTime);
        }
 
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
 
            spriteBatch.Begin();
            base.Draw(gameTime);
            spriteBatch.End();
        }
    }
}

 

На рис. 10.3. вы можете видеть игровой экран проекта P10_2.


Рис. 10.3. Игровой экран проекта P10_2

Вопросы


1) В какой папке на ПК по умолчанию сохраняются файлы, которые создаются в процессе работы игрового проекта?

  • a. В корневом каталоге диска D
  • b. В папке, где расположен исполняемый файл игры
  • c. В папке, соответствующей игровому проекту, расположенной по адресу Мои документы\SavedGames
  • d. В корневом каталоге диска C

2) Какой тип имеет переменная, задающая контейнер для хранения игровых файлов?

  • a. File
  • b. StorageContainer
  • c. FileStream
  • d. StorageDevice

3) Какой тип имеет переменная, задающая устройство, используемое для сохранения файлов

  • a. File
  • b. StorageContainer
  • c. FileStream
  • d. StorageDevice


4) Что такое сериализация объекта?

  • a. Уничтожение объекта
  • b. Сохранение объекта в виде файла
  • c. Восстановление состояния объекта из файла
  • d. Создание нового объекта

5) Что такое десериализация объекта?

  • a. Уничтожение объекта
  • b. Сохранение объекта в виде файла
  • c. Восстановление состояния объекта из файла
  • d. Создание нового объекта

6) Какой атрибут должен иметь класс, подлежащий сериализации?

  • a. [Serializable]
  • b. [AttributeUsage]
  • c. [Author]
  • d. [Deserializable]

7) При проектировании класса, подлежащего сериализации, рекомендуется

  • a. Включать в класс как можно больше свойств, которые хранят всю информацию об игре
  • b. Включать в класс лишь ту информацию, которая необходима для реализации функций сохранения и загрузки игры

8) Какой класс содержит статические методы, которые удобно использовать при работе с именами файлов

  • a. String
  • b. FileStream
  • c. Path
  • d. File


Материал публикуется с разрешения авторов - Ю.В. Дашко, А.А. Заика

Студенческий блог MS Russia
Интернет-Университет Информационных технологий - курс разработан по гранту от Microsoft и ИНТУИТ
сайт ИУБиП

Комментарии
#1 | Misha_xD 28.05.2011 09:09:01
При выполнении данной лекции возникли проблемы с :
StorageContainer container = device.OpenContainer("P10_1"Wink;
У меня xna GameStudio 4.0 и там в принципе нет такой метода.
Есть конечно друго .BeginOpenContainer, но его конструктор меня поразил, пытался найти ответы на msdn по поводу использования этого конструктора, результат ни какой. Вот решил сюда черкануть, надеюсь кто подскажет в чем проблема или у меня или в работе.
#2 | Misha_xD 29.05.2011 12:09:54
Ау, модераторы, спецы, админы =)))
Хелп ))Всем привет
#3 | mike 30.05.2011 11:50:36
Глянь тут - 11 проблем перехода с XNA 3.x на XNA 4.0. Если не поможет, спрашивай на форуме.
#4 | Misha_xD 01.06.2011 09:03:56
Спс тебе добрый человек =)))
Я кстати, так и думал =)
Просто хотел быть уверенным. Проблема была в том, что в 4.0 этого метода нет. А который сейчас уже пытаю его =)
Спасибо.
#5 | Geralt38 08.10.2012 10:47:45
Здравствуйте, у меня возникла такая проблема:
программа говорит, что типов переменных StorageDevice и storagecontainer не сущевствует.
Что делать? код я специально для проверки копипастнул в нетронутом виде.
заранее спасибо
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Online casino players may play several variations of on casinocheatings.com.
Авторизация
Логин

Пароль



Вы не зарегистрированы?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Мини-чат
Вы должны авторизироваться, чтобы добавить сообщение.

27.08.2014
Я умею немного на asp.net + html и css

22.08.2014
на ASP mvc 3 есть пару проектов. Могу помочь, если нужно. Обидно, если закроется Frown

21.08.2014
я тоже ноль

21.08.2014
Я в вебе только с php занимался да и то на уровне чтоб работало.

21.08.2014
Я в вебе полный ноль…

21.08.2014
Переводить его надо, хоть на ту же азуру. И двиг менять на что-то современное. Если есть веб-разрабы - можем скооперироваться. Один делать не буду.

21.08.2014
не знаю всех нюансов по оплате и все хорошее когда нибудь заканчивается

21.08.2014
А что случилось?

21.08.2014
похоже сайт будет работать до 28го числа

09.08.2014
Апи пока не видел. Но есть приложение в магазине Live Lock Screen BETA, так что думаю скоро будет

08.08.2014
Я про API для Update1. На нем работает это

08.08.2014
А что именно нужно? Чтото и сейчас открыто http://msdn.micro.
...105).aspx

06.08.2014
Кто-нибудь слышал об открытии доступа к Lock Screen Api?

31.07.2014
VPDExpress на базе MVS 2012, ни в какую не ловит исключения. Даже если их сам создаешь. И всех так?

25.07.2014
С днем системного администратора причастных к этой профессии! По случаю - тортик от жены

RSS каналы сайта
XNA - Новости
XNA - Статьи
XNA - Форум
XNA - Галерея
XNA - Файлы
Время загрузки: 0,05 секунд 8,709,590 уникальных посетителей