在XNA中重构map loading switch语句

时间:2013-04-30 07:46:53

标签: c# oop xna

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

这是我在Draw中删除的开关语句:

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

加载方法:

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

如何让Load方法注意每个对象都有内容?到目前为止我尝试的所有东西都没用。

2 个答案:

答案 0 :(得分:2)

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

关于在Max加载仅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
对P.Speed来说,你应该用播放器的速度增加加载范围

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

答案 1 :(得分:2)

对于null内容,您必须将原始内容管理器(在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;
    }