2

I am new to Python and using Zelle's graphics to create a game. I need the two while loops below to run at the same time, however I am running into difficulty. I tried nesting the while loops but then the horses and civilians would only move if the mouse was clicked, which I don't want. What I want is for the horses and civilians to always be moving, and the princess to move only when the mouse is clicked, and stop the game with a "game over" when she has saved 10 civilians.

    # animation loop.
while True==True:

    for horse in horseList:
        if horse.leg.getX() > -187:
            horse.move( -1, 20 )
        else:
            horse.move( 5, 28 )

    for civilian in civiliansList:

        if civilian.getX() < 800:
            civilian.move( 20, 0 )
        else:
            civilian.move( -100, 0 )

while civiliansSaved != 10:

    mouse = win.getMouse()

    princess.move( mouse, civilianCounter)

    civilianCounter = princess.move( mouse, civilianCounter)
    # move is a method that will return an updated civilianCounter ( it is initially 0 and defined outside of the while loop ), depending on whether princess runs into civilians

else:
    print( "Game over" )
    win.getMouse()
    win.close()
juiceb0xxie
  • 59
  • 1
  • 2
  • 7
  • 1
    Have you tried moving the stuff inside your first loop into the second loop? The first loop is unnecessary. – Shashank May 07 '15 at 06:06
  • If the content of both loops always happens together, and both have to stop when `civiliansSaved` reaches `10`, they should all be in one loop with the `civiliansSaved != 10` condition. – TigerhawkT3 May 07 '15 at 06:08
  • Looks like you just need to run two functions simultaneously. Here's a similar thread that might help: http://stackoverflow.com/questions/18864859/python-executing-multiple-functions-simultaneously – DigitalDouble May 07 '15 at 06:09
  • you can try this : http://stackoverflow.com/questions/2098495/parallel-while-loops-in-python – Ranvijay Sachan May 07 '15 at 06:13

3 Answers3

2

Just use checkMouse() instead of getMouse() inside your animation loop.

Simple as that, I think.

while civiliansSaved < 11:

    for horse in horseList:
        if horse.leg.getX() > -187      
            horse.move( -1, 20 )
        else:
            horse.move( 5, 28 )

    for civilian in civiliansList:
        if civilian.getX() < 800:
            civilian.move( 20, 0 )
        else:
            civilian.move( -100, 0 )

    mouse = win.checkMouse()

    if mouse:
        princess.move( mouse, civilianCounter)
        civilianCounter = princess.move( mouse, civilianCounter)

print( "Game over" )
win.getMouse()
win.close()

Doco:

checkMouse() Similar to getMouse, but does not pause for a user click. Returns the latest point where the mouse was clicked or None if the window as not been clicked since the previous call to checkMouse or getMouse. This is particularly useful for controlling simple animation loops.

GreenAsJade
  • 14,459
  • 11
  • 63
  • 98
0

Here is an example that should do what you want without the need for parallel processing (which is tricky in python):

while True:  # you don't need to write True==True
    for horse in horseList:
        if horse.leg.getX() > -187:
            horse.move( -1, 20 )
        else:
            horse.move( 5, 28 )

    for civilian in civiliansList:  
        if civilian.getX() < 800:
            civilian.move( 20, 0 )
        else:
            civilian.move( -100, 0 )

    mouse = win.getMouse()
    princess.move( mouse, civilianCounter)
    civilianCounter = princess.move( mouse, civilianCounter)

    if civiliansSaved >= 10: # check to see if 10 or more have been saved
        break
        print( "Game over" )
        win.getMouse()
        win.close()

What you want to do is to keep the game running until the civilianSaved counter is at least 10. But you can't do that in a separate loop from your main game loop, so it makes more sense to not stop the game until the count is at least 10. This if statement can be included in your main game loop.

yikes.gov
  • 165
  • 1
  • 8
  • In this solution, the horses only move once each time the mouse is clicked. My understanding is that they are supposed to keep moving while you are not clicking the mouse. – GreenAsJade May 07 '15 at 07:01
0

Zelle's graphics is not an event driven graphics tool, which I think is what you are looking for. Maybe consider switching to tkinter which is part of the Python standard library. You can use a callback function to handle mouse events so that your app is free to do other things while it is waiting to process a mouse event.

tkinter has an after() feature which allows you to call a function after a specified period of time. You can create separate functions for civilian movement and horse movement and call these functions after a specified period of time (say 50 ms). This effectively simulates running the functions in parallel and allows horses and civilians to move at the same time, at least from the user's perspective. You would need another call to after() within the movement functions so that they are continuously called.

self.root.after(50, self.process_horse_movement)
self.root.after(50, self.process_civilian_movement)

Then at the end of each movement function:

def process_horse_movement():
    ...
    self.root.after(50, self.process_horse_movement)

def process_civilian_movement():
    ...
    self.root.after(50, self.process_civilian_movement)

Also, a minor point. Use while True: instead of while True == True:.

Craig Burgler
  • 1,749
  • 10
  • 19