Search code examples
pythonpython-3.xtkinterpong

pong game tkinter ball collision with paddle problem


does anyone know how i can make the ball go out of the screen if it doesn't touch the paddle?

this is the line that im having trouble with:

# intersection avec les raquettes
    elif newX<= hit1:
      newX=balle[0]
      balle[2]*=-1

and here's the complete code:

from tkinter import *
myHeight=400
myWidth=800
mySpeed=10

def initialiserBalle(dx,dy,rayon,couleur):
    b=[myWidth/2,myHeight/2,dx,dy,rayon]
    b.append(myCanvas.create_oval(myWidth/2-rayon,myHeight/2-rayon,\
                                  myWidth/2+rayon,myHeight/2+rayon,\
                                  width=2,fill=couleur))
    return b

def initialiserRaquette(x,y,largeur,hauteur,couleur):
    r=[x,y,0,0,largeur,hauteur]
    r.append(myCanvas.create_rectangle(x-largeur/2,y-hauteur/2,\
                                      x+largeur/2,y+hauteur/2,\
                                      width=2,fill=couleur))
    return r

def miseAJourBalle():
    # calcul de la nouvelle position
    newX=balle[0]+balle[2]
    newY=balle[1]+balle[3]
    hit1=raquette1[0]+raquette1[4]
    hit2=raquette2[1]+raquette2[5]
    # correction
    if newX<0 or newX>=myWidth:    
        newX=balle[0]
        balle[2]*=-1
    if newY<0 or newY>=myHeight:
        newY=balle[1]
        balle[3]*=-1

    # intersection avec les raquettes
    elif newX<= hit1:
      newX=balle[0]
      balle[2]*=-1


    # mise a jour des coordonnees
    balle[0]=newX
    balle[1]=newY
    # mise a jour de l'element graphique
    myCanvas.coords(balle[5],\
                    balle[0]-balle[4],balle[1]-balle[4],\
                    balle[0]+balle[4],balle[1]+balle[4])

def miseAJourRaquette(r):
    newY=r[1]+r[3]
    if newY-r[5]/2<0 or newY+r[5]/2>=myHeight:
        newY=r[1]
        r[3]=0
    r[1]=newY
    myCanvas.coords(r[6],\
                    r[0]-r[4]/2,r[1]-r[5]/2,\
                    r[0]+r[4]/2,r[1]+r[5]/2)
   
def animation():
    miseAJourBalle()
    miseAJourRaquette(raquette1)
    miseAJourRaquette(raquette2)
    myCanvas.after(mySpeed,animation)

def moveRaquettes(event):
    if event.keysym == 'a':
        raquette1[3]=-5
    if event.keysym == 'q':
        raquette1[3]=5
    if event.keysym == 'Up':
        raquette2[3]=-5
    if event.keysym == 'Down':
        raquette2[3]=5

def stopRaquettes(event):
    if event.keysym == 'a' or event.keysym == 'q':
        raquette1[3]=0
    if event.keysym == 'Up' or event.keysym == 'Down':
        raquette2[3]=0

mainWindow=Tk()
mainWindow.title('Pong')
mainWindow.geometry(str(myWidth)+'x'+str(myHeight))
myCanvas=Canvas(mainWindow,bg='dark grey',height=myHeight,width=myWidth)
myCanvas.pack(side=TOP)
balle=initialiserBalle(5,5,20,'red')
raquette1=initialiserRaquette(60,myHeight/2,40,100,'green')
raquette2=initialiserRaquette(myWidth-60,myHeight/2,40,100,'pink')
mainWindow.bind("<Key>",moveRaquettes)
mainWindow.bind("<KeyRelease>",stopRaquettes)
animation()
mainWindow.mainloop()



Solution

  • remove this if statement:

    if newX<0 or newX>=myWidth:    
           newX=balle[0]
           balle[2]*=-1
    

    this is the part that doesn't allow the ball to go outside the vertical walls

    and replace your miseAJourBalle function with this:

    def miseAJourBalle():
        # calcul de la nouvelle position
        newX=balle[0]+balle[2]
        newY=balle[1]+balle[3]
        hit1=raquette1[0]+raquette1[4]
        hit2=raquette2[1]+raquette2[5]
        
        if newY<0 or newY>=myHeight:
            newY=balle[1]
            balle[3]*=-1
    
        # intersection avec les raquettes
    
        bbox1 = myCanvas.bbox(raquette1[6])
        bbox2 = myCanvas.bbox(raquette2[6])
            
        if newX <= bbox1[2] and (newY>bbox1[1] and newY<bbox1[3]):
            newX=balle[0]
            balle[2]*=-1  
    
        if newX >= bbox2[0] and (newY>bbox2[1] and newY<bbox2[3]):
            newX=balle[0]
            balle[2]*=-1  
    
        # mise a jour des coordonnees
        balle[0]=newX
        balle[1]=newY
        # mise a jour de l'element graphique
        myCanvas.coords(balle[5],\
                        balle[0]-balle[4],balle[1]-balle[4],\
                        balle[0]+balle[4],balle[1]+balle[4])
    
    

    bbox will return a tuple describing the bounding box of the rectangle use that to check the if the ball has hit the rectangle.

    Also, next time when you post a question pls consider adding English comments beside the function names so we can easily know what each function does. Translation apps don't always give correct translation