Python
  Home arrow Python arrow Page 4 - A PyGame Working Example, continued
Dev Shed Forums 
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Sun Developer Network 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Actuate Whitepapers 
VeriSign Whitepapers 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PYTHON

A PyGame Working Example, continued
By: Peyton McCullough
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 8
    2006-02-14

    Table of Contents:
  • A PyGame Working Example, continued
  • Setting Things Up
  • Cleaning Up
  • Constructing the Main Loop
  • The Game in Action

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT

    Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here

    A PyGame Working Example, continued - Constructing the Main Loop


    (Page 4 of 5 )

    Now that we've created functions to get things set up for us, we're ready to get into the function containing the main loop of the game. Before we get into our function's actual loop, though, we'll have to do a bit of configuration. First, we'll have to get the size of each position on the screen. This simply involves dividing the height and width of the background by the number of rows and columns. Then, we'll have to define two variables that work with movement. When the user presses a key, the first variable will need to be set to the direction of the movement. When the user releases a key, the second variable will need to be set to True, which will signal movement to stop. This way, a user can hold down a key and see movement rather than have to repeatedly tap the key.

    Though we have a list of sprite groups, we also need a list that will store the sprite groups that are actually visible on the screen. This way, we'll know which ones to update. Next, we need to actually draw the player. Finally, we'll have to load custom events into the timer. This is done by setting the timer to trigger our own event IDs at set intervals. The first event will update the player, and the second event will update the objects. The speeds at which things will be updated will be passed as arguments.

    Here's all this in action:

    def run(playerSpeed = 250, objectSpeed = 1000):

       # Get the row and column widths
       colWidth = background.get_rect().width / columns
       rowHeight = background.get_rect().height / rows

       # Define a variable that stores whether an arrow key is
    pressed
       # This is used for continuous/scrolling movement of the player
       moving = False

       # We should also define a variable that signals stops
       # Otherwise, if a player pushes a key in between updates and
    releases
       # it, the move will not be registered
       movingStop = False

       # Create a list to store the visible groups
       visible = []

       # Blit the player
       updateRects = player.draw(screen)
       pygame.display.update(updateRects)

       # Load a screen update event into the timer
       # This will update the player only
       pygame.time.set_timer(pygame.USEREVENT + 1, playerSpeed)

       # Load a screen update event into the timer
       # This will update the objects
       pygame.time.set_timer(pygame.USEREVENT + 2, objectSpeed)

    With all that done, we're now ready to jump into the main loop. First, we'll need to check for quit events and key presses:

    def run(playerSpeed = 250, objectSpeed = 1000):

       ...

       while True:

          for event in pygame.event.get():
             if event.type == pygame.QUIT:
                sys.exit()

             # Check for a key push by the user
             elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                   moving = 'right'
                elif event.key == pygame.K_LEFT:
                   moving = 'left'

             # Check by a key release by the user
             elif event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT or pygame.K_LEFT:
                   movingStop = True

    The above code simply sets the player to move when a key is pressed, and it sets it to stop moving when a key is released. It also enables the player to exit the game.

    The next task ahead of us is moving the player around. To do this, we first need to check to see whether our custom player update event has been triggered. If it has, we then need to move the player in the proper direction, if any direction at all. We finally need to check to see whether the player has collided with any of the objects and then redraw the player:

    def run(playerSpeed = 250, objectSpeed = 1000):

       ...

             # Check for the update player event
             elif event.type == pygame.USEREVENT + 1:

                # Move the player if needed
                if moving == 'right':
                   player.update(colWidth)
                if moving == 'left':
                   player.update(-colWidth)

                # Stop movement if needed
                if movingStop:
                   moving = False
                   movingStop = False

                # Collision detection
                for group in visible:
                   if pygame.sprite.spritecollideany(playerSprite,
    group):
                      return False

                # Redraw the player
                player.clear(screen, erase) 
                updateRects = player.draw(screen)

                pygame.display.update(updateRects)

    As I mentioned earlier, the visible list above will contain a list of all the visible sprite groups. To check for collision, we iterate through this list and use pygame.sprite.spritecollideany. There's no need to use a method that kills the colliding sprites since we want to completely back out of the loop. What object the player hits doesn't really matter to us. As you can see, we return False to get out of the loop.

    All that's left now is moving the objects around, an extremely simple task. This is done when our custom object update event has been triggered. If anything remains in the layout list, we add it to our visible list. Likewise, we delete any sprite group that has fallen off the screen. Aside from that, we simply update each sprite group, and if the visible list is empty, then the player has won the level.

    def run(playerSpeed = 250, objectSpeed = 1000):

       ...

             # Check for the update object event
             elif event.type == pygame.USEREVENT + 2:

                # Add a row
                if layout:
                   visible.append(layout.pop())

                # Delete passed rows
                if visible:
                   if visible[0].y >= screen.get_rect().height:
                      visible.pop(0)

                # If there are no visible rows, the player has won
                else:
                   return True

                # Make a list of rectangles to be updated
                updateRects = []

                # Update each group
                for group in visible:
                   group.clear(screen, erase)
                   group.update(rowHeight)
                   group.y = group.y + rowHeight
                   updateRects.extend(group.draw(screen))

                pygame.display.update(updateRects)

    More Python Articles
    More By Peyton McCullough


       · Hey, all,This is a continuation of the last PyGame article, and it focuses on...
       · Note that some of the examples don't take full advantage of the API. For...
       · Hey there, great job w/ this tutorial, this is really helping!Just a little note...
     

       

    PYTHON ARTICLES

    - SSH with Twisted
    - Mobile Programming in Python using PyS60: UI...
    - Python: Count on It
    - Python Strings: Spinning Yarns
    - Python: More Fun with Strings
    - Python: Stringing You Along
    - Python Operators
    - Bluetooth Programming in Python: Network Pro...
    - Python Sets
    - Python Conditionals, Lists, Dictionaries, an...
    - Python: Input and Variables
    - Introduction to Python Programming
    - Mobile Programming in Python using PyS60: Ge...
    - Bluetooth Programming using Python
    - Finishing the PyMailGUI Client: User Help To...





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 5 hosted by Hostway