瓷砖尺寸算法

发布于 2024-08-14 18:23:05 字数 943 浏览 2 评论 0原文

我正在用 C++ 制作一个瓷砖游戏。现在,当游戏加载时,所有图块都根据以下条件自行放置:

tilesize ->它们是正方形,所以这是宽度和高度

tile_count_xtile_count_y

有以下变量:

desktop_widthdesktop_heightgame_window_widthgame_window_heighttile_count_xtile_count_y

窗口

大小

适当

基于这些值,我正在寻找一种算法,该算法将在给定桌面和tile_count约束的情况下设置 然后,在此范围内,我希望我的图块有一个偏移量,该偏移量将在窗口周围与 x% 接壤,这也基本上决定了图块大小:

示例: 如果我有 10 * 3 块瓷砖,那么:

______________________________
Window Title              _[]X
------------------------------
|                            |
|    [][][][][][][][][][]    | 
|    [][][][][][][][][][]    |
|    [][][][][][][][][][]    |
|                            |
------------------------------

我只是不确定执行此操作所需的公式。

编辑(来自评论):

  • Tilesize更改,tilecountx和y是静态的
  • 我希望游戏窗口尽可能大,因为它可以给定桌面分辨率,但我也希望它的纵横比尊重tilecoutx和tilecounty

我找到了一个例子我的意思是,在 Windows 中打开扫雷

I'm making a tile game in c++. Right now when the game loads all the tiles place themselves based on:

tilesize -> they are squares so this is width and height

tile_count_x

tile_count_y

I have the following variables:

desktop_width

desktop_height

game_window_width

game_window_height

tile_count_x

tile_count_y

Based on these values, I'm looking for an algorithm that will set an appropriate window size given the desktop and tile_count constraints. Then within this, I want my tiles to have an offset that will border x% around the window which will basically decide the tilesize too:

Example:
If I have 10 * 3 of tiles then:

______________________________
Window Title              _[]X
------------------------------
|                            |
|    [][][][][][][][][][]    | 
|    [][][][][][][][][][]    |
|    [][][][][][][][][][]    |
|                            |
------------------------------

I'm just not sure the formula required to do this.

EDIT (from comments):

  • Tilesize changes, tilecountx and y are static
  • I want the gamewindow to be as big as it can be given the desktop resolution, but I also want its aspect ratio to respect the tilecoutx and tilecounty

I found an example of what I mean, open up Minesweeper in Windows

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

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

发布评论

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

