|
Быть может кто-то из Вас знает игру Sims, к какому жанру она относиться? Жизненная симуляция, ролевая игра, там можно и дома строить..... |
Опубликован: 10.04.2009 | Доступ: свободный | Студентов: 3253 / 244 | Оценка: 4.49 / 4.39 | Длительность: 17:21:00
Темы: Компьютерная графика, Программирование, Игры
Специальности: Программист
Самостоятельная работа 10:
Работа с файлами, сериализация
Механизмы сериализации и игровая логика реализованы в коде класса Game1. Его вы можете видеть в листинге 14.5.
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.Net;
using Microsoft.Xna.Framework.Storage;
//Классы для работы с устройствами ввода-вывода
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();
}
}
}
Листинг
14.5.
Код класса Game1
На рис. 14.3. вы можете видеть игровой экран проекта P10_2.
