Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何为基于2D平铺的游戏定义平铺结构?_C++_Tiles - Fatal编程技术网

C++ 如何为基于2D平铺的游戏定义平铺结构?

C++ 如何为基于2D平铺的游戏定义平铺结构?,c++,tiles,C++,Tiles,我正在制作一个基于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

我正在制作一个基于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阵列,那么当我从hd保存/加载时,它的内存只有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;
};
在每个平铺上,由于二维阵列的定义如下:

瓷砖[x][y]

每个磁贴大约有10个字节,即使很小一部分磁贴是动画的


我想存储一个2D指针数组,然后每个指针指向一个普通平铺或一个动画平铺,但这意味着每个指针都有4个字节,并且至少指向4-10个字节。

你能将结构合并吗?例如(请原谅任何语法错误,我不记得确切的语法):


因此,通过这种方式,您有一个额外的字节来表示它是否为动画。如果未设置动画,则将使用“NoData”,不会增加开销。如果互动程序已设置动画,则会为动画相关数据添加6个开销字节。

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

struct AnimationSequence
{
    BYTE first;
    BYTE current;
    BYTE frames[];
    float frametime;
}
然后,您可以定义一个数组,其中包含两个表示动画的每种类型的平铺及其动画方式的平铺。然后,在动画计时器中,循环此数组,对照屏幕上的瓷砖进行检查,并根据需要重新绘制


另外,为了节省更多内存,您可能需要考虑的是,不要将瓦片数据中的X/Y坐标值存储起来。我假设您的X/Y字节表示在屏幕上绘制磁贴的位置,或者类似的位置。您可以尝试将坐标值附加到游戏的视图窗口(以其自己的数组形式),而不是磁贴本身,这样,当您将它们绘制到屏幕上时,只有一个视图窗口的磁贴可用作查找列表,而不是整个地图的价值。

你是在为一个8MB内存的游戏机编程吗?你确定这是一个瓶颈吗?gameboy是怎么做到的?我记得口袋妖怪有很多地图,有些是静态的,有些是静态的animated@Kaije:他们过去一次只加载一个子集,足以填满几个屏幕。而且,只有几种类型的分片(每个分片可能有一个字节),映射也没有那么大。IIRC,来自Zelda Link的觉醒的地图有点像512x512,整个ROM安装在几百千字节中。但是联盟总是会为最大的数据类型消耗内存,不管它是否被使用。用这个没法省钱。呸!你是对的。我不知道工会是这样运作的。抱歉。瓷砖中存储的x和y是纹理位置,我有一个1024x1024像素的大精灵表,上面有32x32个瓷砖图像,以获得我喜欢的纹理“矩形”:rect.left=(tile.x*tile_WIDTH),rect.right=rect.left+tile_WIDTH。然后把它画到屏幕上。实际的tile由两个for循环定位,x和y增加32。但是您已经有了tile.index,它告诉您相同的事情,因此x和y是冗余的。(tile.index%32)*32将为您提供sprite工作表中的tile的X像素位置,math.floor(tile.index/32)*32将为您提供Y像素位置。可以在绘制时动态计算这些位置(这可能会使处理速度稍慢),也可以一次性计算所有位置并将其保存在查找列表数组中。(假设tile.index表示sprite工作表中的特定矩形或对象;虽然我不认为最大值为255是可能的,所以我可能错了。)tile index是纹理的索引,我说过我有一个1024x1024纹理,但实际上数组中有很多纹理,因此,每个平铺上的纹理id是它们用来渲染的纹理,如Draw(纹理[tile.i],&rect);
struct AnimationSequence
{
    BYTE first;
    BYTE current;
    BYTE frames[];
    float frametime;
}