Skip to main content
 首页 » 编程设计

python之在 wxpython 中使用小部件需要一些帮助

2025年05月04日14lonelyxmas

嘿,我在 wxpython 中使用 pygame,我想知道如何在程序的 pygame 部分中使用 wx 小部件。

所以,我只想用 wxButton 替换播放器图像。 (因此,当您按下左键时,按钮将向左移动,等等)。播放器图片为player.png,另一张图片为bad.png

import wx, sys, os, pygame, random 
 
class PygameDisplay(wx.Window): 
    def __init__(self, parent, ID): 
        wx.Window.__init__(self, parent, ID) 
 
WINDOWWIDTH = 600 
WINDOWHEIGHT = 600 
TEXTCOLOR = (255, 255, 255) 
BACKGROUNDCOLOR = (0, 0, 0) 
FPS = 40 
BADDIEMINSIZE = 10 
BADDIEMAXSIZE = 40 
BADDIEMINSPEED = 1 
BADDIEMAXSPEED = 8 
ADDNEWBADDIERATE = 6 
PLAYERMOVERATE = 5 
 
def terminate(): 
    pygame.quit() 
    sys.exit() 
 
def waitForPlayerToPressKey(): 
    while True: 
        for event in pygame.event.get(): 
            if event.type == pygame.QUIT: 
                terminate() 
            if event.type == pygame.KEYDOWN: 
                if event.key == pygame.K_ESCAPE: # pressing escape quits 
                    terminate() 
                return 
 
def playerHasHitBaddie(playerRect, baddies): 
    for b in baddies: 
        if playerRect.colliderect(b['rect']): 
            return True 
    return False 
 
def drawText(text, font, surface, x, y): 
    textobj = font.render(text, 1, TEXTCOLOR) 
    textrect = textobj.get_rect() 
    textrect.topleft = (x, y) 
    surface.blit(textobj, textrect) 
 
# set up pygame, the window, and the mouse cursor 
pygame.init() 
mainClock = pygame.time.Clock() 
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) 
pygame.display.set_caption('Dodger') 
pygame.mouse.set_visible(False) 
 
# set up fonts 
font = pygame.font.SysFont(None, 48) 
 
# set up sounds 
 
# set up images 
playerImage = pygame.image.load('player.png') 
playerRect = playerImage.get_rect() 
baddieImage = pygame.image.load('bad.png') 
 
