•

Check out our Community Blogs

Register and join over 40,000 other developers!

Recent Blog Entries

• surajkumardotin

Student college project

• TopHatProductions115

The TXP-Network is coming back this July...

• moonvik

Java...

• phi

I love this community !

• JackJames

hi i am jack i am seo expert jack james would love you to read new post

Tkinter bouncy ball with full control over direction

python tkinter game

No replies to this topic

#1 DanielTan

DanielTan

CC Regular

• Member
• 25 posts

Posted 07 August 2013 - 06:16 AM

Right, in my previous tutorial

I wrote some code for a ball snake game. Problem is, in that game, there's only eight directions. Now then, let's get greedy and make it go any way we want.

Also, we will use parametric functions do make paths for our sprites, which in this case, for simplicity, will be simple geometric shapes.

I got this idea to use vectors from a website for java programming (forgot what it was though), and it proved useful for games like these, where you need every direction possible. The thing was, it did not hurt to have some understanding of physics and maths.

Besides, it's easier to write maths in python.

Here's the code first:

I will just copy paste the outer shell of the interface here, to save some time.

```from tkinter import *
from random import*
from math import *

'''New game to illustrate the use of tkinter to make a game that can handle collisions.
'''

class game:
def __init__(self):
self.root=Tk()
self.RUN=False

self.frame=Frame(bg="black")
self.frame.pack();

self.canvas=Canvas(self.frame, bg="black",width=300,height=300)
self.canvas.pack()

self.clock=Label(self.frame, bg="black", fg="white")
self.clock.pack()
self.points=Label(self.frame, bg="black", fg="white")
self.points.pack()
self.button=Button(self.frame, bg="black", fg="white", text="Click to start" ,command=self.start)
self.button.pack()

self.root.mainloop()

def start(self):
self.time=0
self.RUN=True

self.foodX=[]
self.foodY=[]

self.trapX=[]
self.trapY=[]

self.powerupX=[[],[]]
self.powerupY=[[],[]]

self.TEXT="Welcome to tkinter"
self.point=0

self.x=100
self.y=100
self.xa=200
self.ya=100
self.tempx=0
self.tempy=0

self.size=3
self.canvas.bind("<ButtonPress-1>", self.onMClick)
self.run()

def run(self):
if self.RUN is True:
self.time+=1
#Here's where the ball circles round and round
self.xa+=25*sin((pi/3)*self.time)
self.ya+=25*cos((pi/3)*self.time)
self.clock['text']="TIME:" + str(self.time//100)
self.points['text']="Points gathered: " + str(self.point)
self.move(10*self.size,2)
self.paint()
self.root.after(10, self.run)

def end(self):
self.RUN=False
self.canvas.unbind("<ButtonPress-1>")

def paint(self):
self.canvas.delete(ALL)
self.canvas.create_text(100,100, text=self.TEXT, fill="green")

if self.time//100<=60:
if 10*self.size >0:
self.TEXT="Welcome to tkinter"
ball=self.canvas.create_oval(self.x-10*self.size,self.y-10*self.size,self.x+10*self.size,self.y+10*self.size, fill="white")
hey=self.canvas.create_oval(self.xa-10,self.ya-10,self.xa+10,self.ya+10, fill="white")

def move(self, b,speed):
#movement handler

def onMClick(self,event):
#mouseclick events

app=game()

```

The outer shell of the interface is covered in that link above, so let's continue with the juicier parts. We want the ball to move where we click.

FIrst, we should have the mouseclick update the direction vector, which is a vector, of length one.

```def onMClick(self,event):
#using unit vectors here
X=event.x-self.x
Y=event.y-self.y
self.tempx=X/((X**2 + Y**2)**(0.5))
self.tempy=Y/((X**2 + Y**2)**(0.5))
print(self.tempx, self.tempy)
```

once again, i allow the event handler to handle the direction, and another function to handle movements and collisions.

```def move(self, b,speed):
if self.tempy and self.y-b>0 and  self.y+b<300:
self.y+=speed*self.tempy
elif self.tempy<=0 and self.y-b<=0 :
self.tempy*=-1
self.y+=speed*self.tempy
elif self.tempy>0 and self.y+b>=300:
self.tempy*=-1
self.y+=speed*self.tempy
if self.tempx and self.x-b>0 and  self.x+b<300:
self.x+=speed*self.tempx
elif self.tempx<=0 and self.x-b<=0 :
self.tempx*=-1
self.x+=speed*self.tempx
elif self.tempx>0 and self.x+b>=300:
self.tempx*=-1
self.x+=speed*self.tempx
```

The good thing about vectors is that just by multiplying it by negative one, you reverse the direction.

There! add this to the outer shell and you're done.

Also, you might notice that there is a rotating circle.

from this:

```    def run(self):
if self.RUN is True:
self.time+=1
#Here's where the ball circles round and round
self.xa+=25*sin((pi/3)*self.time)
self.ya+=25*cos((pi/3)*self.time)
self.clock['text']="TIME:" + str(self.time//100)
self.points['text']="Points gathered: " + str(self.point)
self.move(10*self.size,2)
self.paint()
self.root.after(10, self.run)
```

Where the sin and cos are both parametric equations of a circle.

And voila, your ball will move anywhere you want it and it will bounce off walls.

• 0

Also tagged with one or more of these keywords: python, tkinter, game

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download