using System;
using System.Collections.Generic;
using System.Linq;
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.Media;
using Microsoft.Xna.Framework.Storage;
using System.IO;
using System.Xml.Serialization;
namespace ButtonGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
MouseState mouse, prevMouse;
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public IAsyncResult result;
public Object stateobj;
public bool GameSaveRequested = false;
public GamePadState currentState;
public class GameImages
{
//Image Diminsions and Graphic
public Texture2D texture;
//Images position on the Viewport
public Vector2 position = new Vector2(0, 0);
}//GameImages
GameImages button;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.PreferMultiSampling = false;
graphics.IsFullScreen = false;
}//Game1()
protected override void Initialize()
{
button = new GameImages();
base.Initialize();
}//Initialize
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
//Gives the button the graphic "button.PNG" from resources
button.texture = Content.Load<Texture2D>("Button");
//Sets the drawing point of the button to the middle of the screen
button.position = new Vector2(300, 400);
}
protected override void Update(GameTime gameTime)
{
//Gets current position and condition of the mouse
mouse = Mouse.GetState();
//Makes the cursor visible on the screen of the game
this.IsMouseVisible = true;
//If the User has released the Left mouse button and previously had it pressed, (Left Clicked)
if (mouse.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Released && prevMouse.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
{
//Check if the mouse was within the bounds of GameImage button
if (CheckForClick(button))
{
//Remove the button from view
button.position = new Vector2(5000, 5000);
}
if (mouse.Y > 600)
{
button.texture = Content.Load<Texture2D>("Catch - Red");
}
}
if (mouse.X < 50)
{
button.position.X += 3;
}
else if (mouse.X > 500)
{
button.position.X -= 3;
}
//If the User has released the Right mouse button and previously had it pressed, (Right Clicked)
else if ((mouse.RightButton == Microsoft.Xna.Framework.Input.ButtonState.Released && prevMouse.RightButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed))
{
//Bring Back the button
//button.position = new Vector2(300,400);
InitiateSave();
}
else if ((mouse.MiddleButton == Microsoft.Xna.Framework.Input.ButtonState.Released && prevMouse.MiddleButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed))
{
InitiateLoad();
}
//Store the current mouse position and conditon into a orevious state to prepare for new input
prevMouse = mouse;
base.Update(gameTime);
}//Update
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
//Background Color
GraphicsDevice.Clear(Color.CornflowerBlue);
//if button is not off the screen
if (button.position != new Vector2(5000, 5000))
{
//Draw the button
DrawImage(button);
}
spriteBatch.End();
base.Draw(gameTime);
}//Draw
public void DrawImage(GameImages image)
{
spriteBatch.Draw(image.texture, image.position, Color.White);
}//DrawImage
public bool CheckForClick(GameImages rectangle)
{
if (mouse.Y < rectangle.position.Y + rectangle.texture.Height &&
mouse.Y > rectangle.position.Y &&
mouse.X > rectangle.position.X &&
mouse.X < rectangle.position.X + rectangle.texture.Width)
return true;
else
return false;
}//CheckForClick
StorageDevice device;
string containerName="MyGamesStorage";
string filename = "mysave.sav";
public struct SaveGame
{
public Vector2 buttonPosition;
public Texture2D newbuttonTexture;
}//Save Game
private void InitiateSave()
{
device = null;
StorageDevice.BeginShowSelector(PlayerIndex.One, this.SaveToDevice, null);
}
void SaveToDevice(IAsyncResult result)
{
device = StorageDevice.EndShowSelector(result);
if (device != null && device.IsConnected)
{
SaveGame SaveData = new SaveGame()
{
buttonPosition = button.position,
newbuttonTexture = button.texture,
};
IAsyncResult r = device.BeginOpenContainer(containerName, null, null);
result.AsyncWaitHandle.WaitOne();
StorageContainer container = device.EndOpenContainer(r);
if (container.FileExists(filename))
container.DeleteFile(filename);
Stream stream = container.CreateFile(filename);
XmlSerializer serializer = new XmlSerializer(typeof(SaveGame));
serializer.Serialize(stream, SaveData);
stream.Close();
container.Dispose();
result.AsyncWaitHandle.Close();
}
}
private void InitiateLoad()
{
device = null;
StorageDevice.BeginShowSelector(PlayerIndex.One, this.LoadFromDevice, null);
}
void LoadFromDevice(IAsyncResult result)
{
device = StorageDevice.EndShowSelector(result);
IAsyncResult r = device.BeginOpenContainer(containerName, null, null);
result.AsyncWaitHandle.WaitOne();
StorageContainer container = device.EndOpenContainer(r);
result.AsyncWaitHandle.Close();
if (container.FileExists(filename))
{
Stream stream = container.OpenFile(filename, FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(SaveGame));
SaveGame SaveData = (SaveGame)serializer.Deserialize(stream);
stream.Close();
container.Dispose();
//Update the game based on the save game file
button.position = SaveData.buttonPosition;
button.texture = SaveData.newbuttonTexture;
}
}
}
}
我已經簡化並在較小的程序中再現了我的問題,因此它更易於共享。ObjectdispsoedException未處理無法訪問處置的對象。對象名稱:'Texture2D'
當我運行程序並右鍵單擊保存,然後移動對象的位置有點,所以我可以看到一個變化,然後中間點擊加載遊戲,我得到的錯誤。
我做什麼重現錯誤:
- 運行程序
- 右鍵 - 這個保存的遊戲鼠標經過屏幕的底部
- 左擊 - 這改變了按鈕的圖像爲「Catch - Red」
- 將鼠標置於屏幕左側,以便按鈕移動
- 中間點擊以便遊戲加載之前保存的數據,按鈕應居中它的第一個圖像「按鈕」
這是我得到的錯誤信息 ObjectdispsoedException了未處理無法訪問已釋放的對象。對象名稱:'Texture2D'。在spriteBatch.End()上的 ;線。
不可否認,我只是複製並通過互聯網上的保存和加載類,我不知道每一步如何完全工作。
代碼的目標:我希望能夠保存數據,例如位置,分配的內容,數組等,以便稍後再次加載。
直到有人有更好的答案走來: 由於我在與content.load /圖像的麻煩,我m只是保存數字變量並使用它們來重新加載圖像數據。 即;調用一個指定int變量的方法, public int numImageSaver; 當用戶點擊保存按鈕時,分配變量numImageSaver = 1; 然後在savetodevice方法,保存numImageSaver, 當用戶加載數據,抓住numImageSaver從可變後在保存文件。 然後調用如果(numImageSaver == 1){button.texture = ...) –
研究由線代碼行後,我意識到SAVEDATA沒有轉移,將破譯的數量與if或切換 的方法GameImages的紋理部分。爲了解決這個問題,我只需在變量從Savedata獲取分配數據之後調用一個方法。這個方法必須爲你計劃在當前屏幕上使用的每一個紋理賦值(如果你做了一些加載或分配一個新紋理的東西(點擊/類型),你不需要把它加載到這個方法中。) –