评论(4

没︽人懂的悲伤 2024-08-21 18:23:05

我不是 C++ 程序员,但您应该从中得到一些东西:

// Amount of padding to leave around tiles (of window size)
int percentage = 10;

tile_ratio = tile_count_x / tile_count_y;
desktop_ratio = desktop_width / desktop_height;

// Determine the maximum window width and height
// according to tile and desktop aspect ratios
if(tile_ratio >= desktop_ratio) {
    window_width = desktop_width;
    window_height = window_width * (1 / tile_ratio);
} else {
    window_height = desktop_height;
    window_width = window_height * tile_ratio;
}

// Determine maximum width and height for tiles,
// taking account x% of padding on both sides, hence the * 2
tile_width = window_width * ((100 - (percentage * 2)) / 100);
tile_height = window_height * ((100 - (percentage * 2)) / 100);

// As the tiles must be square, determine the smaller side as the size
tile_size = tile_width < tile_height ? tile_width : tile_height;

// To maintain the x% padding, we must calculate the window size again as we just changed the tilesize
factor = (100 / (100 - (percentage * 2)));
window_width = tile_size * tile_count_x * factor;
window_height = tile_size * tile_count_y * factor;

现在您拥有最大窗口宽度和高度,以便:

  1. 窗口的宽高比与图块相同
  2. 窗口不大于桌面
  3. 窗口有瓷砖所有边周围填充的 x%

请注意,我根本没有测试过这段代码,但它应该可以工作。如果您发现任何错误,请尝试了解我尝试执行的操作并进行相应的修复。

I'm not a C++ programmer but you should get something out of this:

// Amount of padding to leave around tiles (of window size)
int percentage = 10;

tile_ratio = tile_count_x / tile_count_y;
desktop_ratio = desktop_width / desktop_height;

// Determine the maximum window width and height
// according to tile and desktop aspect ratios
if(tile_ratio >= desktop_ratio) {
    window_width = desktop_width;
    window_height = window_width * (1 / tile_ratio);
} else {
    window_height = desktop_height;
    window_width = window_height * tile_ratio;
}

// Determine maximum width and height for tiles,
// taking account x% of padding on both sides, hence the * 2
tile_width = window_width * ((100 - (percentage * 2)) / 100);
tile_height = window_height * ((100 - (percentage * 2)) / 100);

// As the tiles must be square, determine the smaller side as the size
tile_size = tile_width < tile_height ? tile_width : tile_height;

// To maintain the x% padding, we must calculate the window size again as we just changed the tilesize
factor = (100 / (100 - (percentage * 2)));
window_width = tile_size * tile_count_x * factor;
window_height = tile_size * tile_count_y * factor;

Now you have the maximum window width and height so that:

  1. The window is in the same aspect ratio as the tiles
  2. The window is no bigger than the desktop
  3. The window has x% of padding around all sides of tiles

Note that I haven't tested this code at all, but it should work. If you find any errors, try to understand what I tried to do and fix accordingly.

你曾走过我的故事 2024-08-21 18:23:05

简单线性代数:

game_window_width = (tile_count_x * TILE_WIDTH) + 2*(game_window_width * X / 100)

我们有 2 个变量(TILE_WIDTHX)和只有 1 个方程,所以嗯,你运气不好。

您需要指定 TILE_WIDTHX(边距)。假设您指定 X,那么您可以求解方程:

TILE_WIDTH = (game_window_width - (2*(game_window_width * X / 100))) / 
             tile_count_x

如果我们考虑高度,并且需要相同的边框,那么我们有 2 个方程和 3 个未知数。仍然是索尔。

Simple linear algebra:

game_window_width = (tile_count_x * TILE_WIDTH) + 2*(game_window_width * X / 100)

We have 2 variables (TILE_WIDTH and X) and only 1 equation, so um, you're out of luck.

You will need to either specify TILE_WIDTH or X (the margin). Let's say you specify X, then you can solve the equation:

TILE_WIDTH = (game_window_width - (2*(game_window_width * X / 100))) / 
             tile_count_x

If we take into account the height, and require the same border, then we have 2 equations, and 3 unknowns. Still SOL.

行至春深 2024-08-21 18:23:05

如果您使用的是 Win32,那么您可以使用类似以下内容来初始调整窗口客户区的大小。

initial_width = (tile_count_x * tile_size) + (border_width * 2);
initial_height = (tile_count_y * tile_size) + (border_width * 2);

当窗口接收到调整大小事件时,您只需将每个图块拉伸(即放大或缩小每个图块)窗口已扩展或缩小的像素数(假设轴被锁定,即您无法调整每个图块的大小)独立)。

换句话说,tile_size 会有所不同:

tile_size += window_resize_amount;

此代码来自内存,但它可能会给出一个想法。

DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_CAPTION;
DWORD dwExStyle = 0;

int border_width = tile_size; // make border 1 tile

RECT r, w;
SetRect(&r, 0, 0, (tile_count_x * tile_size) + (border_width * 2), (tile_count_y * tile_size) + (border_width * 2));
AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
SystemParametersInfo(SPI_GETWORKAREA, 0, &w, 0);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = ((w.right - w.left) / 2) - (width / 2);
int y = ((w.bottom - w.top) / 2) - (height / 2);

hWnd = CreateWindowEx(dwExStyle, szClassName, szAppName, dwStyle, x, y, width, height, NULL, NULL, hInstance, 0);

If you are working with Win32, then you could use something like the following to initially size the client-area of your window.

initial_width = (tile_count_x * tile_size) + (border_width * 2);
initial_height = (tile_count_y * tile_size) + (border_width * 2);

