繁体   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