Возможно вы искали: 'Disciples 2: Dark Prop...'

May 12 2025 01:24:28
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96030355
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18346
• Обзор The Walking ... 18789
• Обзор DMC: Devil M... 19864
• Обзор на игру Valk... 15867
• Обзор на игру Stars! 17754
• Обзор на Far Cry 3 17935
• Обзор на Resident ... 16012
• Обзор на Chivalry:... 17495
• Обзор на игру Kerb... 17970
• Обзор игры 007: Fr... 16604
Превью о играх
• Превью к игре Comp... 17946
• Превью о игре Mage... 14451
• Превью Incredible ... 14706
• Превью Firefall 13462
• Превью Dead Space 3 16325
• Превью о игре SimC... 14717
• Превью к игре Fuse 15432
• Превью Red Orche... 15532
• Превью Gothic 3 16334
• Превью Black & W... 17345
Главная » Статьи » Всё о XNA » Работа с файлами

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

Практически все игры используют какие-либо внешние данные. В частности, подавляющее большинство игр содержит возможности сохранения игрового процесса в его текущем состоянии и его загрузки, игры хранят во внешних файлах статистические данные, загружают из файлов дополнительные уровни. 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
{
    /// 
    /// This is a game component that implements IUpdateable.
    /// 
    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
{
    /// 
    /// This is the main type for your game
    /// 
    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
2477 Прочтений •  [Работа с файлами] [08.08.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Работа с файлами Ukraine Vova 08.08.2012
• Работа с DBF файлами в Perl (dbf pe... Ukraine Vova 08.05.2012
• Работа с бинарными файлами на Perl ... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка