如何处理与坐标的碰撞? (在 python 中)

How to handle collisions with coordinates? (in python)

我正在编写一个 Flappy Bird,我快完成了,但我只错过了一件事:鸟和管道之间的碰撞......我设法确保如果鸟撞到地面或从屏幕上消失,游戏结束(感谢函数 fin() )。如果鸟碰到管道,我也希望游戏结束,但我做不到,要求这样的人通常使用 Pygame :(.

提前感谢您的帮助,希望解决方案很简单,但我只是没有找到它。

我试图单独管理碰撞(我们可以在我的程序中看到相应的部分)但是小鸟随机停止...

这是游戏的图片(下载图片zip文件很火link)!

Here are the pictures !

from tkinter import *
import random
from random import randint

def sauter(event):
    canvas.move(image_oiseau, 0, -10*DY)

def deplacement():
    global mouvement
    global tuyx,tuyx2,h,H,oisx,oisy,solx,sol2x,score

    x0, y0, x1, y1 = canvas.bbox(image_oiseau)
    if y1 < 416 :
        canvas.move(image_oiseau, 0, DY)
    else :
        fin()

    if y1<=-5:
        fin()

#Here are the parts supposed to handle collisions ...
    if y1 >= h :
        fin()

    if y1 >= H :
        fin()

    if y0<=h-379.8:
        fin()

    if y0<=h-379.8:
        fin()
#That's the end of the parts supposed to handle collsions...

    canvas.coords(image_sol,solx,512)  
    if solx >= -144:
        solx=solx-5
    else:
        solx=144

    canvas.coords(image_sol2,sol2x,512)
    if sol2x >= 144:
        sol2x=sol2x-5
    else:
        sol2x=432

    canvas.coords(image_tuyau_haut,tuyx,h)
    canvas.coords(image_tuyau_bas,tuyx,h-379.8)
    if tuyx>=-28:
        tuyx=tuyx-5
    else:
        tuyx=316
        h=randint(272,523)
        score+=1

    canvas.coords(image_tuyau_haut2,tuyx2,H)
    canvas.coords(image_tuyau_bas2,tuyx2,H-379.8)
    if tuyx2>=-28:
        tuyx2=tuyx2-5
    else:
        tuyx2=316
        H=randint(272,523)
        score+=1

    lscore.config(text=str(score))    
    mouvement =canvas.after(40,deplacement)  

def debut():
    pause=1
    if pause==1:
        M.destroy()
        deplacement()
        canvas.bind("<space>",sauter)  

def fin():
    pause=0
    if pause==0:
        canvas.after_cancel(mouvement)
        canvas.unbind("<space>",sauter)

def rejouer():
    global tuyx,tuyx2,oisx,oisy,solx,sol2x,score
    tuyx=316
    tuyx2=488
    oisx=67
    oisy=244
    solx=144
    sol2x=432
    score=0



LARGEUR = 286
HAUTEUR = 510
DY = 5
tuyx=316
tuyx2=488 
h=randint(272,523)
H=randint(272,523)
oisx=67
oisy=244
solx=144
sol2x=432
score=0
mouvement=None


fenetre = Tk()
canvas = Canvas(fenetre, width=LARGEUR, height=HAUTEUR)

fond = PhotoImage(file="background-day.png")
fond2 = PhotoImage(file="background-night.png")
fond=[fond,fond2]
F= random.choice(fond)
canvas.create_image(144,256, anchor=CENTER,image=F)

tuyau_haut = PhotoImage(file="tuyau_vers_le_haut.png")
image_tuyau_haut = canvas.create_image(tuyx,h,anchor=CENTER,image=tuyau_haut)
image_tuyau_haut2 = canvas.create_image(tuyx2,H,anchor=CENTER,image=tuyau_haut)

tuyau_bas = PhotoImage(file="tuyau_vers_le_bas.png")
image_tuyau_bas = canvas.create_image(tuyx,h,anchor=CENTER,image=tuyau_bas)
image_tuyau_bas2 = canvas.create_image(tuyx2,H,anchor=CENTER,image=tuyau_bas)

sol = PhotoImage(file="sol-day.png")
image_sol = canvas.create_image(144,512, anchor=S,image=sol)
image_sol2 = canvas.create_image(432,512, anchor=S,image=sol)

oiseau = PhotoImage(file="yellowbird-midflap.png")
oiseau2 = PhotoImage(file="bluebird-midflap.png")
oiseau3 = PhotoImage(file="redbird-midflap.png")
oiseau=[oiseau,oiseau2,oiseau3]
O=random.choice(oiseau)
image_oiseau=canvas.create_image(oisx,oisy, anchor=W,image=O) 

lscore=Label(fenetre,text='0')
lscore.pack()

menu_debut=PhotoImage(file="menu_jeu.png")
M=Button(fenetre,image=menu_debut,relief=FLAT,command=debut)
Menu_w = canvas.create_window(144,256,window=M)

canvas.pack()
canvas.focus_set()

fenetre.mainloop() 

你有两种方法:

1- 确定要检查哪些坐标与鸟类周界、安全区、顶部和底部 y、管道宽度、管道移动和其他障碍物等的碰撞。所有这些都很有趣,可以实现和检查,但有点乏味且容易出错。

2- 利用 tkinter canvas 的强大功能,并使用方法 find_overlapping(x0, y0, x1, y1) 即 returns 所有项的元组与给定的矩形重叠,或者完全被它包围,并使用它来确定是否发生了碰撞,可能使用 tag 来标记障碍物。

我的建议是使用find_overlapping

可能是这样的(伪代码)

obstacles = canvas.find_withtag('obstacle')
for item in canvas.find_overlapping(canvas.coords(bird)):
    if item in obstacles:
        bird.is_dead()