[Tutor] canvas -> make an object 'seem' to move

John Fouhy john at fouhy.net
Tue May 8 00:22:23 CEST 2007


On 08/05/07, Teresa Stanton <tms43 at clearwire.net> wrote:
> I seem to be stuck again.  I've attached my entire file (and the .gif I'm
> using.  My son made this .gif, its our lab). The problem is my xp (the
> variable I use for my x coordinate) isn't updating after the .gif moves.  I
> think I should probably organize the entire module better, but then again,
> I've never written anything this big in Python, and nothing like this in
> Tkinter.  So, perhaps someone will have a suggestion?

Some general comments:

"""
#This will build the north (top) wall of the maze
canvasOne.create_line(10, 10, 790, 10, width = 3, fill = 'blue') #west to east
canvasOne.create_line(20, 20, 395, 20, width = 3, fill = 'blue') #2nd
line, west to middle
canvasOne.create_line(395, 20, 395, 100, width = 3, fill = 'blue')
#middle to south
canvasOne.create_line(405, 20, 405, 100, width = 3, fill = 'blue')#2nd
middle to south
canvasOne.create_line(395, 100, 405, 100, width = 3, fill = 'blue')
#short west to east
canvasOne.create_line(405, 20, 780, 20, width = 3, fill = 'blue') #2nd
line cont, middle to east
"""

This would be a good opportunity to define some functions.  eg, you
could do this:

canvasOne = Canvas(width = 800, height = 700, bg = 'black')
canvasOne.pack()

def createWall((x0, y0), (x1, y1), colour='blue', width=3):
    """ Create a wall from (x0, y0) to (x1, y1). """
    canvasOne.create_line(x0, y0, x1, y1, width=width, fill=colour)

Then ... hmm, I see from running your code that your lines are all
effectively continuous.  So you could represent each wall by a series
of points.  eg:

outerWall = [(10,10), (790,10), (790, 360), ...] # etc
innerWall1 = [...]
# etc

walls = [outerWall, innerWall1, ...]

Then you could draw them like:

for wall in walls:
    for i in range(len(wall-1)):
        createWallall(outerWall[i], outerWall[i+1])

Second comment:

"""
xp = 100
yp = 600

# ...

#onClick Vertical moves the .gif based on where the mouse is clicked
#newY is new location for yp
def onClickVertical(newY, xp, yp):
    print 'here'
    for i in range(newY):
        yp += .8
        canvasOne.coords(ph, xp, yp)
        time.sleep(.001)
        canvasOne.update()
    return xp, yp
"""

I notice you have a statement:

    yp += .8

in this function.  Are you aware that this will _not_ change the value
of yp outside the scope of the function?

If you want to change yp in the global scope, you need to tell python
to treat it as a global variable, by putting the statement 'global yp'
near the top of that function.

A better course of action (global variables are a bit ugly) might be
to encapsulate your maze into a class.  eg:

class Maze(object):
    def __init__(self):
        # initial position of actor
        self.xp = 100
        self.yp = 600
        # create maze, etc.

    def onClickVertical(self, newY, xp, yp):
        # etc

HTH!

-- 
John.


More information about the Tutor mailing list