1 Replies - 3646 Views - Last Post: 15 July 2012 - 08:22 PM Rate Topic: -----

#1 witeboy724  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 30
  • Joined: 21-June 12

Question about loops for animation with Tkinter

Posted 12 July 2012 - 07:20 PM

I'm making a 'Fall Down' game. You may have seen one like it before. I used to play it on my TI-83 back in the day. This is the first step in the programming where the lines are drawn and I'm having trouble getting this to loop.

I'm trying to get my raiselines() and then redraw() to loop. I've tried putting the loop command in different spots and using different methods. While stop==false, x in range(500), etc. Why can I only get this to draw the original lines but not get them to raise up?

If anyone can spot the error I'm missing here that would be much appreciated.


import random
from Tkinter import *


def main():

    #first run, get all new lines

    numberoflines = 8

    for x in range (numberoflines):
        addline()
        liney[x] = (wh/numberoflines) * x
        linecolor[x] = "black" #can change later

        print "x=", x," ",0,liney[x],hole1[x],liney[x]+lineh
        print hole2[x],liney[x],wright,liney[x]+lineh

    redraw()

    for repeat in range(500):
        raiselines()
        print "RAISING!"


def addline():

    for x in range(100):
        if x not in liney: #find next unused number in dic
            print "next number =", x
            break

    hole1[x] = random.randrange(0,ww-holesize)  #make left x of hole
    hole2[x] = hole1[x]+holesize          #find right x, change hole x values to tuple

    print hole1[x],hole2[x]

    liney[x] = wbottom - lineh  #start new line at bottom


def raiselines():

    deleteline = 99

    linesmoved = 0
    for x in range(100):
        if x in liney:
            liney[x]-=linespd
            linesmoved +=1
            #if linesmoved == numberoflines + 1:
            #    break

        if liney[x] + lineh -linespd < 0: #kill line, bottom of line is offscreen
            deleteline = x

    if deleteline != 99:  #if a line is off the screen completely, kill it
        del liney[x]

    redraw()  #once the new liney values are found, redraw everything



def redraw():

    window.delete(ALL) # This erases everything on the canvas.

    for x in liney:

        if liney[x]<0:liney[x]=0 #incase anything is off screen

        window.create_rectangle(0,liney[x],hole1[x],liney[x]+lineh, fill=linecolor[x]) #line before hole
        window.create_rectangle(hole2[x],liney[x],wright,liney[x]+lineh, fill=linecolor[x]) #line after ho

    window.update() # This refreshes the drawing on the canvas.
    window.after(cycle_period) # This makes execution pause for some milliseconds.
    root.mainloop()


ballmins = 15  #min speed of ball from 0
ballmaxs = 20   #max speed of ball (if I decide to accelerate the ball)
ballacc = 1.3  #may or may not accelerate ball.  1 = no accel, >1 = accel

lineh = 14 #thickness of lines (height of box)
linespd = 10  #how fast to raise lines

wh = 700 #window height
ww = 600 #window width
wleft = 0
wtop = 0
wright = wleft + ww  #a lot of these seem useless, but i think they will
wbottom = wtop + wh  #make everything easier to understand in the code

holesize = 80
ballsize = 75

# i <3 dics
liney = {}
linecolor = {}
hole1 = {}
hole2 = {}

#gui
root = Tk()
root.title("Fall Down")
cw = 1000 # canvas width
ch = 1000 # canvas height

window = Canvas(root, width=cw, height=ch, background="white")
window.grid(row=0, column=0)
cycle_period = 1 # time between frames in ms


if __name__ == '__main__':
    main()




Is This A Good Question/Topic? 0
  • +

Replies To: Question about loops for animation with Tkinter

#2 witeboy724  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 30
  • Joined: 21-June 12

Re: Question about loops for animation with Tkinter

Posted 15 July 2012 - 08:22 PM

I figured out what the problem was. I guess I didn't really understand what root.mainloop() was doing during its loop. I think I may have to add it back in somewhere later on once I'm ready to start watching for keypresses. For now though, the background it getting closer to what I would like to start with. I'll go ahead and post the code for anyone who is interested.