When the Window recieves resize events you would simply stretchblt each tile (i.e. enlarge or shrink each tile) by the number of pixels that the window has been expanded or shrunk by (Assuming that the axis are locked, that is you can't resize each independetly).

In other words the tile_size would vary:

tile_size += window_resize_amount;

This code is from memory, but it may give an idea.

DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX | WS_CAPTION;
DWORD dwExStyle = 0;

int border_width = tile_size; // make border 1 tile

RECT r, w;
SetRect(&r, 0, 0, (tile_count_x * tile_size) + (border_width * 2), (tile_count_y * tile_size) + (border_width * 2));
AdjustWindowRectEx(&r, dwStyle, FALSE, dwExStyle);
SystemParametersInfo(SPI_GETWORKAREA, 0, &w, 0);
int width = r.right - r.left;
int height = r.bottom - r.top;
int x = ((w.right - w.left) / 2) - (width / 2);
int y = ((w.bottom - w.top) / 2) - (height / 2);

hWnd = CreateWindowEx(dwExStyle, szClassName, szAppName, dwStyle, x, y, width, height, NULL, NULL, hInstance, 0);
允世 2024-08-21 18:23:05

这是我解决问题的方法...

        //WINDOW SIZE SETUP

        //choose the smaller TILE_SIZE
        if (DESKTOP_WIDTH / TILE_COUNT_X > DESKTOP_HEIGHT / TILE_COUNT_Y)
        {
            TILE_SIZE = DESKTOP_HEIGHT / TILE_COUNT_Y;
        }
        else
        {   
            TILE_SIZE = DESKTOP_WIDTH / TILE_COUNT_X;
        }
        //Set screen size and consider a 5 tile border
        SCREEN_WIDTH = TILE_SIZE * (TILE_COUNT_X + 5);
        SCREEN_HEIGHT = TILE_SIZE * (TILE_COUNT_Y + 5);

        //resize window until it satisfies resolution constraints
        while( SCREEN_WIDTH > (DESKTOP_WIDTH - (DESKTOP_WIDTH * 0.07)))
        {
            TILE_SIZE --;
        SCREEN_WIDTH = TILE_SIZE * (TILE_COUNT_X + 5);
        SCREEN_HEIGHT = TILE_SIZE * (TILE_COUNT_Y + 5);
        }

        while( SCREEN_HEIGHT > (DESKTOP_HEIGHT - (DESKTOP_HEIGHT * 0.15)))
        {
            TILE_SIZE -- ;
        SCREEN_WIDTH = TILE_SIZE * (TILE_COUNT_X + 5);
        SCREEN_HEIGHT = TILE_SIZE * (TILE_COUNT_Y + 5);
        }
for(int i = 0; i < 8; ++i)     //Ensure resolution is multiple of 8
{
    if (SCREEN_WIDTH % 8 != 0) //remainder means not multiple of 8
    {
        SCREEN_WIDTH += 1;
    }

    if (SCREEN_HEIGHT % 8 != 0)
    {
        SCREEN_HEIGHT += 1;
    }
}
        X_OFFSET = (SCREEN_WIDTH - (TILE_SIZE * TILE_COUNT_X)) / 2;
        Y_OFFSET = (SCREEN_HEIGHT - (TILE_SIZE * TILE_COUNT_Y)) / 2;

Here is how I solved it...

        //WINDOW SIZE SETUP

        //choose the smaller TILE_SIZE
        if (DESKTOP_WIDTH / TILE_COUNT_X > DESKTOP_HEIGHT / TILE_COUNT_Y)
        {
            TILE_SIZE = DESKTOP_HEIGHT / TILE_COUNT_Y;
        }
        else
        {   
            TILE_SIZE = DESKTOP_WIDTH / TILE_COUNT_X;
        }
        //Set screen size and consider a 5 tile border
        SCREEN_WIDTH = TILE_SIZE * (TILE_COUNT_X + 5);
        SCREEN_HEIGHT = TILE_SIZE * (TILE_COUNT_Y + 5);

        //resize window until it satisfies resolution constraints
        while( SCREEN_WIDTH > (DESKTOP_WIDTH - (DESKTOP_WIDTH * 0.07)))
        {
            TILE_SIZE --;
        SCREEN_WIDTH = TILE_SIZE * (TILE_COUNT_X + 5);
        SCREEN_HEIGHT = TILE_SIZE * (TILE_COUNT_Y + 5);
        }

        while( SCREEN_HEIGHT > (DESKTOP_HEIGHT - (DESKTOP_HEIGHT * 0.15)))
        {
            TILE_SIZE -- ;
        SCREEN_WIDTH = TILE_SIZE * (TILE_COUNT_X + 5);
        SCREEN_HEIGHT = TILE_SIZE * (TILE_COUNT_Y + 5);
        }
for(int i = 0; i < 8; ++i)     //Ensure resolution is multiple of 8
{
    if (SCREEN_WIDTH % 8 != 0) //remainder means not multiple of 8
    {
        SCREEN_WIDTH += 1;
    }

    if (SCREEN_HEIGHT % 8 != 0)
    {
        SCREEN_HEIGHT += 1;
    }
}
        X_OFFSET = (SCREEN_WIDTH - (TILE_SIZE * TILE_COUNT_X)) / 2;
        Y_OFFSET = (SCREEN_HEIGHT - (TILE_SIZE * TILE_COUNT_Y)) / 2;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文