# show the "Start" screen 
drawText('Dodger', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3)) 
drawText('Press a key to start.', font, windowSurface, (WINDOWWIDTH / 3) - 30, (WINDOWHEIGHT / 3) + 50) 
pygame.display.update() 
waitForPlayerToPressKey() 
 
 
topScore = 0 
while True: 
    # set up the start of the game 
    baddies = [] 
    score = 0 
    playerRect.topleft = (WINDOWWIDTH / 2, WINDOWHEIGHT - 50) 
    moveLeft = moveRight = moveUp = moveDown = False 
    reverseCheat = slowCheat = False 
    baddieAddCounter = 0 
 
    while True: # the game loop runs while the game part is playing 
        score += 1 # increase score 
 
        for event in pygame.event.get(): 
            if event.type == pygame.QUIT: 
                terminate() 
 
            if event.type == pygame.KEYDOWN: 
                if event.key == ord('z'): 
                    reverseCheat = True 
                if event.key == ord('x'): 
                    slowCheat = True 
                if event.key == pygame.K_LEFT or event.key == ord('a'): 
                    moveRight = False 
                    moveLeft = True 
                if event.key == pygame.K_RIGHT or event.key == ord('d'): 
                    moveLeft = False 
                    moveRight = True 
                if event.key == pygame.K_UP or event.key == ord('w'): 
                    moveDown = False 
                    moveUp = True 
                if event.key == pygame.K_DOWN or event.key == ord('s'): 
                    moveUp = False 
                    moveDown = True 
 
            if event.type == pygame.KEYUP: 
                if event.key == ord('z'): 
                    reverseCheat = False 
                    score = 0 
                if event.key == ord('x'): 
                    slowCheat = False 
                    score = 0 
                if event.key == pygame.K_ESCAPE: 
                        terminate() 
 
                if event.key == pygame.K_LEFT or event.key == ord('a'): 
                    moveLeft = False 
                if event.key == pygame.K_RIGHT or event.key == ord('d'): 
                    moveRight = False 
                if event.key == pygame.K_UP or event.key == ord('w'): 
                    moveUp = False 
                if event.key == pygame.K_DOWN or event.key == ord('s'): 
                    moveDown = False 
 
            if event.type == pygame.MOUSEMOTION: 
                # If the mouse moves, move the player where the cursor is. 
                playerRect.move_ip(event.pos[0] - playerRect.centerx, event.pos[1] - playerRect.centery) 
 
        # Add new baddies at the top of the screen, if needed. 
        if not reverseCheat and not slowCheat: 
            baddieAddCounter += 1 
        if baddieAddCounter == ADDNEWBADDIERATE: 
            baddieAddCounter = 0 
            baddieSize = random.randint(BADDIEMINSIZE, BADDIEMAXSIZE) 
            newBaddie = {'rect': pygame.Rect(random.randint(0, WINDOWWIDTH-baddieSize), 0 - baddieSize, baddieSize, baddieSize), 
                        'speed': random.randint(BADDIEMINSPEED, BADDIEMAXSPEED), 
                        'surface':pygame.transform.scale(baddieImage, (baddieSize, baddieSize)), 
                        } 
 
            baddies.append(newBaddie) 
 
        # Move the player around. 
        if moveLeft and playerRect.left > 0: 
            playerRect.move_ip(-1 * PLAYERMOVERATE, 0) 
        if moveRight and playerRect.right < WINDOWWIDTH: 
            playerRect.move_ip(PLAYERMOVERATE, 0) 
        if moveUp and playerRect.top > 0: 
            playerRect.move_ip(0, -1 * PLAYERMOVERATE) 
        if moveDown and playerRect.bottom < WINDOWHEIGHT: 
            playerRect.move_ip(0, PLAYERMOVERATE) 
 
        # Move the mouse cursor to match the player. 
        pygame.mouse.set_pos(playerRect.centerx, playerRect.centery) 
 
        # Move the baddies down. 
        for b in baddies: 
            if not reverseCheat and not slowCheat: 
                b['rect'].move_ip(0, b['speed']) 
            elif reverseCheat: 
                b['rect'].move_ip(0, -5) 
            elif slowCheat: 
                b['rect'].move_ip(0, 1) 
 
         # Delete baddies that have fallen past the bottom. 
        for b in baddies[:]: 
            if b['rect'].top > WINDOWHEIGHT: 
                baddies.remove(b) 
 
        # Draw the game world on the window. 
        windowSurface.fill(BACKGROUNDCOLOR) 
 
        # Draw the score and top score. 
        drawText('Score: %s' % (score), font, windowSurface, 10, 0) 
        drawText('Top Score: %s' % (topScore), font, windowSurface, 10, 40) 
 
        # Draw the player's rectangle 
        windowSurface.blit(playerImage, playerRect) 
 
        # Draw each baddie 
        for b in baddies: 
            windowSurface.blit(b['surface'], b['rect']) 
 
        pygame.display.update() 
 
        # Check if any of the baddies have hit the player. 
        if playerHasHitBaddie(playerRect, baddies): 
            if score > topScore: 
                topScore = score # set new top score 
            break 
 
        mainClock.tick(FPS) 
 
    # Stop the game and show the "Game Over" screen. 
 
    drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3)) 
    drawText('Press a key to play again.', font, windowSurface, (WINDOWWIDTH / 3) - 80, (WINDOWHEIGHT / 3) + 50) 
    pygame.display.update() 
    waitForPlayerToPressKey() 
 
 
    def Update(self, event) 
        # Any update tasks would go here (moving sprites, advancing animation frames etc.) 
        self.Redraw() 
 
    def Redraw(self): 
        if self.size_dirty: 
            self.screen = pygame.Surface(self.size, 0, 32) 
            self.size_dirty = False 
 
        self.screen.fill((0,0,0)) 
        cur = 0 
        w, h = self.screen.get_size() 
        while cur <= h: 
            pygame.draw.aaline(self.screen, (255, 255, 255), (0, h - cur), (cur, 0)) 
            cur += self.linespacing 
 
        s = pygame.image.tostring(self.screen, 'RGB') 
        img = wx.ImageFromData(self.size[0], self.size[1], s) 
        bmp = wx.BitmapFromImage(img) 
        dc = wx.ClientDC(self) 
        dc.DrawBitmap(bmp, 0, 0, False) 
        del dc 
 
    def OnPaint(self, event): 
        self.Redraw() 
 
    def OnSize(self, event): 
        self.size = self.GetSizeTuple() 
        self.size_dirty = True 
 
    def Kill(self, event): 
 
        # Make sure Pygame can't be asked to redraw /before/ quitting by unbinding all methods which 
        # call the Redraw() method 
        # (Otherwise wx seems to call Draw between quitting Pygame and destroying the frame) 
        self.Unbind(event = wx.EVT_PAINT, handler = self.OnPaint) 
        self.Unbind(event = wx.EVT_TIMER, handler = self.Update, source = self.timer) 
 
 
