簡體   English   中英

Tkinter & 龜蛇游戲

[英]Tkinter & Turtle Snake Game

我一直在試驗 Tkinter 的畫布功能。 我把烏龜放在畫布上,並試圖制作一個蛇游戲。 我試圖運行代碼但有一些問題:

  1. 當您按退出退出時,它不會打印分數,

  2. 筆只能舉一次,不能放回去,也不能再放,

  3. 稱為玩家的烏龜有時不會生成在您實際可以看到的屏幕部分,

  4. 當您觸摸名為 player 的烏龜或移動名為 player 的烏龜時,名為 t 的烏龜不會增加分數。

可能還有其他問題,但這些是我所知道的。

這是我的代碼:

import tkinter as tk
import random
import turtle
import time
import sys

game = False
forward = False
left = False
right = False
backward = False
draw = True
score = 0

def spawn(e=None):
    t.penup()
    t.goto(0,0)
    player=turtle.RawTurtle(app)
    player.penup()
    player.shapesize(0.5,0.5)
    player.shape("square")
    player.color("black")
    xrand = random.randint(-100, 100)
    yrand = random.randint(-100, 100)
    player.goto(x=xrand,y=yrand)
    if t.distance(player) <15:
        x = random.randint(-100, -100)
        y = random.randint(-100, -100)
        player.goto(x,y)
        score = score+1

def systemap(e=None):
    app.place(x=100,y=-4)
    button.place(x=660,y=470)

def f(e=None):
    if game == False:
        t.setheading(90)
        t.forward(5)
    elif game == True:
        forward == True
        while forward == True:
            left == False
            right == False
            backward == False
            t.forward(5)
        if forward == False:
            t.setheading(90)
            t.forward(5)

def l(e=None):
    if game == False:
        t.setheading(180)
        t.forward(5)
    elif game == True:
        left == True
        while left == True:
            forward == False
            right == False
            backward == False
            t.forward(5)
        if left == False:
            t.setheading(180)
            t.forward(5)

def r(e=None):
    if game == False:
        t.setheading(0)
        t.forward(5)
    elif game == True:
        right == True
        while right == True:
            forward == False
            left == False
            backward == False
            t.forward(5)
        if right == False:
            t.setheading(0)
            t.forward(5)

def b(e=None):
    if game == False:
        t.setheading(270)
        t.forward(5)
    elif game == True:
        backward == True
        while backward == True:
            forward == False
            left == False
            right == False
            t.forward(5)
        if backward == False:
            t.setheading(270)
            t.forward(5)

def quit(e=None):
    if game == False:
        time.sleep(1)
        window.destroy()
        sys.exit()
    elif game == True:
        time.sleep(2)
        window.destroy()
        print("Score: ",score)
        sys.exit()

def pen(e=None):
    if draw == True:
        t.penup()
        draw == False
    if draw == False:
        t.pendown()
        draw == True

window = tk.Tk()
window.iconbitmap('py.ico')
window.title("Turtle Graphics")
window.geometry("750x500")
window.resizable(False, False)

button = tk.Button(window,
                   text="      Close      ",
                   font="Calibri",
                   borderwidth=0,
                   background="White",
                   command=quit)

app = tk.Canvas(master=window, width=500, height=500, bg="white")

t=turtle.RawTurtle(app)

window.bind("<Up>", f)
window.bind("<Left>", l)
window.bind("<Right>", r)
window.bind("<Down>", b)

window.bind("<w>", f)
window.bind("<a>", l)
window.bind("<d>", r)
window.bind("<s>", b)

window.bind("<p>", pen)

window.bind("<Escape>", quit)

window.bind("<g>", spawn)

systemap()

window.mainloop()

所以這里需要做幾個更正。 我認為你對一些事情有一些誤解。

  1. 您需要在包含全局命名空間中或需要存在的變量的函數中定義global 如果不這樣做,則在嘗試更新變量時會遇到諸如local variable 'score' referenced before assignment類的錯誤。

  2. ==只是一個比較。 您在需要是單個=地方使用它。

  3. 您定義了一個名為quit的函數,這是一個內置方法。 請注意不要覆蓋內置方法。

  4. 您永遠不會看到打印的分數,因為game總是錯誤的。 您的代碼中沒有任何內容將其更改為 True。

  5. whilesleep()不應與 tkinter 在同一線程中使用。 這將導致問題,因為這兩種方法都會阻塞主循環。 管理這種情況的一種方法是改用after()方法或線程。 在這種情況下,我認為線程是矯枉過正的, after()可能是更好的選擇。

最后,我無法真正完全修復您的代碼,因為我不確定您需要在哪里添加game = True

這是您的代碼清理了一下。 我已經更正了列出的大部分內容,但沒有更多細節,我無法猜測您對其余部分的需求。

如果您有任何問題,請告訴我:

import tkinter as tk
import random, turtle

game = False
forward = False
left = False
right = False
backward = False
draw = True
score = 0


def spawn(_=None):
    global score, forward, left, backward, player
    t.penup()
    t.goto(0, 0)
    player = turtle.RawTurtle(app)
    player.penup()
    player.shapesize(0.5, 0.5)
    player.shape("square")
    player.color("black")
    xrand = random.randint(-100, 100)
    yrand = random.randint(-100, 100)
    player.goto(x=xrand, y=yrand)
    if t.distance(player) < 15:
        x = random.randint(-100, -100)
        y = random.randint(-100, -100)
        player.goto(x, y)
        score = score + 1


def systemap(_=None):
    app.place(x=100, y=-4)
    button.place(x=660, y=470)


