Python...Tkinter碰撞

0 投票
2 回答
3686 浏览
提问于 2025-04-18 13:05

你好,我一直在尝试搞清楚如何检测碰撞。目前我已经写了代码,可以在投射物碰到敌人的左下角时检测到碰撞。但我想要的是,当矩形的底部被击中时也能检测到碰撞。

碰撞检测的逻辑是在 move_shot() 这个函数里处理的。

下面是完整的代码

from tkinter import *
# creates window
window = Tk()
size = window.winfo_screenheight()
window.title("This is a window")
# set up geometry using string formatting operator %
window.geometry("%dx%d+%d+%d" % (1000, 1000, 10, 10))
window.update()
# creates canvas
global canvas
canvas = Canvas(window, bg='green')
# pack is a layout manager
canvas.pack(fill=BOTH, expand=1)
canvas.update()
canvas.create_rectangle(0, 1000, 1000, 0, fill="orange", width=10, outline="white", tag="border")

def shooting():
    global loaded_gun

    c = canvas.coords("player")
    canvas.create_line(c[0],c[1] + 20,c[2],c[3],width=5,fill="yellow",tag="shot")
    loaded_gun = 0
    move_shot("shot") # furas


def move_shot(name):

    canvas.move(name,0,-10)
    canvas.update()
    window.after(50, move_shot, "shot") # furas

    global loaded_gun

    ran = len(enemies)

    if loaded_gun == 0:
        for x in range(0,ran):

            shot = canvas.coords(name)
            en = canvas.coords(enemies[x])




            if shot[0] == en[0] and shot[0] <= en[0] + 70:
                if shot[1] <= en[1] + 70:
                    #print(canvas.coords(enemies[x]))
                    canvas.delete(enemies[x])
                    #print(canvas.coords(name))
                    enemies.remove(enemies[x])
                    canvas.delete(name)
                    loaded_gun = 1
                    break





def on_key_press(event):

    global canvas,loaded_gun


    c = canvas.coords("player")

    if event.keysym == 'Left' and c[0] > 0:
        canvas.move("player", -20,0)
    elif event.keysym == 'Right' and c[2] < 1000:
        canvas.move("player", 20, 0)
    elif event.keysym == 'space':
        if loaded_gun == 1:
            shooting()
    elif event.keysym == 'Shift_L':
        loaded_gun = 1
        canvas.delete("shot")

def draw_enemy():
    c = [100,100,170,170]
    inc = 100

    global enemies

    enemies = []

    for x in range(0,8):
        for y in range(0,4):
            enemy = canvas.create_rectangle(c[0] + inc * x,c[1] + inc * y,c[2] + inc * x,c[3] + inc * y,fill="red",tag="enemy")
            enemies.append(enemy)

def move_enemy():
    canvas.move("enemy",0,20)
    window.after(1000, move_enemy) # furas


canvas.create_line(500, 950,500,1000, width=15, fill="red",tag="player")

loaded_gun = 1

draw_enemy()

window.bind_all('<Key>', on_key_press) # furas

move_shot("shot") # furas
move_enemy() # furas

window.mainloop()

2 个回答

1

没关系

我已经搞明白了,我只需要这样做

if shot[0] >= en[0] and shot[0] <= en[0] + 70:
1

看起来检测工作得不错,几乎不用做什么。

我只在子弹离开屏幕时才把它移除。

而且在我再次运行 after() 之前,会检查一下 loaded_gun == 0:。如果你一直运行 after loop,下一发子弹会有两个 after loop,这样它就会快两倍。第三发子弹会快三倍。

我在我修改的地方加了 # furas

from Tkinter import *

# creates window
window = Tk()
size = window.winfo_screenheight()
window.title("This is a window")

# set up geometry using string formatting operator %
window.geometry("%dx%d+%d+%d" % (1000, 1000, 10, 10))
window.update()

# creates canvas
canvas = Canvas(window, bg='green')

# pack is a layout manager
canvas.pack(fill=BOTH, expand=1)
canvas.update()
canvas.create_rectangle(0, 1000, 1000, 0, fill="orange", width=10, outline="white", tag="border")

def shooting():
    global loaded_gun

    c = canvas.coords("player")
    canvas.create_line(c[0],c[1] + 20,c[2],c[3],width=5,fill="yellow",tag="shot")
    loaded_gun = 0

    move_shot("shot")


def move_shot(name):
    global loaded_gun

    canvas.move(name,0,-10)
    canvas.update()

    if loaded_gun == 0:
        shot = canvas.coords(name) # furas

        for x in enemies: # furas

            en = canvas.coords(x) # furas

            if en[0] <= shot[0] <= en[0] + 70: # furas
                if shot[1] <= en[1] + 70: # furas
                    #print(canvas.coords(enemies[x]))
                    canvas.delete(x) # furas
                    #print(canvas.coords(name))
                    enemies.remove(x) # furas
                    canvas.delete(name)
                    loaded_gun = 1
                    break

        if shot[1] < 0: # furas
            canvas.delete(name) # furas
            loaded_gun = 1 # furas

    if loaded_gun == 0: # furas
        window.after(50, move_shot, "shot")


def on_key_press(event):
    global canvas,loaded_gun

    c = canvas.coords("player")

    if event.keysym == 'Left' and c[0] > 0:
        canvas.move("player", -20,0)
    elif event.keysym == 'Right' and c[2] < 1000:
        canvas.move("player", 20, 0)
    elif event.keysym == 'space':
        if loaded_gun == 1:
            shooting()
    elif event.keysym == 'Shift_L':
        loaded_gun = 1
        canvas.delete("shot")

def draw_enemy():
    global enemies

    c = [100,100,170,170]
    inc = 100

    enemies = []

    for x in range(8):
        for y in range(4):
            enemy = canvas.create_rectangle(c[0] + inc * x, c[1] + inc * y,c[2] + inc * x,c[3] + inc * y,fill="red",tag="enemy")
            enemies.append(enemy)

def move_enemy():
    canvas.move("enemy", 0, 20)
    window.after(1000, move_enemy) # furas

#----------------------------------------------------------------------

canvas.create_line(500, 950,500,1000, width=15, fill="red",tag="player")

loaded_gun = 1

draw_enemy()

window.bind_all('<Key>', on_key_press) # furas

move_shot("shot") # furas
move_enemy() # furas

window.mainloop()

撰写回答