objectdissoedexception未处理.对象名称:'Texture2D'

本文关键字:Texture2D 未处理 对象 objectdissoedexception | 更新日期: 2023-09-27 18:08:28

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;
      }
  }
}
}

我已经在一个较小的程序中简化并复制了我的问题,以便于分享。

当我运行程序并右键点击保存,然后移动对象的位置一点,这样我就可以看到变化,然后点击中键加载游戏,我得到了错误。

我做了什么来重现错误:

  • 运行程序
  • 右键-这保存了游戏
  • 用鼠标左键点击屏幕底部-这会改变按钮的图像为"Catch - Red"
  • 将鼠标放置在屏幕左侧,使按钮移动
  • 中键点击使游戏加载之前保存的数据,按钮应该与它的第一个图像"button"居中

这就是我得到错误消息的地方objectdissoedexception未处理。对象名称:'Texture2D'。在spriteBatch.End()上;线。

无可否认,我只是从网上复制并传递了保存和加载类,我不知道每一步是如何完全工作的。

代码的目标:我希望能够保存数据,如位置,分配的内容,数组等。

objectdissoedexception未处理.对象名称:'Texture2D'

首先,你不应该在update中加载内容。它应该在"loadcontent"中完成,因此得名…你应该在load content中加载这2个纹理,然后在update中交换它们。

第二,问题是你在加载函数中再次设置texture2D。因为content.load()所做的是将纹理加载到显卡上。但是如果你重置它,那么引用就会改变。这与我的第一点有关。您应该已经加载了内容,当内容。Load被调用。所以你应该把texture2d和游戏对象分开。

例如(不会编译,但你明白的意思):

class MyGameObject
{
   public int textureIndex = 0;
   public Vector2 position = new Vector2(0, 0);
}
class Game
{
  Texture2D[] textures;
  MyGameObject poop;
  void loadContent()
  {
    textures = new Texture2D[2];
    textures[0] = Content.Load<Texture2D>("a texture");
    textures[1] = Content.Load<Texture2D>("different texture");
    poop = new MyGameObject();
    poop.textureIndex = 0;
  }
  void update()
  {
     if (mouse.Y > 600)
     {
        poop.textureIndex = 1;
     }
  }
  void draw()
  {
     spriteBatch.draw(textures[poop.textureIndex], poop.position);
  }
  ....other stuff....
}