def f(_=None):
    global forward, left, right, backward
    if not game:
        t.setheading(90)
        t.forward(5)
    else:
        forward = True
        while forward:
            left = False
            right = False
            backward = False
            t.forward(5)
        if not forward:
            t.setheading(90)
            t.forward(5)


def l(_=None):
    global forward, left, right, backward
    if not game:
        t.setheading(180)
        t.forward(5)
    else:
        left = True
        while left:
            forward = False
            right = False
            backward = False
            t.forward(5)
        if not left:
            t.setheading(180)
            t.forward(5)


def r(_=None):
    global forward, left, right, backward
    if not game:
        t.setheading(0)
        t.forward(5)
    else:
        right = True
        while right:
            forward = False
            left = False
            backward = False
            t.forward(5)
        if not right:
            t.setheading(0)
            t.forward(5)


def b(_=None):
    global forward, left, right, backward
    if not game:
        t.setheading(270)
        t.forward(5)
    else:
        backward = True
        while backward:
            forward = False
            left = False
            right = False
            t.forward(5)
        if not backward:
            t.setheading(270)
            t.forward(5)


def quit_func(_=None):
    if not game:
        window.destroy()
    else:
        window.destroy()
        print("Score: ", score)


def pen(_=None):
    global draw
    if draw:
        t.penup()
        draw = False
    else:
        t.pendown()
        draw = True


window = tk.Tk()
window.title("Turtle Graphics")
window.geometry("750x500")
window.resizable(False, False)
button = tk.Button(window, text="Close", font="Calibri", borderwidth=0, background="White", command=quit_func)
app = tk.Canvas(master=window, width=500, height=500, bg="white")
t = turtle.RawTurtle(app)

window.bind("<Up>", f)
window.bind("<Left>", l)
window.bind("<Right>", r)
window.bind("<Down>", b)
window.bind("<w>", f)
window.bind("<a>", l)
window.bind("<d>", r)
window.bind("<s>", b)
window.bind("<p>", pen)
window.bind("<Escape>", quit_func)
window.bind("<g>", spawn)

systemap()
window.mainloop()

我看到的主要問題是您希望海龜隨着程序的用戶不斷移動而只改變方向。 我不相信你會通過無限循環獲得這種效果,例如:

    while right == True:
        forward == False
        left == False
        backward == False
        t.forward(5)

這依賴於一些外部事件來改變right的值,但並沒有真正暫停讓其他事件運行。 (加上===的錯誤使用。)

其他問題包括:

由於符號錯誤,玩家只能重新定位一次,始終移動到同一地點:

x = random.randint(-100, -100)
y = random.randint(-100, -100)

缺少必要的global語句以及== vs =誤用:

def pen(e=None):
    if draw == True:
        t.penup()
        draw == False
    if draw == False:
        t.pendown()
        draw == True

如果沒有測試這些基本功能中的一些,您永遠不應該像您那樣編碼。 您編寫的未經測試的代碼越多,調試起來就越困難。

下面是我對你的代碼的返工,實現了烏龜(蛇)的恆定運動。 我還將一些與海龜相關的代碼從 tkinter 領域移到了海龜方法中。 我為這個例子簡化了一些東西(例如只有一組運動鍵,箭頭。)但我相信它現在是一個非常基本但可玩的游戲:

import tkinter as tk
from turtle import TurtleScreen, RawTurtle
from random import randint

direction = None
score = 0

def spawn():
    player = RawTurtle(screen)
    player.hideturtle()
    player.shape('square')
    player.shapesize(0.5)
    player.color('black')
    player.penup()

    x = randint(-100, 100)
    y = randint(-100, 100)
    player.goto(x, y)
    player.showturtle()

    players.append(player)

def check_collision():
    global score

    for player in players:
        if turtle.distance(player) < 15:
            x = randint(-100, 100)
            y = randint(-100, 100)
            player.goto(x, y)
            score += 1

def f():
    global direction

    def move():
        check_collision()

        if direction == 'forward':
            turtle.forward(5)
            screen.ontimer(move, 100)

    if direction != 'forward':
        direction = 'forward'
        turtle.setheading(90)
        move()

def l():
    global direction

    def move():
        check_collision()

        if direction == 'left':
            turtle.forward(5)
            screen.ontimer(move, 100)

    if direction != 'left':
        direction = 'left'
        turtle.setheading(180)
        move()

def r():
    global direction

    def move():
        check_collision()

        if direction == 'right':
            turtle.forward(5)
            screen.ontimer(move, 100)

    if direction != 'right':
        direction = 'right'
        turtle.setheading(0)
        move()

def b():
    global direction

    def move():
        check_collision()

        if direction == 'backward':
            turtle.forward(5)
            screen.ontimer(move, 100)

    if direction != 'backward':
        direction = 'backward'
        turtle.setheading(270)
        move()

def pen():
    if turtle.isdown():
        turtle.penup()
    else:
        turtle.pendown()

def quit_game(e=None):  # called from either turtle or tkinter
    window.destroy()
    print("Score:", score)
    exit()

players = []

window = tk.Tk()
# window.iconbitmap('py.ico')
window.title("Turtle Graphics")
window.geometry("600x600")
window.resizable(False, False)

canvas = tk.Canvas(master=window, width=500, height=500)
canvas.pack()

tk.Button(window, width=17, text='Close', borderwidth=0, command=quit_game).pack()

screen = TurtleScreen(canvas)
turtle = RawTurtle(screen)

screen.onkey(f, 'Up')
screen.onkey(l, 'Left')
screen.onkey(r, 'Right')
screen.onkey(b, 'Down')

screen.onkey(pen, 'p')
screen.onkey(quit_game, 'Escape')
screen.onkey(spawn, 'g')

screen.listen()
screen.mainloop()

在此處輸入圖片說明

暫無
暫無

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

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