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

Python 如何阻止一个形状进入另一个形状?,python,python-3.x,tkinter,collision-detection,tkinter-canvas,Python,Python 3.x,Tkinter,Collision Detection,Tkinter Canvas,例如,当你像马里奥一样四处走动时,你会看到一个障碍物。我要让你通过这个障碍。我已经找到了答案,我让它检测到它撞到了什么东西上,我就是无法让它停下来。c.find_overlapping()函数为我完成了所有这些 这是我的密码: from tkinter import * except ImportError: from Tkinter import * shiva = Tk() shiva.title("Super Mario Python Limited") shiva.geo

例如,当你像马里奥一样四处走动时,你会看到一个障碍物。我要让你通过这个障碍。我已经找到了答案,我让它检测到它撞到了什么东西上,我就是无法让它停下来。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()
从tkinter导入*
除恐怖外:
从Tkinter进口*
shiva=Tk()
shiva.title(“超级马里奥蟒蛇有限公司”)
希瓦几何(“1000x2000”)
c=帆布(湿婆,高度=2000,宽度=1000,背景=“#a7f2e6”,高光厚度=0)
c、 包()
topyellow=c.创建矩形(20、30、200、300,fill=“黄色”)
蘑菇状=c.创建矩形(500600600700,fill=“橙色”)
mario=c.创建一个矩形(20600,60650,fill=“红色”)
prevkey=“”
def移动(事件):
全局前置键
key=event.keysym
如果键==“向上”:
c、 移动(马里奥,0,-10)
prevkey==“向上”
elif键==“向下”:
c、 移动(马里奥,0,10)
prevkey=“向下”
elif键==“左”:
c、 移动(马里奥,-10,0)
prevkey=“左”
elif键==“右”:
c、 移动(马里奥,10,0)
prevkey=“右”
c、 全部绑定(“,移动)
prevkey=“”
def make_collide(移动形状、其他形状):
全局前置键
如果c.find_重叠(c.coords(othershape)[0],c.coords(othershape)[1],c.coords(othershape)[2],c.coords(othershape)[3])==(int(othershape),int(moveshape)):
def移动(事件):
全局前置键
key=event.keysym
如果key==str(prevkey):
c、 移动(马里奥,0,0)
其他:
如果键==“向上”:
c、 移动(移动形状,0,-10)
elif键==“向下”:
c、 移动(移动形状,0,10)
elif键==“左”:
c、 移动(移动形状,-10,0)
elif键==“右”:
c、 移动(移动形状,10,0)
c、 全部绑定(“,移动)
其他:
def移动(事件):
全局前置键
key=event.keysym
如果键==“向上”:
c、 移动(移动形状,0,-10)
prevkey=“向上”
elif键==“向下”:
c、 移动(移动形状,0,10)
prevkey=“向下”
elif键==“左”:
c、 移动(移动形状,-10,0)
prevkey=“左”
elif键==“右”:
c、 移动(移动形状,10,0)
prevkey=“右”
c、 全部绑定(“,移动)
def detect_touch1():
使碰撞(马里奥,黄色)
使碰撞(马里奥,蘑菇)
湿婆。之后(20,探测触摸1)
检测_touch1()
我该怎么做才能让马里奥在碰到石头时,不只是穿过石头


提前感谢

在这里你可以看到一种方法,它有点混乱,但我相信你能理解它是如何工作的。查看所有的
canvas
方法,了解您可以轻松执行的操作

从tkinter导入*
shiva=Tk()
shiva.title(“超级马里奥蟒蛇有限公司”)
希瓦几何(“1000x2000”)
c=帆布(湿婆,高度=2000,宽度=1000,背景=“#a7f2e6”,高光厚度=0)
c、 包()
topyellow=c.创建矩形(20、30、200、300,fill=“黄色”)
蘑菇状=c.创建矩形(500600600700,fill=“橙色”)
mario=c.创建一个矩形(20600,60650,fill=“红色”)
#初始化玩家的边界框
盈余=10
x、 y,x1,y1=c.coords(马里奥)
x_s,y_s,x1_s,y1_s=x-盈余,y-盈余,x1+盈余,y1+盈余
顶部面积=x,y,x1,y
右_面积=x1,y,x1_s,y1
底部面积=x,y1,x1,y1
左_面积=x-剩余,y,x,y1
t=c.创建矩形(*顶部区域,轮廓='红色',填充=)
r=c.创建矩形(*右侧区域,轮廓='红色',填充=)
b=c.创建矩形(*底部区域,轮廓='红色',填充=)
l=c.创建矩形(*左侧区域,轮廓='红色',填充=)
#将具有“碰撞检测器”功能的矩形添加到列表中,如果它们是玩家碰撞的dected as对象,则将其删除
位置矩形=[t,r,b,l]
prevkey=“”
def移动(事件):
全局前置键
key=event.keysym
盈余=10
#获取新的边界框位置
顶部重叠=列表(c.查找重叠(*c.坐标(t)))
右上方=列表(c.查找重叠(*c.坐标(r)))
底部重叠=列表(c.查找重叠(*c.坐标(b)))
左上方=列表(c.查找重叠(*c.坐标(l)))
#从检测到的对象中移除播放器和盒子
对于处于位置的元素\u矩形+[mario]:
如果元素位于顶部,则覆盖:
上盖移除(元素)
如果右上角的元素覆盖:
右上盖移除(元素)
如果底部的元素覆盖:
底部覆盖移除(elem)
如果左上角的元素覆盖:
左上方移除(元素)
#检查玩家是否可以移动
如果键==“向上”且len(顶部上方)=0:
对于处于位置的长方体:#移动边界长方体
c、 移动(框,0,-剩余)
c、 移动(马里奥,0,-剩余)
prevkey==“向上”
elif键==“向下”和len(底部上方)==0:
对于处于位置的长方体:#移动边界长方体
c、 移动(框,0,剩余)
c、 移动(马里奥,0,剩余)
prevkey=“向下”
elif键==“左”和len(左上方)==0:
对于处于位置的长方体:#移动边界长方体
c、 移动(框,-剩余,0)
c、 移动(马里奥,-剩余,0)
prevkey=“左”
elif键==“右”和len(右上方)==0:
对于处于位置的长方体:#移动边界长方体
c、 移动(框,剩余,0)
c、 移动(马里奥,剩余,0)
prevkey=“右”
c、 全部绑定(“,移动)
prevkey=“”
def make_collide(移动形状、其他形状):
全局前置键
如果c.find_重叠(c.coords(othershape)[0],c.coords(othershape)[1],c.coords(othershape)[2],c.coords(othershape)[3])==(int(othershape),int(moveshape)):
c、 全部绑定(“,移动)
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()