class Frame(wx.Frame): 
    def __init__(self, parent): 
        wx.Frame.__init__(self, parent, -1) 
        self.display = PygameDisplay(self, -1) 
        self.statusbar = self.CreateStatusBar() 
        self.statusbar.SetFieldsCount(3) 
        self.statusbar.SetStatusWidths([-3, -4, -2]) 
        self.statusbar.SetStatusText("wxPython", 0) 
        self.statusbar.SetStatusText("Look, it's a nifty status bar!!!", 1) 
 
        self.Bind(wx.EVT_SIZE, self.OnSize) 
        self.Bind(wx.EVT_CLOSE, self.Kill) 
 
        self.curframe = 0 
        self.SetTitle("Pygame embedded in wxPython") 
        self.slider = wx.Slider(self, wx.ID_ANY, 5, 1, 10, style = wx.SL_HORIZONTAL | wx.SL_LABELS) 
        self.slider.SetTickFreq(0.1, 1) 
        self.timer = wx.Timer(self) 
 
        self.Bind(wx.EVT_SCROLL, self.OnScroll) 
        self.Bind(wx.EVT_SIZE, self.OnSize) 
        self.Bind(wx.EVT_TIMER, self.Update, self.timer) 
 
        self.timer.Start((1000.0 / self.display.fps)) 
 
        sizer = wx.BoxSizer(wx.VERTICAL) 
        sizer.Add(self.slider, 0, flag = wx.EXPAND) 
        sizer.Add(self.display, 1, flag = wx.EXPAND) 
 
        self.SetAutoLayout(True) 
        self.SetSizer(sizer) 
        self.Layout() 
 
    def Kill(self, event): 
        self.display.Kill(event) 
        self.Destroy() 
 
    def OnSize(self, event): 
        self.Layout() 
 
    def Update(self, event): 
        self.curframe += 1 
        self.statusbar.SetStatusText("Frame %i" % self.curframe, 2) 
 
    def OnScroll(self, event): 
        self.display.linespacing = self.slider.GetValue() 
 
 
class App(wx.App): 
    def OnInit(self): 
        self.frame = Frame(parent = None) 
        self.frame.Show() 
        self.SetTopWindow(self.frame) 
        return True 
 
 
if __name__ == "__main__": 
    app = App() 
    app.MainLoop() 

请您参考如下方法:

我不相信你可以使用 wxPython wigits inside pygame。您可以使用一些 GUI 模块。

http://www.pygame.org/tags/gui

Google 代码之夏也有一个致力于改进 GUI 的项目。