#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    2
    Rep Power
    0

    Help with using Tkinter on Python


    Hello, I am trying to use Tkinter GUI from Python to develop a simple game. I've searched all over for this answer on Google but haven't been able to find a sufficient enough answer to my question.

    How would I go about getting a pixel image of a player and put him on screen and respond to keys?

    small note: I am using Python 3.3 and the syntax is a little different from earlier versions.
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    12
    Rep Power
    0
    Why Tkinter if there's some game oriented resources for Python? Check this:

    Google Python Programming/Game Programming in Python wikibooks

    It will get you a list with the possibilities for 2D and also 3D programming.
    (I would post the link but i can't due to newbieness)
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    190
    Rep Power
    2
    Agreed. Use pygame or pyglet. Tkinter doesn't even have native support for png or jpg files. This means you are going to have to use a non-standard library anyway; it might as well be a more appropriate tool.

    Here is a script showing a rectangle that you can control with arrow keys in tkinter (tkinter is not my specialty though so I apologize if there is a better way to accomplish the same thing).

    python Code:
    try:
        import Tkinter as tk
    except ImportError:
        import tkinter as tk
     
     
    DIRECT_DICT = {'Up'    : ( 0,-1),
                   'Down'  : ( 0, 1),
                   'Left'  : (-1, 0),
                   'Right' : ( 1, 0)}
     
     
    class Sprite(object):
        def __init__(self,location,size):
            self.x,self.y = location
            self.width,self.height = size
            self.speed = 3
     
        def update(self,canvas,keys):
            rect = (self.x,self.y,self.x+self.width,self.y+self.height)
            canvas.create_rectangle(rect,outline="green",fill="purple",width=2)
            for key in DIRECT_DICT:
                if keys.get(key,False):
                    self.x += DIRECT_DICT[key][0]*self.speed
                    self.y += DIRECT_DICT[key][1]*self.speed
     
     
    class Control(object):
        def __init__(self):
            self.root = tk.Tk()
            self.canvas = tk.Canvas(self.root,width=500,height=500,bg='dark slate gray')
            self.canvas.focus_set()
            self.canvas.bind("<Key>",self.key_pressed)
            self.canvas.bind("<KeyRelease>",self.key_released)
            self.canvas.pack()
            self.fps = 60
            self.player = Sprite((250,250),(50,50))
            self.pressed = {}
     
        def key_pressed(self,event):
            self.pressed[event.keysym] = True
     
        def key_released(self,event):
            self.pressed[event.keysym] = False
     
        def update(self):
            self.canvas.delete(tk.ALL)
            self.player.update(self.canvas,self.pressed)
            self.root.after(1000//self.fps,self.update)
     
        def main(self):
            self.update()
            self.root.mainloop()
     
     
    if __name__ == "__main__":
        run_it = Control()
        run_it.main()

    -Mek

    Comments on this post

    • TheNaiveCoder agrees : Wow, this is really nice
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    In this code the figure walks during rotation. Why?
    Code:
    '''
        Try mouse over and the keys
            Up
            Right
            Left
            Down
            asterisk
            slash
            r
    
            space
            q
    '''
    
    DEBUG = False and True
    
    import sys, pprint, operator
    
    if sys.version[0] != '3':
        sys.stderr.write('Version 3 required\n')
        exit(0)
    
    import math
    import tkinter
    
    if DEBUG:
        help(tkinter.Canvas.create_polygon)
    
    TAU = 2*math.pi # http://tauday.com
    
    def car(L):
        return L[0]
    
    def cdr(L):
        return L[1:]
    
    def flatten(L):
        if hasattr(L, '__len__'):
            if L:
                return flatten(car(L)) + flatten(cdr(L))
            return []
        return [L]
    
    def dotproduct(x, y, u = sum, v = operator.mul):
        result = [[0] * len(y[0]) for i in x]
        for (i, X,) in enumerate(x):
            for (j, Y,) in enumerate(zip(*y)):
                result[i][j] = u(list(map(v, X, Y)))
        return result
    
    def average(L):
        return sum(L) / len(L)
    
    def scale(L, factor):
        return [a*factor for a in L]
    
    def translate(L, t):
        return [a+t for a in L]
    
    def scale_about_center(L, factor):
        t = average(L)
        return translate(scale(translate(L, -t), factor), t)
    
    def rotate_about_center(x, y, d):
        (s, c,) = (math.sin(d), math.cos(d),)
        (tx, ty,) = (average(x), average(y),)
        (x,y,h,) = dotproduct(
            dotproduct([[1,0,tx],[0,1,ty],[0,0,1]],dotproduct([[c,s,1],[-s,c,1],[0,0,1]],[[1,0,-tx],[0,1,-ty],[0,0,1]])),
            [x,y,[1]*len(x)])
        return (x,y,)
    
    def star(points=5):
        n = 1+2*(min(max(int(points),3),103)//2)
        (x, y,) = ([], [],)
        d = TAU * (n//2) / n
        for i in range(n):
            angle = (d*i)%TAU
            x.append(math.cos(angle))
            y.append(math.sin(angle))
        return (x, y,)
    
    class c:
    
        def __init__(self, points = 7):
            self.root = root = tkinter.Tk()
            self.canvas = canvas = tkinter.Canvas(root)
            canvas.pack()
            (self.t, self.radius,) = (5, 20,)
            (x, y,) = (scale(a, self.radius) for a in star(points))
            self.rotation = TAU/(3*points)
            root.update()
            config = canvas.config()
            if DEBUG:
                print(canvas.config())
                pprint.pprint(config)
            (w, h,) = (int(config[a][-1]) for a in 'width height'.split())
            x = translate(x, w//2)
            y = translate(y, h//2)
            self.sprite = canvas.create_polygon(
                *flatten(tuple(zip(x, y))),
                width=4, joinstyle=tkinter.BEVEL,
                outline='grey', fill='blue',
                activeoutline='grey2', activefill='pink')
            canvas.bind('<Key>', self.keycallback)
            #canvas.bind('<Button>', canvas.focus_set) # screwy.
            canvas.focus_set()
    
            if DEBUG:
                pprint.pprint(canvas.itemconfig(self.sprite))
    
            root.mainloop()
    
        def __str__(self):
            return pprint.pformat(self.xy)
    
        def keycallback(self, event):
            if event.keysym in set('asterisk 8'.split()):
                self.enlarge()
            elif event.keysym == 'slash':
                self.shrink()
            elif event.keysym == 'Up':
                self.move(UD= 1)
            elif event.keysym == 'Down':
                self.move(UD=-1)
            elif event.keysym == 'Left':
                self.move(LR=-1)
            elif event.keysym == 'Right':
                self.move(LR= 1)
            elif event.keysym == 'r':
                self.xy = rotate_about_center(*self.xy, d = self.rotation)
            elif event.keysym == 'space':
                print(self)
            elif event.keysym == 'q':
                self.canvas.quit()
            if DEBUG:
                print()
                for attribute in dir(event):
                    if not attribute.startswith('__'):
                        print(attribute, getattr(event, attribute))
    
        def getxy(self):
            xy = self.canvas.coords(self.sprite)
            return (xy[0::2], xy[1::2],)
    
        def setxy(self, xy):
            self.canvas.coords(self.sprite, *flatten(tuple(zip(*xy))))
    
        xy = property(getxy, setxy)
    
        def enlarge(self):
            r = self.radius
            factor = 2-math.atan(r)*4/TAU
            self.radius = r*factor
            if DEBUG:
                print('enlarge', r, self.radius, factor)
            self.xy = [scale_about_center(a, factor) for a in self.xy]
    
        def shrink(self):
            r = self.radius
            factor = 1-0.5*math.atan(r/99)/(TAU/4)
            self.radius = r*factor
            if DEBUG:
                print(' shrink', r, self.radius, factor)
            self.xy = [scale_about_center(a, factor) for a in self.xy]
    
        def move(self,LR=0,UD=0):
            t = self.t
            (x, y,) = self.xy
            self.xy = (translate(x,  t*LR), translate(y, -t*UD),)
    
    print(__doc__)
    c()
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    @Mekire

    Does your code leak memory? Instead of changing the item coordinates you make new rectangles on the canvas. I don't know the answer.

    Thanks, Dave.
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    190
    Rep Power
    2
    Originally Posted by b49P23TIvg
    @Mekire

    Does your code leak memory? Instead of changing the item coordinates you make new rectangles on the canvas. I don't know the answer.

    Thanks, Dave.
    Hmm... well there was no memory leak to my knowledge because I was calling
    Code:
    self.canvas.delete(tk.ALL)
    every frame.

    That aside though you are correct. I was under the false assumption that the create_blah canvas methods simply drew on the canvas. I was unaware that they could later be manipulated.

    -Mek
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    2
    Rep Power
    0
    Wow this got a lot more answers than I thought. Thanks, guys.

    I've been having trouble with pygame and its installation messing up my idle so I thought I'd just go with tkinter because it comes packed with python. I'll try to look into that more.

IMN logo majestic logo threadwatch logo seochat tools logo