The starting lines and added lines aren't even. It's slow, and sizes, speeds, positions, and other stuff needs to change, blah blah. Next step I'll smooth it out. As far as the question in this thread is concerned, I think the answer is to just leave out root.mainloop() for now. Thanks everyone who took a look.


import random
from Tkinter import *


def main():


    #first run, get all new lines

    numberoflines = 10

    for x in range (1,numberoflines):
        addline()
        liney[x] = ((wh - lineh)/numberoflines) * x #if there are n lines, line 1 goes at 1/n of wh, line 2 at 2/n, etc.
        linecolor[x] = "black" #can change later


    redraw()


    while STOP == False:
        raiselines()
        print "RAISING!"


def addline():

    for x in range(1,100):
        if x not in liney: #find next unused number in dic
            print "new line number =", x
            break

    liney[x] = wbottom  #start new line at bottom
    hole1[x] = random.randrange(0,ww-holesize)  #make left x of hole
    hole2[x] = hole1[x]+holesize          #find right x, change hole x values to tuple?
    linecolor[x] = "black"

    print x, liney[x],hole1[x],hole2[x]



def raiselines():

    deleteline = 99  #99 here means don't delete any lines

    linesmoved = 0
    for x in liney:
        liney[x]-=linespd


        if liney[x] + lineh -linespd < 0: #kill line, bottom of line is offscreen
            deleteline = x

    if deleteline != 99:  #if a line is off the screen completely, kill it
        del liney[deleteline]

    global newlinecounter
    newlinecounter += 1
    if newlinecounter == newlinefreq:
        newlinecounter = 0
        addline()

    redraw()  #once the new liney values are found, redraw everything



def redraw():

    window.delete(ALL) # This erases everything on the canvas.

    for x in liney:

        if liney[x] + lineh - linespd<0:liney[x]=0-lineh #in case a line is off screen, shouldn't be necessary

        print x
        print "liney, hole1, hole2"
        print liney[x],hole1[x],hole2[x]


        #temp fix until I figure out the quickest and cleanest way to do make bottom lines scroll into view rather than just pop up
        if liney[x] + lineh > wbottom:   #if line goes off the bottom of the screen, it equals the bottom of the screen
            linebottom = wbottom
        else:
            linebottom = liney[x]+lineh

        window.create_rectangle(0,liney[x],hole1[x],linebottom, fill=linecolor[x]) #line before hole
        window.create_rectangle(hole2[x],liney[x],wright,linebottom, fill=linecolor[x]) #line after ho


    #Create border to show window size.  window was a poor choice for a variable name as it turns out
    window.create_rectangle(wleft,wtop,wright,wbottom, fill="", outline = "black")


    window.update() # This refreshes the drawing on the canvas.
    window.after(cycle_period) # This makes execution pause for some milliseconds.



ballmins = 15  #min speed of ball from 0
ballmaxs = 20   #max speed of ball (if I decide to accelerate the ball)
ballacc = 1.3  #may or may not accelerate ball.  1 = no accel, >1 = accel


lineh = 14 #thickness of lines (height of boxes)
linespd = 1  #how fast to raise lines
newlinefreq = 90 #number of frames between lines - smaller number, less wait between lines
newlinecounter = newlinefreq - 1 #counts to newlinefreq, creates new line, resets to 0

wh = 700 #window height
ww = 600 #window width
wleft = 0
wtop = 0
wright = wleft + ww  #a lot of these seem useless, but i think they will
wbottom = wtop + wh  #make everything easier to understand in the code

holesize = 80
ballsize = 75

# i <3 dics
liney = {}
linecolor = {}
hole1 = {}
hole2 = {}

#gui
root = Tk()
root.title("Fall Down")
cw = 1000 # canvas width
ch = 1000 # canvas height

STOP = False

window = Canvas(root, width=cw, height=ch, background="white")
window.grid(row=0, column=0)
cycle_period = 1 # time between frames in ms


if __name__ == '__main__':
    main()



Was This Post Helpful? 0
  • +
  • -

Page 1 of 1