0

作業中のゲームのレベルエディタを作成しようとしています。フラットファイルからデータを取得し、バイトごとの検索に基づいて、事前設定されたタイルからグリッドを組み立てます。アプリのこの部分は問題がないはずです。問題は、00からFFまでの16x16グリッドのテストタイルをロードするだけのエディターのテストバージョンが間違った場所にロードされていることです。

例:アプリフレームは次のようになります。

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

私の恐ろしいASCIIアートを言い訳にすると、フレームには基本的に水平サイザーがあり、2つの垂直サイザーがあります。1つは左用、もう1つは右用です。これらのそれぞれにはパネルがあり、それぞれに2番目のサイザーがあります。左側のサイザーには64ピクセル幅のスペーサーがあり、グリッドサイザーは後で画像で埋められます。右の2番目のサイザーはユーザーサイズですが、そこにあるスペーサーを介して最低960ピクセル、次にコードのレベルの幅と高さによって決定されるグリッドサイザーです。

基本的に、各サイドには、メインフレームにあるサイザーの半分のサイザーの内側にあるパネル上にある、セクションの幅のスペーサーを持つサイザーの内側にグリッドサイザーがあります。時々私を混乱させるので、これが理にかなっていることを願っています: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グリッドを実行するための同様のコードがありますが、明らかな理由で、それが同じ問題を抱えているかどうかを判断する方法はありません。どちらにもスクロールバーは機能しますが、スクロールすると再描画の問題が発生するため、アプリケーション全体に画像を描画し、アプリケーションのレイアウトを無視しているのではないかと思います。

ここで見逃したことはありますか?グリッドサイザー、画像、GUI全般をPythonで使用したのはこれが初めてで、VB6よりも少しクロスプラットフォームなもので書きたいと思った後、この言語を始めたばかりです。何か考えはありますか?= /

4

1 に答える 1

1

それはたくさんのコードとたくさんのサイザーです! しかし、おそらくあなたの ImgPanels は、自分自身ではなく、親として rightPanel を持つべきだと思います。

また、self.SetSizer(self.h_sizer) を呼び出したことはありますか? それはどこにも見当たりませんでした。

レイアウトの一部を別の関数で作成することをお勧めします。こうすれば、ローカルの名前空間が風変わりなサイザー名で汚染されることを心配する必要はありません。したがって、サイザー階層の各部分に対して、関数を持つことができます。

create_controls
    create_left_panel
        create_grid
    create_right_panel

また、通常は、サイザーにダミーのスペーサーを追加してサイズの制約を設定する代わりに、子コントロールで SetMinSize を使用します。その後、Fit がそれを行います。Fit といえば、引数を取ることができるとは知りませんでした。

于 2009-12-31T03:26:39.933 に答える