我正在尝试为我正在开发的游戏构建关卡编辑器。它从一个平面文件中提取数据,然后基于逐字节搜索,它将从预先设置的图块中组装一个网格。应用程序的这一部分我应该没有问题。问题是我的编辑器测试版本只加载了从 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 更跨平台的东西来写东西——有什么想法吗?=/