簡體   English   中英

為什么在另一個函數中重新定義一個函數不起作用? (巨蟒龜)

[英]Why doesn’t redefining a function inside another function work? (Python Turtle)

我正在編寫一個游戲,其中敵人的海龜(在程序中稱為 badturt)追逐用戶的海龜。 用戶可以通過發送攻擊(另一只烏龜)使其烏龜攻擊敵方烏龜。

在 lvl 2 中,有兩只敵方海龜追逐用戶的海龜。 為了讓一只敵龜停止移動(在它被攻擊/擊中后),我嘗試重新定義使敵龜移動的函數,這是在另一個函數中完成的。 (我將其重新定義為無)

attack = turtle.Turtle()
#...attributes

def turtleattack():
    global lvl
    global q
    global w
    global e
    #... positioning attack
    for i in range(75):
        attack.forward(10)
        if lvl == 1:
            Chase(badturt)
        if lvl == 2:
            Chase(badturt)
            Chase(badturt2)
        if lvl == 3:
            Chase(badturt)
            Chase(badturt2)
            Chase(badturt3)
        IfAttackHit()
bg.onkeypress(turtleattack, 'z')
bg.listen()


def Chase(bt): #makes bad turt (bt) chase turt
    bt.setheading(bt.towards(turt))
    bt.forward(11)

def StopChase(bt):
    global lvl
    global win
    #global Chase <---------------- program stops running if I write it in
    if lvl == 1:
        #...
    if lvl == 2:
        def Chase(bt):
            None
        if q == 2 and w == 2:
            lvl = 3
            writeinfo()
    if lvl == 3:
        def Chase(bt):
            None
        if q == 3 and w == 3 and e == 3:
            #... (winning the game)

def ChaseAgain(bt): #makes badturt chase again when it moves onto next lvl
    def Chase(bt):
        bt.setheading(badturt.towards(turt))
        bt.forward(11)
    Chase(bt)


def IfAttackHit():
    global win
    global lvl
    global q
    global w
    global e
    if lvl == 1:
        if badturt.distance(attack) < 20:
            badturt.hideturtle()
            attack.hideturtle()
            badturt.goto(300,350)
            q = 1
            StopChase(badturt) #<---- doesn't work
    if lvl == 2:
        if badturt.distance(attack) < 20:
            badturt.hideturtle()
            attack.hideturtle()
            badturt.goto(300,350)
            q = 2
            StopChase(badturt)
        if badturt2.distance(attack) < 20:
            badturt2.hideturtle()
            badturt2.goto(-300,350)
            attack.hideturtle()
            w = 2
            StopChase(badturt2)
    if lvl == 3:
        #same format as lvl 2 but with addition of badturt3


while True:
    if lvl == 1:
         while True:
            CheckDamage()
            if turthealth == 0:
                LOSE()
                break
            IfAttackHit()
            Chase(badturt)
            if q == 1:
                break
    break
    if lvl == 2:
        ChaseAgain(badturt) #make it move again
        ChaseAgain(badturt2)
        badturt.goto(300,350)
        badturt.showturtle()
        badturt2.showturtle()
        while True:
            CheckDamage()
            if turthealth == 0:
                LOSE()
                break
            IfAttackHit()
            Chase(badturt)
            Chase(badturt2)
    break
    if lvl == 3:
        #same format as lvl 2 but with addition of badturt3
        break

這沒有用。 是因為它嵌套在另一個函數中嗎? 從未調用過 StopChase() 嗎? 函數是否再次被重新定義,以便敵方烏龜再次開始移動?

另外,我的老師告訴我,我必須編寫“全局追逐”以在另一個函數中重新定義它,但是當我這樣做時,程序會在那一點停止運行 - 當我將光標移到海龜屏幕上時,它只顯示加載光標,屏幕上沒有任何反應/它凍結。 (這樣做是錯誤的,還是我的筆記本電腦上的 python 程序有問題?)

我還嘗試重新定義 Chase() 以便 badturt 只會向前移動 0(基本上使它什么都不做),但這也不起作用。

請讓我知道我做錯了什么,或者是否有另一種方法可以讓 badturt 停止移動。

當你重新定義一個非類方法時,重新定義是永久性的,這意味着它適用於一切。 你可能不想那樣。

什么反對在您的 Chase 方法中編寫條件?


您的代碼中存在各種不良的編碼實踐:

  • 您通常應該避免使用global 您應該創建具有屬性的類和類的實例並傳遞這些實例。
  • 方法沒有大寫。 類是大寫的。
  • 由於break您有一些無法訪問的代碼
  • 當不應該發生任何事情時,使用pass而不是None

Tin Nguyen 是絕對正確的,你絕對應該聽從他的建議。 我只想詳細說明你的第一個問題。 即使它可能很糟糕,使用 global 重新定義您的函數也應該有效。 這是我嘗試的最小示例:

def f():
    print("f")

def g():
    global f
    def f():
        print("f_prime")

f()
g()
f()

當被調用時,我得到:

f
f_prime

您的程序停止的原因必須在其他地方,但您沒有提供您遇到的錯誤(如果有)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM