0

我正在尝试为我正在开发的游戏构建关卡编辑器。它从一个平面文件中提取数据,然后基于逐字节搜索,它将从预先设置的图块中组装一个网格。应用程序的这一部分我应该没有问题。问题是我的编辑器测试版本只加载了从 00 到 FF 的 16x16 网格测试图块,加载到了错误的位置。

示例:应用程序框架如下所示:

|-T-------|
| |       |
| |       |
| |       |
| |       |
|---------|

原谅我可怕的 ASCII 艺术,框架上基本上有一个水平尺寸器,有 2 个垂直尺寸器,一个用于左侧,一个用于右侧。它们中的每一个都有一个面板,每个面板都有第二个尺寸器。左边的 sizer 里面有一个 64 像素宽的 spacer,然后是 gridsizer,后来用图像填充。右边的第二个 sizer 是用户可调整的,但至少 960 像素通过那里的垫片,然后是由代码中的级别宽度和高度确定的 gridsizer。

从本质上讲,对于每一侧 - 有一个 gridsizer 在一个 sizer 里面有一个用于该部分宽度的垫片,它位于一个面板上,该面板位于一个 sizer 内部,用于主框架上的那一半 sizer。我希望这是有道理的,因为它有时会让我感到困惑:P

这是执行所有这些操作的代码:

    #Horizontal sizer
    self.h_sizer = wx.BoxSizer(wx.HORIZONTAL)
    #Vertical sizer
    self.v_sizer_left = wx.BoxSizer(wx.VERTICAL)
    self.v_sizer_right = wx.BoxSizer(wx.VERTICAL)

    #Create the 2 panels
    self.leftPanel = wx.ScrolledWindow(self, style = wx.VSCROLL | wx.ALWAYS_SHOW_SB)
    self.leftPanel.EnableScrolling(False, True)
    self.rightPanel = wx.ScrolledWindow(self, style = wx.VSCROLL | wx.ALWAYS_SHOW_SB)
    self.rightPanel.EnableScrolling(False, True)

    #Create a sizer for the contents of the left panel
    self.lps = wx.BoxSizer(wx.VERTICAL)
    self.lps.Add((64, 0)) #Add a spacer into the sizer to force it to be 64px wide
    self.leftPanelSizer = wx.GridSizer(256, 1, 2, 2) # horizontal rows, vertical rows, vgap, hgap
    self.lps.Add(self.leftPanelSizer)   #Add the tiles grid to the left panel sizer
    self.leftPanel.SetSizerAndFit(self.lps) #Set the leftPanel to use LeftPanelSizer (it's not lupus) as the sizer
    self.leftPanel.SetScrollbars(0,66,0, 0) #Add the scrollbar, increment in 64 pixel bits plus the 2 spacer pixels
    self.leftPanel.SetAutoLayout(True) 
    self.lps.Fit(self.leftPanel)


    #Create a sizer for the contents of the right panel
    self.rps = wx.BoxSizer(wx.VERTICAL)
    self.rps.Add((960, 0)) #Set it's width and height to be the window's, for now, with a spacer
    self.rightPanelSizer = wx.GridSizer(16, 16, 0, 0) # horizontal rows, vertical rows, vgap, hgap
    self.rps.Add(self.rightPanelSizer)  #Add the level grid to the right panel sizer
    self.rightPanel.SetSizerAndFit(self.rps)    #Set the rightPanel to use RightPanelSizer as the sizer
    self.rightPanel.SetScrollbars(64,64,0, 0)   #Add the scrollbar, increment in 64 pixel bits - vertical and horizontal
    self.rightPanel.SetAutoLayout(True)
    self.rps.Fit(self.rightPanel)


    #Debugging purposes. Colours :)
    self.leftPanel.SetBackgroundColour((0,255,0))
    self.rightPanel.SetBackgroundColour((0,128,128))

    #Add the left panel to the left vertical sizer, tell it to resize with the window (0 does not resize, 1 does). Do not expand the sizer on this side.
    self.v_sizer_left.Add(self.leftPanel, 1)
    #Add the right panel to the right vertical sizer, tell it to resize with the window (0 does not resize, 1 does) Expand the sizer to fit as much as possible on this side.
    self.v_sizer_right.Add(self.rightPanel, 1, wx.EXPAND)

    #Now add the 2 vertical sizers to the horizontal sizer.
    self.h_sizer.Add(self.v_sizer_left, 0, wx.EXPAND)   #First the left one...
    self.h_sizer.Add((0,704))                           #Add in a spacer between the two to get the vertical window size correct...
    self.h_sizer.Add(self.v_sizer_right, 1, wx.EXPAND)  #And finally the right hand frame.

获取所有数据后,应用程序将使用它从指定目录生成带有 .png 瓷砖的关卡布局,但出于测试目的,如上所述,我只是生成一个从 00 到 FF 的 16x16 网格 - 通过菜单选项我称这种方法为:

def populateLevelGrid(self, id):
    #This debug method fills the level grid scrollbar with 256 example image tiles
    levelTileset = self.levelTilesetLookup[id]
    #levelWidth = self.levelWidthLookup[id]
    #levelHeight = self.levelHeightLookup[id]
    #levelTileTotal = levelWidth * levelHeight

    levelTileTotal = 256    #debug line

    self.imgPanelGrid = []
    for i in range(levelTileTotal):
        self.imgPanelGrid.append(ImgPanel.ImgPanel(self, False))
        self.rightPanelSizer.Add(self.imgPanelGrid[i]) 
        self.imgPanelGrid[i].set_image("tiles/"+ levelTileset + "/" + str(i) + ".png")
    self.rightPanelSizer.Layout() 
    self.rightPanelSizer.FitInside(self.rightPanel)

这可行,但将网格固定在整个框架的左上角,而不是框架右半部分的左上角 - 它应该打开。有类似的代码在左框架上做一个 1x256 网格,但我无法判断这是否因为明显的原因而遇到同样的问题。两者都有工作滚动条,但在滚动时有重绘问题,这让我想知道它是否在整个应用程序上绘制图像而只是忽略了应用程序布局。

我在这里错过了什么吗?这是我第一次在 python 中使用 gridsizers、图像和 GUI 做任何事情,最近才开始使用这种语言,因为我想用比 VB6 更跨平台的东西来写东西——有什么想法吗?=/

4

1 回答 1

1

那是很多代码和很多sizer!但我认为也许您的 ImgPanel 应该将 rightPanel 作为其父级,而不是自身。

另外,你有没有打电话给 self.SetSizer(self.h_sizer)?没在哪里看到。

我建议在单独的函数中创建部​​分布局。然后你就不必担心你的本地命名空间会被所有这些古怪的 sizer 名称污染。因此,对于 sizer 层次结构的每个部分,您都可以拥有一个函数。

create_controls
    create_left_panel
        create_grid
    create_right_panel

此外,我通常在子控件上使用 SetMinSize,而不是在 sizer 中添加虚拟垫片来设置大小约束。然后 Fit 会为您完成。说到Fit,我什至不知道它会引起争论!

于 2009-12-31T03:26:39.933 回答