Random func is not working. Ball only goes one direction - python

Here is my code but for some reason whenever I run it the ball only goes in one direction.
from tkinter import * import random import time
class Ball:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
self.canvas.move(self.id, 245, 100)
starts = [-3, -2, -1, 1, 2, 3]
random.shuffle(starts)
self.x = starts[0]
self.y = -3
self.canvas_height = self.canvas.winfo_height()
self.canvas_width = self.canvas.winfo_width()
def draw(self):
self.canvas.move(self.id, self.x, self.y)
pos = self.canvas.coords(self.id)
if pos[1] <= 0:
self.y = 1
if pos[3] >= self.canvas_height:
self.y = -1
if pos[0] <= 0:
self.x = 3
if pos[2] >= self.canvas_width:
self.x = -3
tk = Tk()
tk.title("Game")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
ball = Ball(canvas, 'red') while 1:
ball.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
Can someone please help me?

Shuffle is working properly but there is some problem with your logic due to which ball always go to the left side and in the upward direction. You need to revise that. Also you must use if and elif in draw method for both x and y to stop your ball going out of the frame instead of using if for all.
Feel free to ask question incase of any confusion.

In case you ever run into issue like this, try debugging or at least printing some crucial values to double-check if these in fact are correct (same as you assumed).
And so if you would print self.canvas_height and self.canvas_width values you would notice that these are incorrect (they always return 1).
Solution to your problem is to change these lines in your init function:
self.canvas_height = self.canvas.winfo_height()
self.canvas_width = self.canvas.winfo_width()
to these lines:
self.canvas_height = self.canvas.winfo_reqheight()
self.canvas_width = self.canvas.winfo_reqwidth()

Related

How do I create 4 squares in tkinter so that they start in the middle of the screen and each one of them goes in its own corner and disappears?

Here is the code, I have managed to position the square a little bit but the whole thing is just messy and fast when executed, it doesn't really resemble anything, let alone what I wanted to make.
What do I need to do in order to get these 4 squares to start in the middle and move to each corner, disappearing from the screen? I made an example here:
from tkinter import *
W, H = 500, 500
tk = Tk()
canvas = Canvas(tk,width=W,height=H)
canvas.pack()
class Square:
def __init__(self,size,speedx, speedy, color):
self.square = canvas.create_rectangle(50,50,100,100,fill=color)
self.speedx = speedx
self.speedy = speedy
self.movement()
def movement(self):
canvas.move(self.square,self.speedx,self.speedy)
pos = canvas.coords(self.square)
if pos[2]>=W or pos[0]<=0:
self.speedx *= -1
if pos[3]>=H or pos[1]<=0:
self.speedy *= -1
tk.after(40,self.movement)
square1 = Square(200,150,200,'brown')
square2 = Square(200,200,150,'yellow')
square3 = Square(200,200,200,'green')
square4 = Square(200,150,150,'blue')
tk.mainloop()
You need to define direction for each rectangle separately, so that each of them moves its own way.
import tkinter as tk
W, H = 500, 500
SPEED = 20
window = tk.Tk()
canvas = tk.Canvas(window, width=W, height=H)
canvas.pack()
class Square:
def __init__(self, x, y, color, speed_x, speed_y):
self.speed_x = speed_x
self.speed_y = speed_y
self.square = canvas.create_rectangle(x, y, x+50, y+50, fill=color)
self.movement()
def movement(self):
canvas.move(self.square, self.speed_x, self.speed_y)
window.after(200, self.movement)
Square(200, 200, 'brown', -SPEED, -SPEED)
Square(250, 200, 'yellow', SPEED, -SPEED)
Square(200, 250, 'green', -SPEED, SPEED)
Square(250, 250, 'blue', SPEED, SPEED)
window.mainloop()
Output:

tkinter breakout game beginner problems

