wxPython渲染问题,非常缓慢且崩溃,不确定原因

wxPython渲染问题,非常缓慢且崩溃,不确定原因,python,performance,crash,wxpython,render,Python,Performance,Crash,Wxpython,Render,我一直在创建一个简单的基于平铺的游戏来帮助我学习python和wx python。首先,我想创建自己的“世界”,并测试我制作的简单地图生成器,我绑定了return键来生成一个新地图并显示它。 那就是我遇到这个问题的时候。每次单击“返回”时,它会减慢很多速度,逐行渲染每个平铺,这显然是缓慢和低效的,最终只是冻结 我是一个新手程序员,从来没有处理过任何形式的GUI,所以这对我来说都是非常新的,请容忍我!我可以猜,我设置东西的方式对机器来说是非常累人的,而且可能我导致了很多递归。我完全不知道。另外,我

我一直在创建一个简单的基于平铺的游戏来帮助我学习python和wx python。首先,我想创建自己的“世界”,并测试我制作的简单地图生成器,我绑定了return键来生成一个新地图并显示它。 那就是我遇到这个问题的时候。每次单击“返回”时,它会减慢很多速度,逐行渲染每个平铺,这显然是缓慢和低效的,最终只是冻结

我是一个新手程序员,从来没有处理过任何形式的GUI,所以这对我来说都是非常新的,请容忍我!我可以猜,我设置东西的方式对机器来说是非常累人的,而且可能我导致了很多递归。我完全不知道。另外,我对OOP不太熟悉,所以我只是按照示例创建我的类,因此我只有一个大型类来处理所有事情,我对所有的'\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu'函数不是很确定

以下是我到目前为止编写的所有代码,请忽略注释掉的部分,它们用于将来的函数等:

import wx
import random


#main screen class, handles all events within the main screen
class MainScreen(wx.Frame):

    hMap = []
    tTotalX = 50
    tTotalY = 50

    def __init__(self, *args, **kwargs):
        #This line is equivilant to wx.Frame.__init__('stuff')
        super(MainScreen, self).__init__(None, -1, 'You shouldnt see this', style = wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)

        self.renderScreen()

    def genMap(self,tTotalX,tTotalY):
        count1 = 0
        count2 = 0
        self.hMap = []
        while count1 < tTotalY:
            count2 = 0
            newrow = []
            while count2 < tTotalX: 
                newrow.append(random.randint(1,120))
                count2 += 1
            self.hMap.append(newrow)
            count1 += 1
        self.smooth(tTotalX, tTotalY)
        self.smooth(tTotalX, tTotalY)


    def smooth(self, tTotalX, tTotalY):
        countx = 0
        county = 0
        while county < tTotalY:
            countx = 0

            while countx < tTotalX: 
                above = county - 1
                below = int(county + 1)
                east = int(countx + 1)
                west = int(countx - 1)
                if east >= tTotalX:
                    east = 0
                if west < 0:
                    west = tTotalX -1

                teast = self.hMap[county][east]
                twest = self.hMap[county][west]

                if above < 0 or below >= tTotalY: 
                    smooth = (self.hMap[county][countx] + teast + twest)/3
                else:
                    tabove = self.hMap[above][countx]
                    tbelow = self.hMap[below][countx]
                    smooth = (self.hMap[county][countx] + tabove + tbelow + teast + twest)/5

                self.hMap[countx][county] = int(smooth)               
                countx += 1

            county += 1        

    def getTileType(self, coordX, coordY, totalX, totalY):
        #this is the part of map creation, getting tile type based on tile attributes
        tType = ''
        height = self.hMap[coordX][coordY]
        #the below values are all up to tweaking in order to produce the best maps
        if height <= 55:
            tType = 'ocean.png'

        if height > 55:
            tType = 'coast.png'

        if height > 60:
            tType = 'grassland.png'

        if height > 75:
            tType = 'hills.png'

        if height > 80:
            tType = 'mountain.png'

        if tType == '':
            tType = 'grassland.png'

        return tType

    #render the main screen so that it dislays all data
    def renderScreen(self):
        frameSize = 810 #Size of the game window
        tTotalX = self.tTotalX #the dimensions of the tile display, setting for in-game coordinates
        tTotalY = self.tTotalY
        #tsTiny = 1 #ts = Tile Size
        #tsSmall = 4
        tsMed = 16
        #tsLrg = 32
        #tsXlrg = 64
        tsCurrent = tsMed #the currently selected zoom level, for now fixed at tsMed
        pposX = 0 #ppos = Pixel Position
        pposY = 0
        tposX = 0 #tpos = tile position, essentially the tile co-ordinates independent of pixel position
        tposY = 0
    #The below is just an example of how to map out the grid, it should be in its own function in due time

        self.genMap(tTotalX, tTotalY)

        while tposY < tTotalY: #loops through all y coordinates
            tposX = 0   
            while tposX < tTotalX: #loops through all x coordinates
                pposX = tposX*tsCurrent
                pposY = tposY*tsCurrent
                tiletype = self.getTileType(tposX,tposY,tTotalX,tTotalY)

                img = wx.Image(('F:\First Pass\\' + str(tiletype)), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
                wx.StaticBitmap(self, -1, img, (pposX, pposY))#paints the image object (i think)

                tposX += 1
            tposY += 1

        self.Bind(wx.EVT_KEY_DOWN, self.onclick)
        self.SetSize((frameSize-4, frameSize+16))
        self.SetBackgroundColour('CYAN')
        self.Centre()
        self.SetTitle('Nations First Pass')
        #string = wx.StaticText(self, label = 'Welcome to Nations, First Pass', pos = (tTotalX*tsCurrent/2,tsCurrent*tTotalY/2))
        #string.SetFont(wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT))

        self.Show()

    def onclick(self, e):
        key = e.GetKeyCode()

        if key == wx.WXK_RETURN:

            self.renderScreen()


 #game loop
     def main():
         app = wx.App()
         MainScreen(None)
         app.MainLoop()

 if __name__ == '__main__':
     main()
您需要制作自己的“ocean.png”“coast.png”“grades.png”“hills.png”和“mountain.png”它们需要16x16像素,或者您可以从Imgur链接使用我的:

另外,请根据需要更改img代码中的文件路径。我需要弄清楚如何设置它,以便自己也能做到这一点,但这是另一天的另一个挑战


如果您对此有任何了解,我将不胜感激。

每次调用renderScreen时,您都会创建一组新的wx.staticBitmap,并且在创建一组新位图之前不会删除它们。过一段时间后,你会看到一堆堆的小部件和旧的小部件不再可见,但它们仍然在消耗资源。至少,您应该更改一些内容,以便您的程序只生成一组wx.staticBitmap,跟踪它们,然后在需要更改它们时调用它们的SetBitmap方法

为了获得更好的性能,您应该忘记静态位图,自己在EVT_绘制处理程序中绘制图像。静态位图是静态的,变化不大。相反,您可以为窗口实现一个EVT_绘制处理程序,它将在需要重画窗口时被调用,您可以通过调用窗口的刷新方法触发新的重画