2

A simple question: Why does this the first code work but the seemingly identical second code freezes up when the pygame window comes?

# Moving Pan
# Demonstrates mouse input

from livewires import games

games.init(screen_width = 640, screen_height = 480, fps = 50)

class Pan(games.Sprite):
    """ A pan controlled by the mouse. """
    def update(self):
        """ Move to mouse coordinates. """
        self.x = games.mouse.x
        self.y = games.mouse.y

def main():
    wall_image = games.load_image("wall.jpg", transparent = False)
    games.screen.background = wall_image

    pan_image = games.load_image("pan.bmp")
    the_pan = Pan(image = pan_image,
                  x = games.mouse.x,
                  y = games.mouse.y)
    games.screen.add(the_pan)

    games.mouse.is_visible = False

    games.screen.event_grab = True

    games.screen.mainloop()

# kick it off!
main()

The malfunctioning second:

from livewires import games,color
games.init (screen_width = 640, screen_height = 480, fps = 50)

#Creating a moving object tied to the cursor. This includes one method with two
#lines of code.
class Pan (games.Sprite):
    def moved (self):
    #Receives mouse position
        self.x = games.mouse.x
    #Changes mouse position to new x,y values.
        self.y = games.mouse.y

#The Main
myscr = games.screen
myscr.set_background (games.load_image ("wall.jpg", transparent = False))
pan_image = games.load_image ("pan.bmp")
le_pan = Pan (image = pan_image,
              x = games.mouse.x,
              y = games.mouse.y)

games.mouse.is_visible = False
myscr.add (le_pan)
myscr.event_grab = True
myscr.mainloop()
Stephen Terry
  • 6,169
  • 1
  • 28
  • 31
Louis93
  • 3,843
  • 8
  • 48
  • 94

1 Answers1

2

I have never worked with livewires, but in games you usually need a - more or less - endless game-loop.

The sense behind a game-loop is, that you always want to know where the mouse is or what keys are pressed, not only once! So you have to ask Where is the mouse? over and over. And to achieve that, you use a loop that checks everything you want everytime it gets executed.

In the first example the game-loop is the function main. The flow of the application is like this:

  1. Import needed libraries

    from livewires import games
    
  2. Initialize the game-screen

    games.init(screen_width = 640, screen_height = 480, fps = 50)
    
  3. Declare a sprite which can be displayed on the screen

    class Pan(games.Sprite):
        """ A pan controlled by the mouse. """
        def update(self):
            """ Move to mouse coordinates. """
            self.x = games.mouse.x
            self.y = games.mouse.y
    
  4. Declare the main method and setup the game-screen background

    def main():
        wall_image = games.load_image("wall.jpg", transparent = False)
        games.screen.background = wall_image
    
  5. Add the above defined sprite to the screen and move it to the position of the mouse-cursor

        pan_image = games.load_image("pan.bmp")
        the_pan = Pan(image = pan_image,
                      x = games.mouse.x,
                      y = games.mouse.y)
        games.screen.add(the_pan)
    
  6. Make mouse cursor invisible and activate events

        games.mouse.is_visible = False
        games.screen.event_grab = True
    
  7. Run mainloop. The call of this method says: Run me( functionmain)over and over!

        games.screen.mainloop()
    
  8. Call main for the first time

    main()
    

In the second example, there is no game-loop. The flow of the application (tighter packed) is like this:

  1. Import libraries, initialize game-screen, declare a sprite

    from livewires import games,color
    games.init (screen_width = 640, screen_height = 480, fps = 50)
    
    class Pan (games.Sprite):
        def moved (self):
            self.x = games.mouse.x
            self.y = games.mouse.y
    
  2. Setup game-screen background and add sprite

    myscr = games.screen
    myscr.set_background (games.load_image ("wall.jpg", transparent = False))
    pan_image = games.load_image ("pan.bmp")
    le_pan = Pan (image = pan_image,
                  x = games.mouse.x,
                  y = games.mouse.y)
    myscr.add(le_pan)
    
  3. Deactivate mouse cursor, enable events

    games.mouse.is_visible = False
    myscr.event_grab = True
    
  4. Run mainloop. The call of this method says: Run me( functionundefined)over and over!

    myscr.mainloop()
    

And here is the sticking point! You cannot call code that is in the root of a Python-file! The mainloop function doesn't know where to return or where to start off. The call gets lost, your program freezes. The game-screen can't get updated, because nothing is telling it how it should update.

Conclusion: You have to have a function for your game-loop!

Pit
  • 3,606
  • 1
  • 25
  • 34
  • Great answer, but how come the mainloop() in the second piece of code doesn't do the same thing? Sorry if this is a daft question, I'm new to this. – Louis93 Jun 24 '11 at 15:12
  • 1
    Your question is totally adequate and should be answered so that you go away with more knowledge than you came with. That said, here is why `mainloop()` won't work in the second example. What `mainloop` does, or better what I expect it to do (I didn't find any documentation on it), is running the function again from which it had been called before, if no other circumstances are preventing it from doing that (closing the application etc.). If you now call `mainloop` from outside of any function, there is nothing `mainloop` could call back. I try to improve my answer to be more explanatory! – Pit Jun 24 '11 at 15:20
  • I updated my answer by a good piece, I hope you get the clue! – Pit Jun 24 '11 at 15:47
  • Wow, great, informative, well-written answer! Thanks so much. – Louis93 Jun 24 '11 at 15:53