帮助C#程序设计实现:多列表或更好的方法?

时间:2010-03-18 19:11:11

标签: c# xna

我正在XNA中创建一个基于2D磁贴的RPG,并处于初始设计阶段。我在想我的瓷砖引擎是如何工作的,并想出了粗略的草图。基本上我想要一个瓷砖网格,但在每个瓷砖位置,我希望能够添加多个瓷砖并具有偏移量。我喜欢这样,所以我可以做一些事情,比如在世界地图上添加单独的树,以提供更多的天赋。或者在某个城镇的酒吧里放瓶子,而不必用不同的瓶子画出一堆不同的酒吧瓷砖。

但也许我的影响力超过了我的掌握。我去实现这个想法,并在我的Map对象中有这样的东西:

List<Tile>[,] Grid;

但后来我想到了。假设我有一个200x200的世界地图,就RPG而言,它实际上相当小。这将达到40,000个列表。在我看来,我认为必须有一个更好的方法。现在这是预先成熟的优化。我不知道我碰巧设计我的地图和游戏的方式是否能够处理这个问题,但是如果我的游戏变得更加复杂的话,它似乎也会毫无效率地出现,并且可能会出现问题。

我的一个想法是使偏移和多个图块可选,这样我只需要在需要时付费。但我不确定我是怎么做到的。多个对象数组?

object[,] Grid;

所以这是我的标准:

  • 瓷砖位置的2D网格
  • 每个图块位置至少有1个图块,但可以选择包含更多
  • 每个额外的图块可以选择具有x和y偏移以进行精确放置

任何人都可以帮助实现这样的设计的一些想法(不需要为我做,只需要想法),同时将内存使用量降至最低?

如果你需要更多背景,那么我的Map和Tile对象大致相当于:

public struct Map
{
    public Texture2D Texture;
    public List<Rectangle> Sources; //Source Rectangles for where in Texture to get the sprite
    public List<Tile>[,] Grid;
}
public struct Tile
{
    public int Index; //Where in Sources to find the source Rectangle
    public int X, Y; //Optional offsets
}

3 个答案:

答案 0 :(得分:4)

你能做的就是拥有一个Tile数组:

class Grid
{
    Tile[,] grid;
}

...让Tile课程中包含List<Sprite>

class Tile
{
    List<Sprite> sprites;
}

......而且Sprite类会有你的纹理和偏移量:

class Sprite
{
    Vector2 offset;
    Texture2D texture;
}

通过绘制方法完成所有这些:

class Grid
{
    Tile[,] grid;

    void Draw(GraphicsDevice graphics)
    {
        // call your tiles Draw()
    }


}

class Tile
{
    List<Sprite> sprites;
    void Draw(GraphicsDevice graphics, int x, int y)
    {
        // call your sprites Draw()
    }
}

class Sprite
{
    Vector2 offset;
    Texture2D texture; // or texture and rectangle, or whatever

    void Draw(GraphicsDevice graphics, int x, int y)
    {
        // draw the sprite to graphics using x, y, offset and texture
    }
}

当然它比这复杂得多,但你应该明白这一点。

将您在不同类中的所有问题分开,可以轻松添加不会与现有代码冲突的新功能。尝试将所有数据混合在单个对象(例如List&lt; Tile&gt; [,])中是不好的形式,并且在您尝试扩展时最终会咬你。

答案 1 :(得分:1)

您的方法似乎使演示与行为混淆。如果游戏的行为是基于区块的,那么在功能上进行设计,然后根据董事会的状态编写演示文稿。

答案 2 :(得分:1)

你基本上想要一个稀疏矩阵来表示每个图块上的“装饰”。稀疏矩阵是矩阵结构,其中并非所有元素都需要具有值。那里有代表它们的C#库。

一种简单的方法是使用普通字典,其中键是Tile#(每个图块的唯一编号),例如可以使用与用于处理视频存储器的相同类型的公式计算:Y * MAXIMUM_X + X对于给定的图块,只需检查是否有一个条目为其唯一的图块#。字典应该包含该特定图块的装饰列表:

Dictionary<int, List<Sprites>> spritesPerTile;
// ...
if (spritesPerTile.ContainsKey(tileNumber))
{
    List<Sprites> decorationsThisTile = spritesPerTile[tileNumber];
    // Proceed to render sprites on this tile.
}