I am currently writing a brickbreaker game in python to teach myself classes and such however I am unable to get the ball to show up. I have the bricks and the paddle, the paddle is moving but not seeing the ball. Any idea why?
import tkinter as tk #display graphic user interface
class PlayComponent(object):
def __init__(self, canvas, item): #pass canvas and item
self.item = item
self.canvas = canvas
def move(self, x, y):
self.canvas.move(self.item,x,y)
def position(self):
return self.canvas.coords(self.item)
def delete(self):
self.canvas.delete(self.item)
class Paddle(PlayComponent): #incorporate all of the playcomponent class
def __init__(self, canvas, x, y): #pass to our initialiation function
self.height = 5
self.width = 100
self.ball = None
item = canvas.create_rectangle(x-self.width/2, y-self.height/2, x+self.width/2, y+self.height/2, fill='green')
super(Paddle,self).__init__(canvas,item)
def set_ball(self,ball):
self.ball = ball
def move(self,dist):
coord = self.position()
width = self.canvas.winfo_width() #prevents paddle from changing size with screen size
if coord[2] +dist <=width and coord[0] +dist >=0:
super(Paddle,self).move(dist, 0)
if self.ball is not None:
self.ball.move(dist,0)
class Brick(PlayComponent):
colorArray = {1:'lightsteelblue', 2: 'royalblue', 3: 'blue'}
def __init__(self, canvas, x, y, hits):
self.width = 60
self.height = 20
self.hits = hits
color = Brick.colorArray[hits] #color changes with number of its
item = canvas.create_rectangle(x-self.width/2,y-self.height/2, x+self.width/2, y+self.height/2, fill = color, tag = 'brick')
super(Brick,self).__init__(canvas, item)
def hit(self):
self.hits -= 1
if self.hits == 0:
self.delete()
else:
self.canvas.itemconfig(self.item, fill=Brick.colorArray[self.hits])
class Ball(PlayComponent):
def __init__(self,canvas, x, y):
self.radius = 16
self.speed = 8
self.direction = [-1,1] #if ball hits a wall it goes in the opposite direction
item = canvas.create_oval(x-self.radius, y-self.radius, x+self.radius, y+self.radius, fill = 'white')
super(Ball,self).__init__(canvas,item) #calls the ball class
def update(self):
coord = self.position()
width = self.canvas.winfo_width() #width of the ball and assigns it to the ball
if coord[1] <=0: #if we are hitting top or bottom
self.direction[1]*= -1 #will change the direction of the ball using the multiplication method
if coord[2] >=width or coord[0] <=0: #if we are hitting left or right wall
self.direction[0]*= -1
#create moving ball
x - self.direction[0] * self.speed
y = self.direction[1] * self.speed
self.move(x,y)
def intersect(self,components):
coord = self.position()
x = (coord[0] + coord[2])*0.5
if len(components) == 1:
component = components[0]
coord = component.position()
if x < coord[0]:
self.direction[0] =- 1
elif x > coord[2]:
self.direction[0] = 1
else:
self.direction[1]+= -1
elif len(components)>1:
self.diirection[1]*=1
for component in components:
if isinstance(component,Brick):
component.hit()
class Game(tk.Frame):
def __init__(self, master): #initialization function
super(Game,self).__init__(master) #super class
#create window
self.width = 1000;
self.height = 400;
#create canvas
self.canvas = tk.Canvas(self, bg = 'brown',
width = self.width,
height = self.height)
self.canvas.pack()
self.pack()
self.items = {}
self.ball = None
self.paddle = Paddle(self.canvas, self.width/2, 320) #determins where paddle starts
self.items[self.paddle.item] = self.paddle
self.hud = None
for x in range(100, self.width -100, 60):
self.display_brick(x+20, 50,2)
self.canvas.focus_set()
self.canvas.bind('<Left>', lambda _:self.paddle.move(-30))
self.canvas.bind('<Right>', lambda _:self.paddle.move(30))
def init_game(self):
self.display_ball()
self.start_game()
def display_ball(self):
if self.ball is not None:
self.ball.delete()
paddle_coords = self.paddle.position()
x = (paddle_coords[0] + paddle_coords[2])*0.5
self.ball = Ball(self.canvas,x,310)
self.paddle.set_ball(self.ball)
def display_brick(self, x, y, hits):
brick = Brick(self.canvas, x, y, hits)
self.items[brick.item] = brick
def start_game(self):
self.canvas.unbind('<space>') #press space bar
self.paddle.ball = None
def game_loop(self):
self.verify_inter()
num__bricks = len(self,canvas.find_withtag('brick'))
if num_bricks == 0:
self.ball.speed = None
else:
self.ball.update()
self.after(50,self.game_loop())
def verify_inter(self):
ball_coords = self.ball.position()
items = self.canvas.find_overlapping(*ball_coords)
object = [self.items[x] for x in items if x in self.items]
self.ball.intersect(object)
if __name__ == '__main__':
root=tk.Tk()
root.title('Brick Breaker')
game = Game(root) #calling game function
#print(game)
#print(game.width)
game.mainloop() #loops around game