Kivy GridLayout 缩放问题 - Android vs PC - 16:9 and 19:5:9 vs 4:3(1920x1080 and 1440x3120 vs 800x600)

Kivy GridLayout scaling issues - Android vs PC - 16:9 and 19:5:9 vs 4:3(1920x1080 and 1440x3120 vs 800x600)

我一直在使用 kivybuildozer 制作一个 Android 贪吃蛇游戏,并且在使用不同的值、布局和方法进行多次迭代之后(以及在 Google、Whosebug 和 kivy forums/documentation) 我已经到了我自己在这里寻求帮助的地步。

问题是这样的;
当 kivy window 为 800x600 时,网格看起来很棒,目标是矩形是完美的,甚至边正方形。 window 最大化并且 window 变成 1920x1080(16:9) 的那一刻,正方形变成宽矩形,因此不均匀。不幸的是,在我的 OnePlus 7 Pro 上试玩这款游戏,纵横比为 19:5:9,分辨率为 1440x3120,结果更加糟糕。

目前我正在使用由 Rectangle 填充的 GridLayout 来实现关卡的网格。我试过根据 Window.sizeWindow.width 制作公式,我试过使用 size_hintsizewidthcols_minimumkivy.metrics 到目前为止没有成功。

附带说明一下,如果我试图实现的或下面代码中的任何内容可以以更好的方式完成,请告诉我。任何替代方案将不胜感激,我对 kivyPython.

都非常缺乏经验和新手

我的代码:

from kivy.core.window import Window
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget


class GridCell(Widget):
    color = ListProperty([1, 1, 1, 1])
    size = ListProperty([0, 0])
    pos = ListProperty([0, 0])

    def __init__(self, size, x, y, **kwargs):
        super().__init__(**kwargs)
        self.color = (0.0, 0.0, 0.0, 1.0)
        self.size = (size, size)
        self.pos = (x, y)


class Level(GridLayout):
    def __init__(self, **kwargs):
        super(Level, self).__init__(**kwargs)
        self.cols = 30
        self.cell_size = 28
        self.spacing = 2
        self.positions = [(row, column) for row in range(self.cols) for column
                          in range(self.cols)]
        self.grid_cells = {}
        self.create_grid()

    def create_grid(self):
        for position in self.positions:
            self.grid_cells[position] = GridCell(self.cell_size, *position)
            self.add_widget(self.grid_cells[position])


if __name__ == '__main__':
    from kivy.app import App
    Builder.load_file('grid_cell.kv')
    Window.clearcolor = (1.0, 1.0, 1.0, 1.0)


    class LevelApp(App):
        def build(self):
            self.title = 'Level'
            level = Level()
            return level


    level_app = LevelApp()
    level_app.run()

grid_cell.kv:

<GridCell>:
    canvas:
        Color:
            rgba: self.color
        Rectangle:
            pos: self.pos
            size: self.size

请注意,您不能用方形单元格的方形网格填充非方形 window。但是,要使单元格保持正方形并将其大小基于 GridLayout,请尝试将 GridCell class 更改为:

class GridCell(Widget):
    color = ListProperty([1, 1, 1, 1])
    def __init__(self, x, y, **kwargs):
        super().__init__(**kwargs)
        self.color = (0.0, 0.0, 0.0, 1.0)
        self.pos = (x, y)

请注意,您不需要定义 possize 属性,因为 Widget 已经有了它们,而且我已经从 [=19] 中删除了 size =]方法。

并将Level更改为:

class Level(GridLayout):
    def __init__(self, **kwargs):
        super(Level, self).__init__(**kwargs)
        self.cols = 30
        self.rows = 30
        self.spacing = 2
        self.positions = [(row, column) for row in range(self.rows) for column
                          in range(self.cols)]
        self.grid_cells = {}
        self.create_grid()

    def create_grid(self):
        for position in self.positions:
            self.grid_cells[position] = GridCell(*position)
            self.add_widget(self.grid_cells[position])

然后在你的 kv:

<GridCell>:
    grid_cols: self.parent.cols if self.parent and self.parent.cols else 1
    grid_rows: self.parent.rows if self.parent and self.parent.rows else 1
    tmp_size: min(self.parent.width/self.grid_cols - self.parent.spacing[0], self.parent.height/self.grid_rows - self.parent.spacing[1]) if self.parent else 0
    size_hint: None, None
    size: self.tmp_size, self.tmp_size
    canvas:
        Color:
            rgba: self.color
        Rectangle:
            pos: self.pos
            size: self.size

这会根据 GridLayoutsizerowscols 计算 tmp_size,并将该大小分配给 GridCell ]. kv 中的 if 语句是必需的,因为 <GridCell> 规则在 GridCell 获得其 parent 分配之前应用。