Python, part 9


We'll see here about the basics on animation in Tk.
First:  in general--draw a shape, call pack() to pack the new stuff,
call update() to update the canvas, and optionally, call wait to get
a slight (or long) pause between the updates.

For pausing your program:  most languages, including Python, have
methods for pausing.  In Python, you'll need
       import  time

       time.sleep(1)

When time.sleep(1) is executed, the program pauses for 1 second.  If
you want a 5-second pause, time.sleep(5), etc.

So we'll go back to our drawing of connected lines.  We'll ad some
code.  So we're adding after the
     oldx = newx
     oldy = newy
     myCanvas.pack()        this prepares what you have so far
     myCanvas.update()    this redraws the updated canvas
     time.sleep(1)                this pauses between drawing lines

Suppose for each update you want the old lines removed?  This is
not so easy.  Suppose you drew a stick figure and want the figure to
move across the canvas.  You probably do NOT want all the old figure
shapes still there--you only want one figure shape, but in a new location.
We'll be seeing how to do this.
-------------------------------------------------

Let's consider our program that drew random lines.  Suppose we wish
to change this so that only one line appears on the screen at a time--
old lines get removed.  Our lines were black on an orange background.
What we can do is the following:

          oldx = 0
          oldy = 0
          while oldx <= 350:
                  newx = random.randrange(1,401)
                  newy = random.randrange(1,401)
                  myCanvas.create_line(oldx,oldy,newx,newy,arrow="last"
                  myCanvas.pack()
                  myCanvas.update()
                  time.sleep(1)
                  myCanvas.create_line(oldx,oldy,newx,newy,fill="orange",arrow="last")
                  oldx = newx
                  oldy = newy
                                                    randlines       undrawlines

Note that we have moved the oldx = newx   and oldy = newy  down.  We have
told Tk to pack and update.  Then we pause for a second with the newly-drawn
line on the screen.  We then write the same line again--but note the part that
says fill="orange".  This redraws the line the same color as the background, so
that the line disappears.  Now--and only now--can we do the oldx = newx and
oldy = newy.  Why wait until now?  Because in redrawing the line in orange we
needed the old AND new coordinate pairs. 
----------------------------------------------------------

Let's now have an orange tennis ball (or golf ball, etc) rolling across a lawn.

myCanvas = Canvas(width=400, height=400, background="sky blue")
myCanvas.create_rectangle(0,300,400,400, fill="dark green")

                                 we want the lower quarter of the sky-blue canvas t be
                                 dark green:  (0,300) is 3/4 the way down the left edge
                                 and (400,400) is the lower right-hand corner.  We have
                                 our sky and our lawn.

oldx = 0                   this gets us into our while loop--we could also use a for loop.
while oldx < 350:            we'll stop when the ball nears the right edge.

         myCanvas.create_oval(oldx,275,oldx+25,300, fill="orange",\
                         outline="orange")
                                 the ball will be 25 pixels  in diameter, so we need the
                                 coordinate pairs (oldx,275) and (oldx+25,300)--why?
                                 the "\" after fill="orange",  tells Python that we need to
                                 continue the statement on the next line.

         myCanvas.pack()
         myCanvas.update()               pack and update
         time.sleep(0.1)                        the pause can be in fractions of a second rather
                                                           than in full seconds--this makes the ball "move"
                                                           faster.

         myCanvas.create_oval(oldx,275,oldx+25,300, fill="sky blue",\
                        outline="sky blue")
         oldx = oldx + 5                              this "advances" the ball 5 pixels each time
                                                                 in the loop

                                                                   rolling

Try the code--the ball moves quite smoothly across the lawn.  We could have made
the advance 2 or 3 pixels at a time.  You can make the ball move faster by changing
time.sleep(0.1) to time.sleep(0.03)  etc.   One small problem--the ball takes small
nicks out of the lawn as it moves!  We might avoid the nicks by redrawing the dark
green lawn each time.  By putting more thought and effort into this,  we could have
made the ball bounce across the lawn.  Lots of variations are possible.