[Python] Why is this method of tkinter collision not working?

Discussão em 'Python' iniciado por Stack, Maio 5, 2025.

  1. Stack

    Stack Membro Participativo

    What I am trying to do is to make a Tkinter game that functions similar to Minecraft, but the left and right collision is not working. For playtesting purposes, I want to print 'Player collided with sprite {sprite number}' whenever the player has collided with the sprite, and even though I am going straight into the blocks, my code doesn't know that the player has collided. I can't seem to find anything wrong with the method - it's a classic method that I first learnt and it has always worked for other games that I have made on Tkinter.

    Here is my code:

    from tkinter import *
    import random
    import time
    tk = Tk()
    tk.title('Current world and position')
    tk.wm_attributes('-fullscreen', 1)
    tk.resizable(0, 0)
    canvas = Canvas(tk, width=1920, height=1200, bd=0, highlightthickness=0, bg='lightblue')
    canvas.pack()
    def within_x(sp1: list, sp2: list):
    if (sp1[0] > sp2[0] and sp1[0] < sp2[2]) or (sp1[2] > sp2[0] and sp1[2] < sp2[2]) or (sp2[0] > sp1[0] and sp2[0] < sp1[0]) or (sp2[2] > sp1[0] and sp2[2] < sp1[2]):
    return True
    else:
    return False
    def within_y(sp1: list, sp2: list):
    if (sp1[1] > sp2[1] and sp1[1] < sp2[3]) or (sp1[3] > sp2[1] and sp1[3] < sp2[3]) or (sp2[1] > sp1[1] and sp2[1] < sp1[1]) or (sp2[3] > sp1[1] and sp2[3] < sp1[3]):
    return True
    else:
    return False
    class Player():
    def __init__(self, canvas, pos: list, items: list):
    self.canvas = canvas
    self.pos = pos
    self.id = self.canvas.create_rectangle(self.pos[0] * 10 + 3, 1200 - ((self.pos[1]) * 10), self.pos[0] * 10 + 8, 1200 - ((self.pos[1]) * 10) + 5, fill='blue')
    self.items = items
    self.dir = 1
    self.coords = self.canvas.coords(self.id)
    self.canvas.bind_all('<KeyPress-a>', self.move_left)
    self.canvas.bind_all('<KeyPress-d>', self.move_right)
    def animate(self):
    self.coords = self.canvas.coords(self.id)
    def move_right(self, evt):
    self.canvas.move(self.id, 3, 0)
    self.pos[0] = int(self.coords[2]//10)
    def move_left(self, evt):
    self.canvas.move(self.id, -3, 0)
    self.pos[0] = int(self.coords[2]//10)
    def generate_world():
    worldlist = []
    spritelist = []
    height = 3
    for x in range(700):
    if x == 0:
    height = 0
    elif height - 4 > -1:
    height = random.randint(height-4, height+3)
    else:
    height = random.randint(0, height+4)
    worldlist.append(height)
    for y in range(height):
    spritelist.append(canvas.create_rectangle(x * 10, 1200 - (y * 10), (x + 1) * 10, 1200 - ((y + 1) * 10), fill='brown', outline='brown'))
    canvas.create_rectangle(x * 10, 1198 - (height * 10), (x + 1) * 10, 1198 - (height * 10) + 2, fill='green', outline='green')
    return worldlist, spritelist
    class World():
    def __init__(self, canvas):
    self.canvas = canvas
    self.world, self.sprites = generate_world()
    def animate(self):
    for sprite in self.sprites:
    sp_coords = self.canvas.coords(sprite)
    if self.coll_left(sp_coords):
    print(f'Player collided with sprite {sprite}')
    if self.coll_right(sp_coords):
    print(f'Player collided with sprite {sprite}')
    def coll_left(self, sp_coords):
    if within_y(player.coords, sp_coords):
    if player.coords[0] >= sp_coords[0] and player.coords[0] <= sp_coords[2]:
    return True
    return False
    def coll_right(self, sp_coords):
    if within_y(player.coords, sp_coords):
    if player.coords[2] >= sp_coords[0] and player.coords[2] <= sp_coords[2]:
    return True
    return False
    world = World(canvas)
    pxpos = random.randint(0, 128)
    player = Player(canvas, [pxpos, world.world[pxpos] + 1], [])
    running = True
    while running:
    player.animate()
    world.animate()
    tk.update()
    tk.update_idletasks()
    time.sleep(0.01)


    The world generation, block colour, and player movement sideways (I haven't done jumping yet) is working fine, so that's not the problem. It's just the collision detection that's acting strange. I'm pretty sure that it's the within_x and within_y functions that aren't working, so if someone is able to spot the error, can they correct it and give the new code for the functions please?

    Continue reading...

Compartilhe esta Página