【问题标题】:Kivy GridLayout scaling issues - Android vs PC - 16:9 and 19:5:9 vs 4:3(1920x1080 and 1440x3120 vs 800x600)Kivy GridLayout 缩放问题 - Android vs PC - 16:9 和 19:5:9 vs 4:3(1920x1080 和 1440x3120 vs 800x600)
【发布时间】:2020-06-18 16:21:01
【问题描述】:

我一直在使用 kivybuildozer 制作 Android Snake 游戏,并且在多次使用不同的值、布局和方法(以及在 Google、StackOverflow 和 kivy 论坛/文档上进行多次搜索)之后,我已经到了我自己在这里寻求帮助的地步。

问题是这样的;
当 kivy 窗口为 800x600 时,网格看起来很棒,矩形的目标是完美的,甚至是正方形。窗口最大化并且窗口变成 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

【问题讨论】:

  • self.size_hint = (None, None) 添加到您的__init__() 方法GridCell 有帮助吗?否则,您的尺寸设置将被忽略。
  • 它更正了大小,但网格不再填满窗口。如果可能的话,我宁愿保持自动缩放工作,并确保列和行的大小相同..
  • 它似乎也因为某种原因改变了行数/列数?或者至少他们走出窗外。
  • 就上下文而言,至少在我当前的蛇/水果运动实现中,产卵和重生这些变化也会破坏所有这些变化。真正尝试找到尽可能避免硬编码的更改,并在尽可能多的分辨率和纵横比上工作.. 至少在 Android 上。
  • 如果有什么我可以澄清或添加以帮助解决此问题,请告诉我。

标签: python android kivy scaling buildozer


【解决方案1】:

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

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 已经拥有它们,并且我已经从__init__() 方法中删除了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,并将该大小分配给GridCellkv 中的 if 语句是必需的,因为在分配 GridCell 之前应用了 &lt;GridCell&gt; 规则。

【讨论】:

  • 根据分辨率/纵横比更改行数/列数是否安全、可行、可扩展且足够灵活?
  • 一般来说,动态改变行/列?
  • 我已经更新了我的答案,现在GridCell 的大小是根据Level sizerowscols 计算的。
  • 所以要明确一点.. 有没有办法解决窗口的一半〜是空的?
  • 我将研究一个介于矩形和正方形之间的形状,具有合理的大小、行数和列数,然后用信息和功能填充空白空间。非常感谢您的时间和帮助。 @约翰安德森
猜你喜欢
  • 2016-01-30
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-18
  • 2014-10-07
相关资源
最近更新 更多