Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is this basic pygame structure? [closed]

Here is how I'm implementing my simple pygames now:

import pygame, sys
from pygame.locals import *

def run_game():
    pygame.init()

    SIZE = (640, 400)
    BG_COLOUR = (0, 0, 0)
    LINE_COLOUR = (255, 255, 255)

    screen = pygame.display.set_mode(SIZE)
    clock = pygame.time.Clock()

    while True:
        time_passed = clock.tick(30)
        for event in pygame.event.get():
                if event.type == QUIT:
                        exit_game()

        screen.fill(BG_COLOUR)
        pygame.draw.aaline(screen, LINE_COLOUR, (1, 1), (639, 399))
        pygame.display.flip()

def exit_game():
    sys.exit()

if __name__ == "__main__"
    run_game()

I've also seen a keeprunning flag being used to exit the main event loop instead, as well as using pygame.event.poll() instead of looping through pygame.event.get(). Any suggestions, like case/naming of variables, anything to make it more effective or readable?

like image 763
mk12 Avatar asked Dec 04 '22 14:12

mk12


2 Answers

Whatever the pygame authors recommend, I suggest avoiding from ... import *: it only makes your code harder to read (as the reader has to inspect each and every barename to check whether it's actually assigned locally OR comes from the deuced *). Change that to import pygame.locals as pygl, say, and make every use of a name from it be a qualified one (I think in your code this just means changing QUIT to pygl.QUIT). What short name exactly you choose to use in lieu of pygl doesn't matter much, but that's a general structure I STRONGLY recommend. Remeber: namespaces are a honking great idea -- let's do more of those!-)

Use 4-space indents everywhere, as PEP 8 says: you seem to be mixing some 4-space indents with other which are 8-space or tabs -- don't!

Don't assign to variables you're never ever gonna use, as you're doing it for time_passed.

Code like: if event.type == QUIT: exit_game() is fine as long as you're testing one or very few possibilities (with if/elif), but doesn't "scale up" much, in either readability or efficiency. When you need to cover several cases, use a dict that you can set up before the loop:

dispatch = {pygl.QUIT: exit_game, # whatever else
           }

and instead of if/elif/else, use:

f = dispatch.get(event.type)
if f is None:  # the "else" case"
   ...
else: f()
like image 69
Alex Martelli Avatar answered Dec 13 '22 11:12

Alex Martelli


Your example is very good . But if you see how worked "pygame.event.poll()" see this simple example:

event = pygame.event.poll()
    while "ok":
        event = pygame.event.wait()
        cursor = pygame.mouse.get_pos()
        if event.type == QUIT:  raise SystemExit
            if event.type == MOUSEBUTTONUP and pygame.mouse.get_pressed()[0]:
               print "up"
        if event.type == MOUSEBUTTONDOWN and pygame.mouse.get_pressed()[0]:
               print "down"
        if event.type == KEYDOWN and event.key == K_SPACE: print "space key"
        if event.type == KEYDOWN and event.key == K_BACKSPACE:
               print "backspace key"

you can use all events from pygame:

  • pygame.event.get - get events from the queue get events from the queue
  • pygame.event.poll - get a single event from the queue get a single event from the queue
  • pygame.event.wait - wait for a single event from the queue

or

  • pygame.event.clear([pygame.QUIT, pygame.ACTIVEEVENT, pygame.KEYDOWN, pygame.KEYUP, pygame.MOUSEMOTION, pygame.JOYBUTTONUP, pygame.USEREVENT]) to remove all events from the queue

Bassicaly you create functions for this events and use it . Like this :

def click_down():
    #print "Event queue:", pygame.event.peek()
    return pygame.event.peek(pygame.MOUSEBUTTONDOWN)

def is_click():
    if not click_down():
        return None

    clicks = pygame.event.get(pygame.MOUSEBUTTONDOWN)
    pygame.event.get(pygame.MOUSEBUTTONUP)
    return clicks[0].pos
def quiting():
    return pygame.event.peek(pygame.QUIT)
def keyboard():
    pygame.event.pump()
    pygame.event.get(pygame.KEYDOWN)

or blocking some events like :

pygame.event.set_blocked((pygame.JOYAXISMOTION))
like image 24
Cătălin George Feștilă Avatar answered Dec 13 '22 12:12

Cătălin George Feștilă