如何阻止一个形状进入另一个形状?

How to stop a shape from going into another?

例如,当你扮演马里奥四处走动时,你看到了一个障碍物。我需要做到这一点,这样你就无法通过障碍物。我查了答案,我让它检测到它撞到了什么东西,我就是不能让它停下来。 c.find_overlapping() 函数为我做了所有这些。

这是我的代码:

    from tkinter import *
except ImportError:
    from Tkinter import *
shiva = Tk()
shiva.title("Super Mario Python Limited")
shiva.geometry("1000x2000")
c = Canvas(shiva, height = 2000, width = 1000, bg = "#a7f2e6", highlightthickness = 0)
c.pack()
topyellow = c.create_rectangle(20, 30, 200, 300, fill = "yellow")
mushroom = c.create_rectangle(500, 600, 600, 700, fill = "orange")
mario = c.create_rectangle(20, 600, 60, 650, fill = "red")


prevkey = ""
def move(event):
    global prevkey
    key = event.keysym
    if key == "Up":
        c.move(mario, 0, -10)
        prevkey == "Up"
    elif key == "Down":
        c.move(mario, 0, 10)
        prevkey = "Down"
    elif key == "Left":
        c.move(mario, -10, 0)
        prevkey = "Left"
    elif key == "Right":
        c.move(mario, 10, 0)
        prevkey = "Right"
c.bind_all("<Key>", move)
prevkey = ""
def make_collide(moveshape, othershape):
    global prevkey
    if c.find_overlapping(c.coords(othershape)[0], c.coords(othershape)[1], c.coords(othershape)[2], c.coords(othershape)[3]) == (int(othershape), int(moveshape)):
        def move(event):
            global prevkey
            key = event.keysym
            if key == str(prevkey):
                c.move(mario, 0, 0)
            else:
                if key == "Up":
                    c.move(moveshape, 0, -10)
                elif key == "Down":
                    c.move(moveshape, 0, 10)
                elif key == "Left":
                    c.move(moveshape, -10, 0)
                elif key == "Right":
                    c.move(moveshape, 10, 0)
        c.bind_all("<Key>", move)
    else:
        def move(event):
            global prevkey
            key = event.keysym
            if key == "Up":
                c.move(moveshape, 0, -10)
                prevkey = "Up"
            elif key == "Down":
                c.move(moveshape, 0, 10)
                prevkey = "Down"
            elif key == "Left":
                c.move(moveshape, -10, 0)
                prevkey = "Left"
            elif key == "Right":
                c.move(moveshape, 10, 0)
                prevkey = "Right"
        c.bind_all("<Key>", move)
def detect_touch1():
    make_collide(mario, topyellow)
    make_collide(mario, mushroom)
    shiva.after(20, detect_touch1)
detect_touch1()

我如何做到这一点,当马里奥撞到一块石头时,他不只是穿过它?

提前致谢!!!

在这里你可以看到一个方法,它有点乱,但我相信你能理解它是如何工作的。查看所有 canvas 方法,了解您可以轻松做什么 (canvas)

from tkinter import *

shiva = Tk()
shiva.title("Super Mario Python Limited")
shiva.geometry("1000x2000")
c = Canvas(shiva, height = 2000, width = 1000, bg = "#a7f2e6", highlightthickness = 0)
c.pack()
topyellow = c.create_rectangle(20, 30, 200, 300, fill = "yellow")
mushroom = c.create_rectangle(500, 600, 600, 700, fill = "orange")
mario = c.create_rectangle(20, 600, 60, 650, fill = "red")


# initialize the bounding box of the player
surplus = 10
x, y, x1, y1 = c.coords(mario)
x_s, y_s, x1_s, y1_s = x - surplus, y - surplus, x1 +surplus, y1 +surplus

top_area = x, y_s, x1, y
right_area = x1, y, x1_s, y1
bottom_area = x, y1, x1, y1_s
left_area = x - surplus, y, x, y1

t = c.create_rectangle(*top_area, outline='red', fill="")
r = c.create_rectangle(*right_area, outline='red', fill="")
b = c.create_rectangle(*bottom_area, outline='red', fill="")
l = c.create_rectangle(*left_area, outline='red', fill="")

# add the rectangles that have the 'collision detector' functionality to a list for remove them if they are the dected as object with which the player collided
position_rectangles = [t, r, b, l]


prevkey = ""
def move(event):
    global prevkey
    key = event.keysym
    surplus = 10

    # get the new bounding boxs positions
    top_overl = list(c.find_overlapping(*c.coords(t)))
    right_overl = list(c.find_overlapping(*c.coords(r)))
    bottom_overl = list(c.find_overlapping(*c.coords(b)))
    left_overl = list(c.find_overlapping(*c.coords(l)))

    # remove from the detected object the player and the boxes
    for elem in position_rectangles + [mario]:
        if elem in top_overl:
            top_overl.remove(elem)
        if elem in right_overl:
            right_overl.remove(elem)
        if elem in bottom_overl:
            bottom_overl.remove(elem)
        if elem in left_overl:
            left_overl.remove(elem)

    # check if the player can move
    if key == "Up" and len(top_overl) == 0:
        for box in position_rectangles: # move the bounding boxs
            c.move(box, 0, -surplus)
        c.move(mario, 0, -surplus)
        prevkey == "Up"
    elif key == "Down"  and len(bottom_overl) == 0:
        for box in position_rectangles: # move the bounding boxs
            c.move(box, 0, surplus)
        c.move(mario, 0, surplus)
        prevkey = "Down"
    elif key == "Left"  and len(left_overl) == 0:
        for box in position_rectangles: # move the bounding boxs
            c.move(box, -surplus, 0)
        c.move(mario, -surplus, 0)
        prevkey = "Left"
    elif key == "Right"  and len(right_overl) == 0:
        for box in position_rectangles: # move the bounding boxs
            c.move(box, surplus, 0)
        c.move(mario, surplus, 0)
        prevkey = "Right"


c.bind_all("<Key>", move)
prevkey = ""

def make_collide(moveshape, othershape):
    global prevkey
    if c.find_overlapping(c.coords(othershape)[0], c.coords(othershape)[1], c.coords(othershape)[2], c.coords(othershape)[3]) == (int(othershape), int(moveshape)):
        c.bind_all("<Key>", move)
    else:
        c.bind_all("<Key>", move)
def detect_touch1():
    make_collide(mario, topyellow)
    make_collide(mario, mushroom)
    shiva.after(20, detect_touch1)
detect_touch1()
shiva.mainloop()

但是当要碰撞的项目很多时,这个方法可能需要一些时间才能起作用,试试看它的行为