如何为基于 2D 图块的游戏定义图块结构?

发布于 2024-11-19 21:33:22 字数 959 浏览 1 评论 0原文

我正在制作一个基于 2d 图块的游戏,并且我尝试通过使用位字段和字节作为图块结构中的值来保持我的图块结构较小:

struct Tile
{
    // 3 bytes (24 bits)
BYTE i : 8; // Texture index (0-255)
BYTE p : 1; // Passable (0-1)
BYTE x : 7; // Texture x (0-127)
BYTE y : 7; // Texture y (0-127)
BYTE v : 1; // Visible (0-1)
};

所以如果我有一个 1024x1024 图块的 2d 数组,那么它只有大约当我从高清保存/加载时,内存为 3MB。

但现在我需要动画图块,因此我需要额外的数据,例如

struct Tile
{
#define TILE_NORMAL     0
#define TILE_ANIMATED   1
    BYTE tile_type;

    // 3 bytes (24 bits)
    BYTE i : 8; // Texture index (0-255)
BYTE p : 1; // Passable (0-1)
BYTE x : 7; // Texture x (0-127)
BYTE y : 7; // Texture y (0-127)
BYTE v : 1; // Visible (0-1)

    // For animated tiles
    BYTE frame;
    BYTE maxFrame;
    float frameTime;
};

每个图块上的数据,并且由于 2D 数组的定义如下:

Tiletiles[x][y];

每个图块大约有 10 个字节,尽管只有一小部分图块是动画的。

我正在考虑存储一个 2D 指针数组,然后每个指针都指向普通图块或动画图块,但这意味着每个指针都是 4 个字节,并且指向至少 4-10 个字节。

I'm making a 2d tile based game, and I've tried to keep my tile structure small by using bit fields and bytes for the values in the tile structure:

struct Tile
{
    // 3 bytes (24 bits)
BYTE i : 8; // Texture index (0-255)
BYTE p : 1; // Passable (0-1)
BYTE x : 7; // Texture x (0-127)
BYTE y : 7; // Texture y (0-127)
BYTE v : 1; // Visible (0-1)
};

so if i have a 2d array of 1024x1024 tiles, then its only around 3mb in memory and when i save/load from hd.

But now I need animated tiles, so I need extra data like,

struct Tile
{
#define TILE_NORMAL     0
#define TILE_ANIMATED   1
    BYTE tile_type;

    // 3 bytes (24 bits)
    BYTE i : 8; // Texture index (0-255)
BYTE p : 1; // Passable (0-1)
BYTE x : 7; // Texture x (0-127)
BYTE y : 7; // Texture y (0-127)
BYTE v : 1; // Visible (0-1)

    // For animated tiles
    BYTE frame;
    BYTE maxFrame;
    float frameTime;
};

On each of the tiles, and since the 2D array is defines like:

Tile tiles[x][y];

Each tile would be around 10 bytes, even though a very small proportion of the tiles are animated.

I was thinking to store a 2D array of pointers, and then each points to either a normal tile or a animated one, but that would mean every pointer is 4 bytes, and points to atleast 4-10 bytes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

絕版丫頭 2024-11-26 21:33:23

你能让这个结构成为一个联合吗?例如(请原谅任何语法错误,我不记得确切的语法):

struct Tile
{
#define TILE_NORMAL     0
#define TILE_ANIMATED   1
    BYTE tile_type;

    // 3 bytes (24 bits)
    BYTE i : 8; // Texture index (0-255)
    BYTE p : 1; // Passable (0-1)
    BYTE v : 1; // Visible (0-1)
    BYTE x : 7; // Texture x (0-127)
    BYTE y : 7; // Texture y (0-127)

    union
    {
        struct AnimatedTileData
        {
            // For animated tiles
            BYTE frame;
            BYTE maxFrame;
            float frameTime;
        };

        struct NoData
        {
        };
    };
};

因此,这样,您就有一个额外的字节来说明它是否是动画的。如果它不是动画的,那么将使用“NoData”,不增加任何开销。如果图块是动画的,则添加 6 个开销字节用于动画相关数据。

Could you make the struct a union? For example (and please pardon any syntax errors, I don't remember the exact syntax):

struct Tile
{
#define TILE_NORMAL     0
#define TILE_ANIMATED   1
    BYTE tile_type;

    // 3 bytes (24 bits)
    BYTE i : 8; // Texture index (0-255)
    BYTE p : 1; // Passable (0-1)
    BYTE v : 1; // Visible (0-1)
    BYTE x : 7; // Texture x (0-127)
    BYTE y : 7; // Texture y (0-127)

    union
    {
        struct AnimatedTileData
        {
            // For animated tiles
            BYTE frame;
            BYTE maxFrame;
            float frameTime;
        };

        struct NoData
        {
        };
    };
};

So, in this way, you have one extra byte to say whether it is animated or not. If it is not animated, then 'NoData' will be used, added no overhead. If the tile is animated, then the 6 overhead bytes are added for animation related data.

纸伞微斜 2024-11-26 21:33:22

如果您想节省内存,请勿将动画数据存储在图块本身中。相反,您可以在游戏程序中定义一个单独的结构,例如:

struct AnimationSequence
{
    BYTE first;
    BYTE current;
    BYTE frames[];
    float frametime;
}

然后您可以定义一个由其中几个组成的数组,它们代表每种类型的动画图块及其动画方式。然后,在动画计时器中循环遍历该数组,对照屏幕上的图块进行检查,并根据需要重新绘制它们。

为了节省更多内存,您可能需要考虑的另一件事是不要在图块数据中存储 X/Y 坐标值。我假设您的 X/Y 字节代表图块在屏幕上绘制的位置,或类似的东西。您可以尝试将坐标值附加到游戏的视图窗口自己的数组中,而不是附加到图块本身,这样您就只有一个视图窗口的图块可用作绘制它们时的查找列表到屏幕上,而不是整个地图的价值。

If you want to save memory, don't store the animation data in the tiles themselves. Instead, you could define a separate struct in your game program, such as:

struct AnimationSequence
{
    BYTE first;
    BYTE current;
    BYTE frames[];
    float frametime;
}

Then you could define an array of a couple of these which represent each type of tile that animates, and how it animates. Then, in your animation timer, cycle through this array, check it against the tiles on the screen, and redraw them as needed.

Another thing you might want to consider, to save more memory, is not storing X/Y coordinate values in the tile data. I'm assuming your X/Y bytes represent the position the tile is drawn on the screen, or something similar. You could try attaching the coordinate values to the view window of the game in their own array, rather than to the tiles themselves, so that you would only have one view window worth of tiles to serve as a lookup list for when you are drawing them to the screen, rather than a whole map's worth.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文