Reputation: 1
I'm in the process of trying to make a very simple ball and paddle game in Python and have the ball moving on the screen with a paddle that moves from left to right. But, the ball moves and hits the bottom of the screen and doesn't change direction, it just stops and slides against the wall.
Any help or suggestions would be appreciated. Here is the code:
from tkinter import Canvas, Tk
import random
canvas_width = 800
canvas_height = 400
root = Tk()
root.title("Ball and Paddle")
c = Canvas(root,width=canvas_width,height=canvas_height,background='orange')
c.pack()
paddle_color = 'blue'
paddle_width = 60
paddle_height = 10
paddle_start_x = canvas_width/2 - paddle_width/2
paddle_start_y = canvas_height - paddle_height - 20
paddle_start_x2 = canvas_width/2 + paddle_width/2
paddle_start_y2 = canvas_height - 20
paddle = c.create_rectangle(paddle_start_x,paddle_start_y,\
paddle_start_x2,paddle_start_y2,\
fill='blue', width=0)
ball_color = 'green'
ball_width = 20
ball_height = 20
ball_start_x1 = canvas_width/2 - ball_width/2
ball_start_y1 = canvas_height/2 - ball_height/2
ball_start_x2 = canvas_width/2 + ball_width/2
ball_start_y2 = canvas_height/2 + ball_height/2
ball_speed = 5
ball = c.create_oval(ball_start_x1, ball_start_y1, \
ball_start_x2, ball_start_y2, \
fill = ball_color, width = 0)
dx = 1
dy = 1
def ball_move():
global dx, dy
(bx1,by1,bx2,by2) = c.coords(ball)
c.move(ball, dx, dy)
if bx1 <= 0:
dx = -dx
if bx2 >= canvas_width:
dx = -dx
if by1 <= 0:
dy = -dy
if by2 >= canvas_height:
dy = -dy
root.after(ball_speed, ball_move)
def move_left(event):
(x1,y1,x2,y2) = c.coords(paddle)
if x1>0:
c.move(paddle,-20,0)
def move_right(event):
(x1,y1,x2,y2) = c.coords(paddle)
if x2 < canvas_width:
c.move(paddle, 20, 0)
c.bind('<Left>',move_left)
c.bind('<Right>',move_right)
c.focus_set()
root.after(ball_speed, ball_move)
root.mainloop()
Upvotes: 0
Views: 1642
Reputation: 76234
(I'm assuming that the if bx1 <= 0:
indentation problem isn't actually present in your real code, and was just a transcription error when writing this post)
This occurs because the ball is getting "lodged" into the border of the screen, when by2 has a value of 401. You reverse dy, which makes it move up to 400 at the next frame. But then you reverse dy again, so it moves back down to 401.
This happens because you're creating the b* variables, then moving the ball, then doing boundary checking on the b* variables. You're effectively inspecting the position of the ball from the previous frame.
Try moving the move
call to after the boundary check.
def ball_move():
global dx, dy
(bx1,by1,bx2,by2) = c.coords(ball)
if bx1 <= 0:
dx = -dx
if bx2 >= canvas_width:
dx = -dx
if by1 <= 0:
dy = -dy
if by2 >= canvas_height:
dy = -dy
c.move(ball, dx, dy)
root.after(ball_speed, ball_move)
Now your ball should bounce.
Upvotes: 2
Reputation: 3731
Indentation issue:
def ball_move():
global dx, dy
(bx1,by1,bx2,by2) = c.coords(ball)
c.move(ball, dx, dy)
if bx1 <= 0:
dx = -dx
if bx2 >= canvas_width:
..snippet..
should be:
def ball_move():
global dx, dy
(bx1,by1,bx2,by2) = c.coords(ball)
c.move(ball, dx, dy)
if bx1 <= 0:
dx = -dx # indent corrected here!
if bx2 >= canvas_width:
..snippet..
Upvotes: 0