侧边滚动一个平铺地图,地图变得混乱

本文关键字:地图 混乱 一个 滚动 | 更新日期: 2023-09-27 18:16:52

我成功地生成了我的贴图,它的工作,但当我想滚动它的瓷砖的顶部行是移动的,所有的瓷砖被拖出屏幕。很难解释,

想象这是贴图:X

XXXXXXXXXXXXXXXXXXXXXXXXXX//当摄像机移动时,它开始逐块移除

XXXXXXXXXXXXXXXXXXXXXXXXXX//导致所有其他瓷砖向上移动到我的线。

XXXXXXXXXXXXXXXXXXXXXXXXXX

XXXXXXXXXXXXXXXXXXXXXXXXXX

看一下我的代码:

public void Draw(SpriteBatch spriteBatch)
{
    currentLevel = level1;
    //Its here i need the value from Player class!
    int currentX = cameraX; //The current x cordiate to draw the tile too
    int currentY = 0; //The current y cordiate to draw the tile too
    for (int i = 0; i < currentLevel.Length; i++)
    {
        /*
         * A switch statement to see if the current level1[i] is either a grass, sky or stone tile
         */
        switch(currentLevel[i])
        {
            case 1:
                //Draw a sky tile
                spriteBatch.Draw(tileSheet, new Rectangle(currentX, currentY, 32, 32), skyTile, Color.White);
                break;
            case 2:
                //Draw a grass tile
                spriteBatch.Draw(tileSheet, new Rectangle(currentX, currentY, 32, 32), grassTile, Color.White);
                break;
            case 3:
                //Draw a stone tile
                spriteBatch.Draw(tileSheet, new Rectangle(currentX, currentY, 32, 32), stoneTile, Color.White);
                break;
        }
        //Add 32 to the current cordinate so we don't draw to the same spot all the time
        currentX = currentX + 32; 
        if (currentX >= 896) //If we hit the width of the map we want:
        {
            //Start drawing from X cordinate zero
            cameraX = 0;
            currentX = cameraX;
            //And Y cordinate + 32
            currentY = currentY + 32;
            //This will make so we draw one line and when we hit a full line on the map then we draw next line and soo on.
        }
    }
}

CameraX变量是来自Player类的getter。当按住键盘上的左键时,该值将递减。

这是我从数组(1 = sky, 2 = grass, 3 = stone)绘制的贴图:

int[] level1 = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3,
                         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3};

任何想法?

侧边滚动一个平铺地图,地图变得混乱

看起来你总是在绘制整个地图中的所有贴图(i从0开始,循环遍历每个贴图)。但是,您并不总是在每行上绘制相同数量的瓷砖。如果CameraX为0,那么您将每行绘制28个贴图,因为您将在32*28(896)像素之后移动到下一行。但是如果CameraX是480,那么您将只在每行上绘制13((896-480)/32)块,而第一行的其余块将绘制在第二行上(因为您仍然试图绘制所有块)。我认为你应该循环遍历你想要绘制的每一行和每一列,并从中计算tile索引,而不是循环遍历地图中的每个tile并独立计算位置。

编辑下面是一些示例代码,用于在给定列和行索引的一维数组中计算tile索引,假设您知道列的数量。(或者你可以直接切换到使用二维数组):

i = row * columnCount + column;

我认为您的问题是,当您到达一行的末尾时,您将CameraX设置为0

你不想在每行结束时移动摄像机,你只想重置x绘图位置(就像在下一行所做的那样)。

因此,删除cameraX = 0;

我不能100%肯定这会导致你所描述的问题,但它绝对是不对的,正如你所说的玩家控制cameraX,所以它不应该在你的绘制功能中改变。

我真的不明白你的代码,但我建议你使用二维数组或访问一维数组在一个适当的方式,如array[ Y * ARRAY_Width + X]。除此之外,你为什么要在整个关卡中开始循环呢?相机内部的内容很重要,否则你将迭代许多不可见的tile。

从你的相机X和Y开始,计算你在相机视口内绘制的水平和垂直瓷砖的数量:这些应该是你需要迭代的唯一瓷砖。而且你似乎在移动瓷砖。你要移动摄像机,而不是你的瓷砖。SpriteBatch.Begin有一个过载来设置包含相机运动的矩阵。如果你不知道如何使用矩阵,只需调用

Matrix view = Matrix.CreateTranslate(new Vector3( myCam.X, myCam.Y, 0));

并将其作为视图矩阵传递给BeginSprite方法。

这些更改将使您的代码更容易。

希望对你有帮助。