I am trying to build a Breakout game for python tkinter with different levels. I don't quite understand the self and __init__ functions in this code.
Is there a way to create the game without those functions or replacing them with simpler functions if it's possible? Also, I don't quite understand the + self.radius parts in the code as well.
import tkinter as tk
def new_window():
root1 = tk.Tk()
root1.title('Jeu')
game = Game(root1)
class GameObject(object):
def __init__(self, canvas, item):
self.canvas = canvas
self.item = item
def get_position(self):
return self.canvas.coords(self.item)
def move(self, x, y):
self.canvas.move(self.item, x, y)
def delete(self):
self.canvas.delete(self.item)
class Ball(GameObject):
def __init__(self, canvas, x, y):
self.radius = 10
self.direction = [1, -1]
# increase the below value to increase the speed of ball
self.speed = 5
item = canvas.create_oval(x - self.radius, y - self.radius,
x + self.radius, y + self.radius,
fill='white')
super(Ball, self).__init__(canvas, item)
def update(self):
coords = self.get_position()
width = self.canvas.winfo_width()
if coords[0] <= 0 or coords[2] >= width:
self.direction[0] *= -1
if coords[1] <= 0:
self.direction[1] *= -1
x = self.direction[0] * self.speed
y = self.direction[1] * self.speed
self.move(x, y)
def collide(self, game_objects):
coords = self.get_position()
x = (coords[0] + coords[2]) * 0.5
if len(game_objects) > 1:
self.direction[1] *= -1
elif len(game_objects) == 1:
game_object = game_objects[0]
coords = game_object.get_position()
if x > coords[2]:
self.direction[0] = 1
elif x < coords[0]:
self.direction[0] = -1
else:
self.direction[1] *= -1
for game_object in game_objects:
if isinstance(game_object, Brick):
game_object.hit()
class Paddle(GameObject):
def __init__(self, canvas, x, y):
self.width = 80
self.height = 10
self.ball = None
item = canvas.create_rectangle(x - self.width / 2,
y - self.height / 2,
x + self.width / 2,
y + self.height / 2,
fill='#FFB643')
super(Paddle, self).__init__(canvas, item)
def set_ball(self, ball):
self.ball = ball
def move(self, offset):
coords = self.get_position()
width = self.canvas.winfo_width()
if coords[0] + offset >= 0 and coords[2] + offset <= width:
super(Paddle, self).move(offset, 0)
if self.ball is not None:
self.ball.move(offset, 0)
class Brick(GameObject):
COLORS = {1: '#4535AA', 2: '#ED639E', 3: '#8FE1A2'}
def __init__(self, canvas, x, y, hits):
self.width = 75
self.height = 20
self.hits = hits
color = Brick.COLORS[hits]
item = canvas.create_rectangle(x - self.width / 2,
y - self.height / 2,
x + self.width / 2,
y + self.height / 2,
fill=color, tags='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.COLORS[self.hits])
class Game(tk.Frame):
def __init__(self, master):
super(Game, self).__init__(master)
self.lives = 3
self.width = 610
self.height = 400
self.canvas = tk.Canvas(self, bg='#D6D1F5',
width=self.width,
height=self.height, )
self.canvas.pack()
self.pack()
self.items = {}
self.ball = None
self.paddle = Paddle(self.canvas, self.width / 2, 326)
self.items[self.paddle.item] = self.paddle
# adding brick with different hit capacities - 3,2 and 1
for x in range(5, self.width - 5, 75):
self.add_brick(x + 37.5, 50, 3)
self.add_brick(x + 37.5, 70, 2)
self.add_brick(x + 37.5, 90, 1)
self.hud = None
self.setup_game()
self.canvas.focus_set()
self.canvas.bind('<Left>',
lambda _: self.paddle.move(-10))
self.canvas.bind('<Right>',
lambda _: self.paddle.move(10))
def setup_game(self):
self.add_ball()
self.update_lives_text()
self.text = self.draw_text(300, 200,
'Press Space to start')
self.canvas.bind('<space>', lambda _: self.start_game())
def add_ball(self):
if self.ball is not None:
self.ball.delete()
paddle_coords = self.paddle.get_position()
x = (paddle_coords[0] + paddle_coords[2]) * 0.5
self.ball = Ball(self.canvas, x, 310)
self.paddle.set_ball(self.ball)
def add_brick(self, x, y, hits):
brick = Brick(self.canvas, x, y, hits)
self.items[brick.item] = brick
def draw_text(self, x, y, text, size='40'):
font = ('Forte', size)
return self.canvas.create_text(x, y, text=text,
font=font)
def update_lives_text(self):
text = 'Lives: %s' % self.lives
if self.hud is None:
self.hud = self.draw_text(50, 20, text, 15)
else:
self.canvas.itemconfig(self.hud, text=text)
def start_game(self):
self.canvas.unbind('<space>')
self.canvas.delete(self.text)
self.paddle.ball = None
self.game_loop()
def game_loop(self):
self.check_collisions()
num_bricks = len(self.canvas.find_withtag('brick'))
if num_bricks == 0:
self.ball.speed = None
self.draw_text(300, 200, 'You win! You the Breaker of Bricks.')
elif self.ball.get_position()[3] >= self.height:
self.ball.speed = None
self.lives -= 1
if self.lives < 0:
self.draw_text(300, 200, 'You Lose! Game Over!')
else:
self.after(1000, self.setup_game)
else:
self.ball.update()
self.after(50, self.game_loop)
def check_collisions(self):
ball_coords = self.ball.get_position()
items = self.canvas.find_overlapping(*ball_coords)
objects = [self.items[x] for x in items if x in self.items]
self.ball.collide(objects)
game.mainloop()
root = tk.Tk()
root.title('Jeu')
game = Game(root)
btn1= tk.Button(root, text='Click me', bd= '5',command=new_window)
Is there a way to create the game without those functions or replacing them with simpler functions if it's possible?
As a proof of concept below a much simpler code of the game for beginners rewritten to get rid of classes as an example that it is possible to write the game without them. You can compare the rewritten code with the original code (link is given in a comment at the beginning of code) to see how it can be done and then rewrite yourself a more complex code:
# https://codingshiksha.com/python/python-3-tkinter-2d-brick-breaker-breakout-game-in-gui-desktop-app-full-project-for-beginners/
from tkinter import Tk, Canvas
import random
import time
tk = Tk()
tk.title("Game")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas_height = 400
canvas_width = 500
canvas = Canvas(tk, width=canvas_width, height=canvas_height, bd=0, highlightthickness=0)
canvas.pack()
tk.update()
ball_id = canvas.create_oval(10, 10, 25, 25, fill='red')
canvas.move(ball_id, 245, 100)
starts = [-3, -2, -1, 1, 2, 3]
random.shuffle(starts)
ball_x = starts[0]
ball_y = -3
paddle_id = canvas.create_rectangle(0, 0, 100, 10, fill='blue')
canvas.move(paddle_id, 200, 300)
paddle_x = 0
def draw_ball():
global ball_x, ball_y
canvas.move(ball_id, ball_x, ball_y)
pos = canvas.coords(ball_id)
if pos[1] <= 0:
ball_y = 3
if pos[3] >= canvas_height:
ball_y = -3
if hit_paddle(pos) == True:
ball_y = -3
if pos[0] <= 0:
ball_x = 3
if pos[2] >= canvas_width:
ball_x = -3
def hit_paddle(pos):
paddle_pos = canvas.coords(paddle_id)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
return True
return False
def turn_left(evt):
global paddle_x
paddle_x = -2
def turn_right(evt):
global paddle_x
paddle_x = 2
def draw_paddle():
global paddle_x
canvas.move(paddle_id, paddle_x, 0)
pos = canvas.coords(paddle_id)
if pos[0] <= 0:
paddle_x = 0
elif pos[2] >= canvas_width:
paddle_x = 0
canvas.bind_all('<KeyPress-Left>' , turn_left)
canvas.bind_all('<KeyPress-Right>', turn_right)
while True:
draw_ball()
draw_paddle()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
By the way: not always usage of classes makes sense if there is a simpler and sometimes even more intuitive way of achieving the same result.
The init function is a part of a class that is run every time you create an instance of that class. Self makes the variable an attribute to the class, or that it can be accessed in other parts of your code by, for example ball = Ball() print(ball.radius). There is more information here at the documentation: https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces . If you are using object-oriented programming, there aren't any alternatives to self and init. The only way not to use them would be to not use classes in your code.
The self.radius part of the code is creating a variable representing the size of the ball. This link describes how the different points you set creates the shape of the oval: https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/create_oval.html. The short answer is that self.radius creates the size by spacing out the two points of the oval.

Move object function has no effect even after calling: Tkinter

So, yeah I'm a beginner to Tkinter Canvas Games and it's being too difficult for me to code than I thought.
Okk, let's come to the chase, below is my code:
import time
from tkinter import *
from numpy import random
class Paddle:
def __init__(self, Main_Frame):
Main_Frame.title("Paddle")
Main_Frame.geometry("300x300+630+150")
self.Random_X = random.randint(270)
self.Random_Y = random.randint(120)
self.x = 3
self.y = 3
self.Y_Position = 288
self.Can = Canvas(Main_Frame, height = 300, width = 300)
self.Can.pack()
self.paddle = self.Can.create_rectangle(0, 288, 90, 300, fill = "Aqua", outline = "Aqua")
self.ball = self.Can.create_oval(self.Random_X, self.Random_Y, self.Random_X + 20, self.Random_Y + 20, outline = "Red", fill = "Red")
self.Can.bind("<Motion>", self.Move_Paddle)
self.Move_Ball()
def Move_Ball(self):
Ball_x1, Ball_y1, Ball_x2, Ball_y2 = self.Can.coords(self.ball)
if Ball_x2 > 300:
self.x = -self.x
if Ball_y2 > 300:
self.y = -self.y
if Ball_x1 < 0:
self.x = -self.x
if Ball_y2 < 10:
self.y = -self.y
self.Can.moveto(self.ball, self.x, self.y)
Window.after(1, self.Move_Ball)
def Move_Paddle(self, event):
self.X_Position = event.x
self.Can.moveto(self.paddle, self.X_Position, self.Y_Position)
Window = Tk()
Class = Paddle(Window)
Window.mainloop()
So, my problem here is that even after calling the Move_Ball() function, it had no effect on the ball, (okk there is no error occurring though) when I tried to call the function under Move_Paddle() function (before adding the Window.after(1, self.Move_Ball) line), it worked well when I moved the mouse around the Canvas, well, I want it to automatically activate when the Paddle class is called.
I was trying to check the problem in the code by placing the function call in Move_Paddel() (with the Window.after(1, self.Move_Ball) line as in the code), it increased the trouble and insanely increased the speed of the ball.
If anyone could help me with these couple of problems, it would be highly appreciated.
Thanks in advance!
Use move() instead of moveto() method. move() method moves each of the items given by tagOrId in the canvas coordinate space by adding X amount to the x-coordinate of each point associated with the item and y amount to the y-coordinate of each point associated with the item.
Then you may increase the delay in the after() method.
Here is the working code:
import time
from tkinter import *
from numpy import random
class Paddle:
def __init__(self, Main_Frame):
Main_Frame.title("Paddle")
Main_Frame.geometry("300x300+630+150")
self.Random_X = random.randint(270)
self.Random_Y = random.randint(120)
self.x = 3
self.y = 3
self.Y_Position = 288
self.Can = Canvas(Main_Frame, height = 300, width = 300)
self.Can.pack()
self.paddle = self.Can.create_rectangle(0, 288, 90, 300, fill = "Aqua", outline = "Aqua")
self.ball = self.Can.create_oval(self.Random_X, self.Random_Y, self.Random_X + 20, self.Random_Y + 20, outline = "Red", fill = "Red")
self.Can.bind("<Motion>", self.Move_Paddle)
self.Move_Ball()
def Move_Ball(self):
Ball_x1, Ball_y1, Ball_x2, Ball_y2 = self.Can.coords(self.ball)
if Ball_x2 > 300:
self.x = -self.x
if Ball_y2 > 300:
self.y = -self.y
if Ball_x1 < 0:
self.x = -self.x
if Ball_y2 < 10:
self.y = -self.y
self.Can.move(self.ball, self.x, self.y)
Window.after(50 ,self.Move_Ball)
def Move_Paddle(self, event):
self.X_Position = event.x
self.Can.moveto(self.paddle, self.X_Position, self.Y_Position)
Window = Tk()
Class = Paddle(Window)
Window.mainloop()
I rewrote your code and now I think it works as you wished. Red ball slowly goes down:
import time
from tkinter import *
from numpy import random
class Paddle:
def __init__(self, main_frame):
self.root = main_frame
random.seed(int(time.time()))
self.x = random.randint(270)
self.y = random.randint(120)
self.Y_Position = 288
self.Can = Canvas(self.root, height=300, width=300)
self.Can.pack()
self.paddle = self.Can.create_rectangle(0, 288, 90, 300, fill="Aqua", outline="Aqua")
self.ball = self.Can.create_oval(self.x, self.y, self.x + 20, self.y + 20, outline="Red", fill="Red")
self.Can.bind("<Motion>", self.move_paddle)
self.move_ball()
def move_ball(self):
Ball_x1, Ball_y1, Ball_x2, Ball_y2 = self.Can.coords(self.ball)
# if Ball_x2 > 300:
# self.x = -self.x
# if Ball_y2 > 300:
# self.y = -self.y
# if Ball_x2 < 0:
# self.x = 300
if Ball_y2 > 300:
self.y = 0
self.y += 0.1
self.Can.moveto(self.ball, self.x, self.y)
self.root.after(1, self.move_ball)
def move_paddle(self, event):
self.X_Position = event.x
self.Can.moveto(self.paddle, self.X_Position, self.Y_Position)
root = Tk()
root.title("Paddle")
root.geometry("300x300+630+150")
Class = Paddle(root)
root.mainloop()
And please read about PEP8
You should use move() instead of moveto() inside Move_Ball() and after(1, ...) is too frequent so the ball will be moved very fast. Try after(50, ...) instead:
def Move_Ball(self):
...
self.Can.move(self.ball, self.x, self.y)
Window.after(50, self.Move_Ball)

Cannot delete tkinter object on canvas

I have created a class object Dot(), a function update() that updates its position and then generated many instances of it on canvas, adding them to a list. I run a loop that keeps updating the position of the dots, and this works fine, but I also want to delete one instantiation of Dot() at each run of the loop.
I've tried many ways but with no success. By using canvas.delete() function I only "freeze" the instantiation, but it remains on screen. How can I fix this?
import numpy as np
import random
import time
from tkinter import *
#create Canvas#
screen = Tk()
hei = 600
wid = 600
canvas = Canvas(screen,width=wid,height=hei)
canvas.pack()
colors = ["red", "green", "blue"]
class Dot:
def __init__(self):
self.l = random.randrange(100,200)
self.t = random.randrange(100,200)
self.l2= self.l-10
self.t2 = self.t-10
color = random.choice(colors)
self.shape = canvas.create_oval(self.l, self.t, self.l2, self.t2, fill=color)
self.speedx = random.randrange(1,3)
self.speedy = random.randrange(1,3)
def update(self):
canvas.move(self.shape, self.speedx, self.speedy)
pos = canvas.coords(self.shape)
jitter = random.randrange(0,200)
if pos[2] >= wid+jitter or pos[0] <= -jitter:
self.speedx *= -1
if pos[3] >= hei+jitter or pos[1] <= -jitter:
self.speedy *= -1
dots = []
for i in range(100):
dots.append(Dot())
while True:
del dots[-1]
canvas.delete(dots[-1])
for dot in dots:
dot.update()
screen.update()
time.sleep(0.005)
screen.mainloop()
The delete method takes the identifier of a canvas item, not the canvas item itself.
Additionally, you should probably do the deletion in a timeout function, otherwise, the GUI won't function properly.
Try this code:
import random
from tkinter import *
screen = Tk()
hei = 600
wid = 600
canvas = Canvas(screen, width=wid, height=hei)
canvas.pack()
colors = ["red", "green", "blue"]
class Dot:
def __init__(self):
self.l = random.randrange(100, 200)
self.t = random.randrange(100, 200)
self.l2 = self.l-10
self.t2 = self.t-10
color = random.choice(colors)
self.shape = canvas.create_oval(self.l, self.t, self.l2, self.t2, fill=color)
self.speedx = random.randrange(1, 3)
self.speedy = random.randrange(1, 3)
def update(self):
canvas.move(self.shape, self.speedx, self.speedy)
pos = canvas.coords(self.shape)
jitter = random.randrange(0, 200)
if pos[2] >= wid+jitter or pos[0] <= -jitter:
self.speedx *= -1
if pos[3] >= hei+jitter or pos[1] <= -jitter:
self.speedy *= -1
dots = []
for i in range(100):
dots.append(Dot())
def timeout():
if dots:
canvas.delete(dots[-1].shape)
del dots[-1]
for dot in dots:
dot.update()
screen.after(5, timeout)
screen.after(5, timeout)
screen.mainloop()
(Tested with Python 3)

Moving a Tkinter widget to a specific coordinates and changing the text of a text widget

I'm trying to make a game like snake, where when you catch/eat the apple and the apple moves to a different spot in tkinter.
But I want to place the "apple", or in this case, a blue triangle, to a random place on the canvas,but the only command I can find is canvas.move(), which moves the widget a certain number of pixels in any direction. This can't fulfill what I need(I think, maybe there is a way around it?). Is there a way to place the blue triangle randomly on the canvas?
from Tkinter import *
import random
import time
class Ball:
def __init__(self, canvas,square):
self.square = square
self.canvas = canvas
self.id = canvas.create_oval(10,10,25,25,fill='red')
self.canvas.move(self.id,245,100)
self.text = self.canvas.create_text(10, 10, text='GAME OVER', font=('Courier', 80))
self.canvas.move(self.text, -7000, -7000)
starts = [-3,-2,-1,1,2,3]
self.x = random.choice(starts)
self.y = -30
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id)
if pos[1] <= 0:
self.y = 4
if pos[3] >= self.canvas.winfo_height():
self.y = -4
if self.hit_square(pos) == True:
self.canvas.move(self.text,245,100)
time.sleep(2)
tk.destroy()
if pos[0] <= 0:
self.x = 4
if pos[2] >= self.canvas.winfo_width():
self.x = -4
def hit_square(self, pos):
square_pos = self.canvas.coords(self.square.id)
if pos[2] >= square_pos[0] and pos[0] <= square_pos[2]:
if pos[3] >= square_pos[1] and pos[3] <= square_pos[3]:
return True
return False
def stay(self):
self.x = 0
self.y = 0
class Square:
def __init__(self,canvas):
self.canvas = canvas
self.id = canvas.create_rectangle(15, 15, 30, 30,fill='green')
self.x = 0
self.y = 0
self.canvas.move(self.id, 200, 250)
self.canvas.bind_all('<KeyPress-Left>',self.left)
self.canvas.bind_all('<KeyPress-Right>', self.right)
self.canvas.bind_all('<KeyPress-Up>', self.up)
self.canvas.bind_all('<KeyPress-Down>', self.down)
def draw(self):
self.canvas.move(self.id,self.x,self.y)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.x = 0
elif pos[2] >= self.canvas.winfo_width():
self.x = 0
if pos[1] <= 0:
self.y = 0
elif pos[3] >= self.canvas.winfo_height():
self.y = 0
def left(self, evt):
self.x = -2
self.y = 0
def right(self, evt):
self.x = 2
self.y = 0
def up(self, evt):
self.y = -2
self.x = 0
def down(self, evt):
self.y = 2
self.x = 0
class Triangle:
def __init__(self,canvas,square):
self.canvas = canvas
self.square = square
self.id = self.canvas.create_polygon(26.5,10,20,25,35,25,fill='blue')
self.canvas.move(self.id,random.randint(10,450),random.randint(10,380))
self.score = 0
def draw_score(self):
self.score_show = self.canvas.create_text(450, 20, text='score:' + str(self.score), font=('Arial', 20))
def hit_square(self):
pos = self.canvas.coords(self.id)
square_pos = self.canvas.coords(self.square.id)
if pos[2] >= square_pos[0] and pos[0] <= square_pos[2]:
if pos[3] >= square_pos[1] and pos[3] <= square_pos[3]:
self.teleport(pos)
def teleport(self, pos):
x = self.canvas.winfo_width()-pos[0]-10
y = self.canvas.winfo_height() - pos[1]-10
self.score += 1
self.canvas.move(self.id,)
tk = Tk()
tk.title("Run from the ball!")
tk.resizable(0,0)
tk.wm_attributes('-topmost',1)
canvas = Canvas(tk, width=500,height=400,bd=0,highlightthickness=0)
canvas.pack()
tk.update()
square = Square(canvas)
ball = Ball(canvas, square)
ball1 = Ball(canvas, square)
ball2 = Ball(canvas, square)
ball3 = Ball(canvas, square)
ball4 = Ball(canvas, square)
triangle = Triangle(canvas, square)
x = 0
while x < float('inf'):
ball.draw()
triangle.draw_score()
triangle.hit_square()
if x >= 10:
ball1.draw()
if x >= 20:
ball2.draw()
if x >= 30:
ball3.draw()
if x >= 40:
ball4.draw()
square.draw()
tk.update_idletasks()
tk.update()
time.sleep(0.01)
x += 0.01
Yes, I know that the score function is messed up, and that the one overlaps the zero. Could you guys help me with that too?
Is there a way to place the blue triangle randomly on the canvas?
Yes. the coords method can get you the current coordinates, but it also lets you change the coordinates to whatever you want.
self.canvas.coords(self.id, 36.5, 20, 30, 35, 45, 35)

Categories

Resources