重构XNA中的映射加载开关语句

本文关键字:加载 开关 语句 映射 XNA 重构 | 更新日期: 2023-09-27 18:11:32

我有一个switch语句,它接受一个元组,并根据元组的第二个值选择要进入哪一组嵌套switch语句。用这种方式一切都运行得很好,但是因为我需要在中心地图周围加载4个地图,以便每次平滑过渡,所以switch语句最终占用了比必要更多的空间。我正在重构一个方法,它现在只是加载并绘制基本精灵。我遇到了一些问题,内容管理器在加载精灵时收到空引用异常,不知道如何正确地将内容传递给Load方法。

下面是我在Draw中的Switch语句的缩写:

GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
Map.FindLocation(Map.LocationXY, ZoneDecider);
switch (Map.TupleHolder.Item1)
{
   case 0:
   {
      switch (Map.TupleHolder.Item2)
      {
         case 0:
            if (LoadNextMap)
            {
               if (Right)
               {
                  backgroundCenter.LoadContent(this.Content,"BackgroundBottom");
                  backgroundCenter.position = new Vector2(0, 0);
               }
               else if (Left)
               {
                  backgroundCenter.LoadContent(this.Content, "BackgroundBottom");
                  backgroundCenter.position = new Vector2(0, 0);
               }
               else if (Top)
               {
                  backgroundCenter.LoadContent(this.Content, "BackgroundBottomRight");
                  backgroundCenter.position = new Vector2(0, 0);
               }
               else if(Bottom)
               {
                  backgroundCenter.LoadContent(this.Content, "BackgroundRight");
                  backgroundCenter.position = new Vector2(0, 0);
               }
               backgroundWest.LoadContent(this.Content, "BackgroundBottom");
               backgroundWest.position = new Vector2(westTransition, 0);
               backgroundEast.LoadContent(this.Content, "BackgroundBottomRight");
               backgroundEast.position = new Vector2(eastTransition, 0);
               backgroundNorth.LoadContent(this.Content, "BackgroundMid");
               backgroundNorth.position = new Vector2(0, northTransition);
               backgroundSouth.LoadContent(this.Content, "BackgroundBottomRight");
               backgroundSouth.position = new Vector2(0, southTransition);
               LoadNextMap = false;
            }
            //new SpriteBatch(graphicsDevice)
            backgroundCenter.Draw(this.spriteBatch);
            //Drawbackground.drawBackground(backgroundWest, backgroundEast,
            // backgroundNorth, backgroundSouth);
            backgroundWest.Draw(this.spriteBatch);
            backgroundEast.Draw(this.spriteBatch);
            backgroundNorth.Draw(this.spriteBatch);
            backgroundSouth.Draw(this.spriteBatch);
            break;

这并不理想,所以为了开始重构,我将if语句的部分移到一个新方法中。

新方法

public class DrawNextBackground
{
    SpriteBatch spriteBatch;
    ContentManager theContentManager;
    public void drawBackground(Background backgroundWest,
        Background backgroundEast, Background backgroundNorth, Background backgroundSouth)
    {
        float eastTransition = 1068;
        float westTransition = -1068;
        float northTransition = -936;
        float southTransition = 936;
        backgroundWest.LoadContent(this.theContentManager, "BackgroundBottom");
        backgroundWest.position = new Vector2(westTransition, 0);
        backgroundEast.LoadContent(this.theContentManager, "BackgroundBottomRight");
        backgroundEast.position = new Vector2(eastTransition, 0);
        backgroundNorth.LoadContent(this.theContentManager, "BackgroundMid");
        backgroundNorth.position = new Vector2(0, northTransition);
        backgroundSouth.LoadContent(this.theContentManager, "BackgroundBottomRight");
        backgroundSouth.position = new Vector2(0, southTransition);
        backgroundWest.Draw(this.spriteBatch);
        backgroundEast.Draw(this.spriteBatch);
        backgroundNorth.Draw(this.spriteBatch);
        backgroundSouth.Draw(this.spriteBatch);
    }
}

Load Method:

    public void LoadContent(ContentManager theContentManager, string theAssetName)
    {
        SpriteSize = theContentManager.Load<Texture2D>(theAssetName);
    }

如何让Load方法注意到每个对象都有内容?

重构XNA中的映射加载开关语句

对于空内容,您必须将原始内容管理器(在Game1.cs中)传递给您的类才能绘制,不要尝试创建一个新的。

    //add this to the drawNextBackground class
    //where the content manager in game1.cs is "Content"
    //Content is inherited from another class, and an example
    //should be visible in the LoadContent method in game1.cs        
    public void initialize(ContentManager contentManager)
    {
          theContentManager = contentManager;
    }

如果我理解正确的话,你的加载总是有5个地图(实际地图和4个侧面地图)。

最多只加载3张地图怎么样?让我们考虑一下
你知道:
玩家(位置,速度,移动方向)
地图(大小,行走方向可以离开地图)

示例图

    ---------------------
    | P |   |   |   |   |
    ---------------------
    |   |   |   |   |   |
    ---------------------
    |   |   |   |   |   |
    ---------------------
    |   |   |   |   |   |   P = Player
    ---------------------

那么现在你可以说如果P.Position靠近地图边缘加载这个地图在这里它会在顶部,左边
这将减少你的装载成本

现在你可以通过给你的地图添加更多的细节来扩展它,让我们将它命名为Walkdirections

    ---------------------
    | X | X | X | X | X |
    ---------------------
    | P |   |   |   |   |
    ---------------------
    |   |   |   |   |   |
    ---------------------
    |   |   |   |   |   |   P = Player
    ---------------------   X = Player can't pass this field

作为地图的设计者你知道他不能在地图14的顶部所以你不需要通过检查map.Walkdirections

来加载它

保持你的旧地图,只要他在加载范围内,也许他想回去

            Map 1                Map 2
    --------------------- ---------------------
    |   |   |   |   |   | | X | X | X | X | X |
    --------------------- ---------------------
    |   |   |   |   |   | | P |   |   |   |   |
    --------------------- ---------------------
    |   |   |   |   |   | |   |   |   |   |   |
    --------------------- ---------------------
    |   |   |   |   |   | |   |   |   |   |   |   P = Player
    --------------------- ---------------------   X = Player can't pass this field
你应该随着玩家的速度增加加载范围

我希望这对你有帮助
顺便说一下,我现在对XNA一无所知