[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Newbie Main Window / Message Loop questions..



Hello, and thanks for looking at this.  I hope you have patience for a pygame newbie..

I'm using Mac OS 10.6, python 2.6.6, and pygame 1.9.1.  I got this slightly modified sample working:

[code]
import sys, pygame
pygame.init()

size = width, height = 320, 240
speed = [4, 4]
black = 0, 0, 0

backbuffer = pygame.display.set_mode(size, pygame.RESIZABLE)

ball = pygame.image.load("ball.gif")
ballrect = ball.get_rect()

gameover = False

while not gameover:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameover = True
            break
        if event.type != pygame.MOUSEMOTION:
            print pygame.event.event_name(event.type), event

    if not gameover:
        ballrect = ballrect.move(speed)
        if ballrect.left < 0 or ballrect.right > width:
            speed[0] = -speed[0]
        if ballrect.top < 0 or ballrect.bottom > height:
            speed[1] = -speed[1]

        backbuffer.fill(black)
        backbuffer.blit(ball, ballrect)
        pygame.display.flip()

[/code]

Here are the problems I'm trying to solve:

- Option Q doesn't work

I guess I could check for keydown and keyup events or read from the keyboard and work around this, but.. it seems weird to me that while there is this "Python" menu up there with a "Quit" option that actually works, when you click it, but the advertised shortcut key (Option Q) for it doesn't work.  I wonder if using pygame.event.pump() would make it work.. I don't think so, because using poll() instead of get() doesn't help, I tried that.

- The program pauses when I hold the mouse down on the menu

For some reason, the whole program just pauses when I click on the top screen menu.  It just stops operating.  Why would that be?  Is there a way to get it to keep going?  Other problems don't behave that way.

- Similarly, the program pauses while the window is being resized.

I created a version of this that supports resizing the window.  I made the window resizable, and, when I get a video resize event, I set the display mode again according to the new size.  That works fine, except that while I'm resizing the window, it the animation stops, even redrawing the window stops, so that a white background shows up where ever the right or bottom edge has moved to the right or down.  Instead of getting a bunch of consecutive resize events, you just get one resize event for the whole drag.  Is there a way to fix that?

It's a little bit tempting to.. try the same program with SDL and C, and.. see if it's an issue with SDL, maybe look at the pygame source and the SDL source..  I know that the warning about the NSQuickDrawView appears to be coming out of SDL although it seems that the more recent versions of SDL are using Quartz, now, so.. I guess we're waiting on a pygame update to make use of a more recent rev of SDL at this point?

Thanks so much for any help,

Shavais


p.s.  For hints and giggles, here's my.. revised version of this program so far:

[code]

# bounce.py - -

import sys, pygame
from pygameapp import PygameApp

INITIAL_WINDOW_SIZE = (400, 320)
DARK_BLUE = (0,0,30)

class Bounce(PygameApp):

    ball        = None
    ballrect    = None
    speed       = None
    magdx       = 4         # magnitude of the speed..
    magdy       = 4

    def __init__(self):
        PygameApp.__init__(self, winsize = INITIAL_WINDOW_SIZE, bgcolor = DARK_BLUE)
        self.loadGraphics()
        self.speed = [self.magdx, self.magdy]

    def loadGraphics(self):
        self.ball = pygame.image.load("ball.gif")
        self.ballrect = self.ball.get_rect()

    def draw(self):
        self.backbuffer.blit(self.ball, self.ballrect)

    def animate(self):
        width, height = self.winsize
        ballrect = self.ballrect.move(self.speed)

        if ballrect.left < 0:           self.speed[0] =  self.magdx
        elif ballrect.right > width:    self.speed[0] = -self.magdx

        if ballrect.top < 0:            self.speed[1] =  self.magdy
        elif ballrect.bottom > height:  self.speed[1] = -self.magdy

        self.ballrect = ballrect


if __name__ == '__main__':
    pygame.init()
    game = Bounce()
    game.run()

# pygameapp.py - -

mport sys, pygame

BLACK = (0,0,0)
DEFAULTWINSIZE = (320,240)

class PygameApp:

    displaymode = None
    winsize     = None
    bgcolor     = None
    backbuffer  = None
    quitflag    = False
    eventmap    = {}

    def __init__(self, winsize = DEFAULTWINSIZE, displaymode = pygame.RESIZABLE, bgcolor = BLACK):
        "subclasses should call this before or after performing their own initialization"
        self.bgcolor = bgcolor
        self.setupDisplay(winsize, displaymode)

        # subclasses could / should register their event handlers in this same way:
        mapping = {
            pygame.QUIT: self.onQuit,
            pygame.VIDEORESIZE: self.onVideoResize
        }
        self.eventmap.update(mapping)       # (this way it doesn't matter whether the subclass init is called before or after this)

    def setupDisplay(self, winsize, displaymode = None):
        self.winsize = winsize
        if displaymode: self.displaymode = displaymode
        self.backbuffer = pygame.display.set_mode(self.winsize, self.displaymode)

    def run(self):
        self.quitflag = False
        while not self.quitflag:
            self.eraseBackground()
            self.draw()
            self.flip()
            self.animate()
            self.processEvents()

    def eraseBackground(self):
        self.backbuffer.fill(self.bgcolor)

    def draw(self):
        "subclass hook - draw the foreground"
        pass

    def flip(self):
        pygame.display.flip()

    def animate(self):
        "subclass hook - move stuff, check for collision, etc"
        pass

    def processEvents(self):
        event = pygame.event.poll()
        if self.eventmap.has_key(event.type):
            handler = self.eventmap[event.type]
            handler(event)

    # a couple of  default event handlers - -

    def onQuit(self, event):
        self.quitflag = True

    def onVideoResize(self, event):
        print event.size
        self.winsize = event.size
        self.setupDisplay(event.size)



[/code]