WP7 захоронение, сохранение спрайта в текущем состоянии не работает
Я работаю над игрой WP7. Я использую управление состоянием игры (http://create.msdn.com/en-US/education/catalog/sample/game_state_management, но думаю, что это не важно) У меня проблема с сохранением данных в Microsoft.Phone.Shell.PhoneApplicationService.Текущее состояние
если я положу туда спрайт в этом методе
public override void Deactivate()
{
#if WINDOWS_PHONE
Microsoft.Phone.Shell.PhoneApplicationService.Current.State["Score"] = Score;
Microsoft.Phone.Shell.PhoneApplicationService.Current.State["cloudSprite"] = cloudSprite;
#endif
base.Deactivate();
}
в этом нет ничего
Microsoft.Phone.Shell.PhoneApplicationService.Current.State
в активировать метод. Однако, если я удаляю cloudSprite и помещаю туда только Score, то это работает нормально. Я не знаю, что не так, может быть, он не может обрабатывать более сложные объекты. Я попробовал также поплавок, все работает. Но если я добавлю что-то более сложное, это не сработает. Как вы думаете?
РЕДАКТИРОВАТЬ
Это мой класс спрайтов. Я не знаю, как сделать его сериализуемым. Я добавил туда [DataContractAttribute()] и [DataMember], но он не работает
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using System.Runtime.Serialization;
using System.IO;
namespace GameStateManagementSample.GameObjects
{
[DataContractAttribute()]
public class Sprite
{
[DataMember]
public Vector2 Position;
[DataMember]
public Vector2 Size;
[DataMember]
public Texture2D Texture;
[DataMember]
public Rectangle Rect
{
get
{
return new Rectangle((int)Position.X, (int)Position.Y, (int)Size.X, (int)Size.Y);
}
}
public Sprite(Vector2 position)
{
Position = position;
}
public Sprite(Vector2 position, Vector2 size)
{
Position = position;
Size = size;
}
public Sprite(Vector2 position, Texture2D texture)
{
Position = position;
Texture = texture;
Size = new Vector2(Texture.Width, Texture.Height);
}
public void LoadContent(string assetName, ContentManager content)
{
Texture = content.Load<Texture2D>(assetName);
if (Size == Vector2.Zero)
Size = new Vector2(Texture.Width, Texture.Height);
}
public virtual void Draw(SpriteBatch spriteBatch)
{
//spriteBatch.Draw(Texture, Rect, Color.White);
spriteBatch.Draw(Texture, Position, Color.White);
}
public virtual void Draw(SpriteBatch spriteBatch, Rectangle TexturePositionInSpriteSheet, Color color)
{
spriteBatch.Draw(Texture, Position, TexturePositionInSpriteSheet, color);
}
public bool Intersects(Vector2 point)
{
if (point.X >= Position.X && point.Y >= Position.Y && point.X <= Position.X + Size.X && point.Y <= Position.Y + Size.Y)
return true;
else return false;
}
public bool Intersects(Rectangle rect)
{
return Rect.Intersects(rect);
}
public static void Serialize(Stream streamObject, object objForSerialization)
{
if (objForSerialization == null || streamObject == null)
return;
DataContractSerializer ser = new DataContractSerializer(objForSerialization.GetType());
ser.WriteObject(streamObject, objForSerialization);
}
public static object Deserialize(Stream streamObject, Type serializedObjectType)
{
if (serializedObjectType == null || streamObject == null)
return null;
DataContractSerializer ser = new DataContractSerializer(serializedObjectType);
return ser.ReadObject(streamObject);
}
}
}
2 ответа
Объекты добавлены в State
коллекции сериализуются с помощью DataContractSerializer. Убедитесь, что все, что вы сохраняете, может быть сериализовано таким образом.
Любые ошибки сериализации игнорируются.
Обновить
Вот упрощенная версия вашего объекта Sprite:
[DataContract]
public class Sprite
{
[DataMember]
public Vector2 Position;
[DataMember]
public Vector2 Size;
[DataMember]
public Texture2D Texture;
public Sprite()
{
}
public Sprite(Vector2 position)
{
Position = position;
}
public Sprite(Vector2 position, Vector2 size)
{
Position = position;
Size = size;
}
public Sprite(Vector2 position, Texture2D texture)
{
Position = position;
Texture = texture;
Size = new Vector2(Texture.Width, Texture.Height);
}
}
И вот пример его сериализации и десериализации:
// Тест сериализации Sprite var sprite1 = new Sprite(new Vector2(12.34f, 56.78f));
Sprite sprite2;
using (var memStr = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(Sprite));
serializer.WriteObject(memStr, sprite1);
memStr.Position = 0;
var sr = new StreamReader(memStr);
var serialized = sr.ReadToEnd();
// serialized now looks like
// <Sprite xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MiscExperiments"><Position xmlns:d2p1="http://schemas.datacontract.org/2004/07/Microsoft.Xna.Framework"><d2p1:X>12.34</d2p1:X><d2p1:Y>56.78</d2p1:Y></Position><Size xmlns:d2p1="http://schemas.datacontract.org/2004/07/Microsoft.Xna.Framework"><d2p1:X>0</d2p1:X><d2p1:Y>0</d2p1:Y></Size><Texture xmlns:d2p1="http://schemas.datacontract.org/2004/07/Microsoft.Xna.Framework.Graphics" i:nil="true" /></Sprite>
memStr.Position = 0;
sprite2 = (Sprite)serializer.ReadObject(memStr);
// sprite2 now contains the same as
// sprite2.Position = { X:12.34, Y:56.78 }
}
Я считаю, что вы получаете ArgumentOutOfRangeException, который игнорируется, если вы не отлаживаете (в этом случае выдается исключение). Элементы, хранящиеся в государственном словаре, должны быть сериализуемыми. Попробуйте как-то сохранить этот спрайт и сохранить только ссылку (источник) на спрайт в словаре состояний.