我正试着为一项家庭作业(job)搞一场打地鼠游戏.程序执行得很好,它会生成一个在方格之间 skip 的随机鼹鼠.应该使用参考点的数字键盘点击鼹鼠,所以7在左上角,以此类推.

然而,无论何时播放,它都会告诉我,我每次都会错过.通过实验,我发现如果我预测鼹鼠go 了哪里,我就会击中它,这意味着它在下一次循环之前不会进行比较.这里需要发生什么?

import turtle
import random
import time

t = turtle.Turtle()
t.hideturtle()

mole_x, mole_y = 0, 0

# Set up screen
wn = turtle.Screen()
wn.title("Whack-A-Mole")
wn.bgcolor("green")
wn.setup(width=600, height=600)
wn.tracer(0)


# Draws a square with top-left position (x,y) and side length size
def drawsq(x, y, size):
    t.penup()
    t.goto(x, y)
    t.pendown()
    for i in range(4):
        t.forward(size)
        t.right(90)
    t.penup()


# Draw a circle at center (x,y) with radius r
def drawcr(x, y, r):
    t.penup()
    t.goto(x, y - r)
    t.pendown()
    t.circle(r)

def molecoords():
    coords = [-150, 0, 150]
    x = random.choice(coords)
    y = random.choice(coords)
    return x, y

#Draws the mole
def draw_mole(x, y): 
    drawcr(x, y, 50)  # Body
    drawcr(x - 40, y - 40, 7)  # Left foot
    drawcr(x + 40, y - 40, 7)  # Right foot
    drawcr(x - 55, y + 15, 7)  # Left hand
    drawcr(x + 55, y + 15, 7)  # Right hand
    t.penup()  # Head
    t.goto(x - 45, y + 20)
    t.setheading(-50)
    t.pendown()
    t.circle(60, 100)
    t.setheading(0)
    drawcr(x - 10, y + 35, 2)  # Left eye
    drawcr(x + 10, y + 35, 2)  # Right eye
    drawgrid(x - 7, y + 20, 2, 1, 7)  # Teeth
    t.goto(x, y + 22)  # Nose
    t.fillcolor("black")  # Set the fill color
    t.begin_fill()  # Begin filling
    t.pendown()
    t.left(60)
    t.forward(5)
    t.left(120)
    t.forward(5)
    t.left(120)
    t.forward(5)
    t.end_fill()
    t.setheading(0)

# Draw a grid with x rows and y columns with squares of side length size starting at (tlx,tly)
def drawgrid(tlx, tly, x, y, size):
    for i in range(x):
        for j in range(y):
            drawsq(tlx + (i * size), tly - j * size, size)

def check_hit(key):
    target_positions = {
        '1': (-150, -150),
        '2': (0, -150),
        '3': (150, -150),
        '4': (-150, 0),
        '5': (0, 0),
        '6': (150, 0),
        '7': (-150, 150),
        '8': (0, 150),
        '9': (150, 150)
    }
    target_x, target_y = target_positions.get(key)
    if (mole_x, mole_y) == (target_x, target_y):
        print("Hit!")
    else:
        print("Miss!")

def on_key_press(key):
    check_hit(key)

def game_loop():
    global mole_x, mole_y
    start = time.time()
    duration = 30
    while time.time() - start < duration:
        t.clear()
        drawgrid(-225, 225, 3, 3, 150)
        mole_x, mole_y = molecoords()
        draw_mole(mole_x, mole_y)
        wn.update()
        time.sleep(2)

# Bind key press events
wn.listen()
wn.onkeypress(lambda: on_key_press('1'), '1')
wn.onkeypress(lambda: on_key_press('2'), '2')
wn.onkeypress(lambda: on_key_press('3'), '3')
wn.onkeypress(lambda: on_key_press('4'), '4')
wn.onkeypress(lambda: on_key_press('5'), '5')
wn.onkeypress(lambda: on_key_press('6'), '6')
wn.onkeypress(lambda: on_key_press('7'), '7')
wn.onkeypress(lambda: on_key_press('8'), '8')
wn.onkeypress(lambda: on_key_press('9'), '9')

game_loop()

def gameover():
    t.penup()
    wn.clear()
    wn.bgcolor("black")
    t.goto(0, 100)
    t.pencolor("White")
    t.write("Time's Up!", align="center", font=("Arial", 80, "bold"))

gameover()

turtle.done()

它正确地读取输入,只是没有在正确的时间应用它们.

推荐答案

这里有很多问题(我通常建议最小化您的问题代码以隔离问题),但根本问题是在Turtle程序中使用whilesleep.一般来说,是neither belong.实现循环和事件的常用工具是Screen().ontimer().

以下是部分重写,它清理了一些东西(使用基本的文档字符串,删除了一些重复),并稍微重新组织了代码,以适应ontimer设计.作为一种练习,还有很大的改进空间.

import random
from turtle import Screen, Turtle


def draw_square(x, y, size):
    """Draws a square with top-left position (x,y) and side length size"""
    t.penup()
    t.goto(x, y)
    t.pendown()
    for i in range(4):
        t.forward(size)
        t.right(90)
    t.penup()


def draw_circle(x, y, r):
    """Draw a circle at center (x,y) with radius r"""
    t.penup()
    t.goto(x, y - r)
    t.pendown()
    t.circle(r)


def new_mole_position():
    """Chooses random mole coordinates"""
    coords = [-150, 0, 150]
    x = random.choice(coords)
    y = random.choice(coords)
    return x, y


def draw_mole(x, y): 
    """Draws the mole at (x, y)"""
    draw_circle(x, y, 50)  # Body
    draw_circle(x - 40, y - 40, 7)  # Left foot
    draw_circle(x + 40, y - 40, 7)  # Right foot
    draw_circle(x - 55, y + 15, 7)  # Left hand
    draw_circle(x + 55, y + 15, 7)  # Right hand
    t.penup()  # Head
    t.goto(x - 45, y + 20)
    t.setheading(-50)
    t.pendown()
    t.circle(60, 100)
    t.setheading(0)
    draw_circle(x - 10, y + 35, 2)  # Left eye
    draw_circle(x + 10, y + 35, 2)  # Right eye
    draw_grid(x - 7, y + 20, 2, 1, 7)  # Teeth
    t.goto(x, y + 22)  # Nose
    t.fillcolor("black")  # Set the fill color
    t.begin_fill()  # Begin filling
    t.pendown()
    t.left(60)
    t.forward(5)
    t.left(120)
    t.forward(5)
    t.left(120)
    t.forward(5)
    t.end_fill()
    t.setheading(0)


def draw_grid(tlx, tly, x, y, size):
    """
    Draws a grid with x rows and y columns with
    squares of side length size starting at (tlx,tly)
    """
    for i in range(x):
        for j in range(y):
            draw_square(tlx + (i * size), tly - j * size, size)


def check_hit(key):
    """Determines whether a key corresponds to the mole"s location"""
    target_positions = {
        "1": (-150, -150),
        "2": (0, -150),
        "3": (150, -150),
        "4": (-150, 0),
        "5": (0, 0),
        "6": (150, 0),
        "7": (-150, 150),
        "8": (0, 150),
        "9": (150, 150)
    }
    target_x, target_y = target_positions.get(key)
    if (mole_x, mole_y) == (target_x, target_y):
        print("Hit!")
    else:
        print("Miss!")


def move_mole():
    """
    Moves the mole and triggers the next mole move
    if the timer hasn"t expired
    """
    global mole_x, mole_y

    if game_over:
        return

    mole_x, mole_y = new_mole_position()
    t.clear()
    draw_grid(-225, 225, 3, 3, 150)
    draw_mole(mole_x, mole_y)
    wn.update()
    wn.ontimer(move_mole, 2000)


def end_game():
    """Ends the game"""
    global game_over
    game_over = True
    t.penup()
    wn.clear()
    wn.bgcolor("black")
    t.goto(0, 100)
    t.pencolor("White")
    t.write("Time's Up!", align="center", font=("Arial", 20, "bold"))


def bind_key(k):
    """Bind key k to check hit on the corresponding square"""
    wn.onkeypress(lambda: check_hit(k), k)


t = Turtle()
t.hideturtle()
mole_x, mole_y = 0, 0

# Set up screen
wn = Screen()
wn.tracer(0)
wn.title("Whack-A-Mole")
wn.bgcolor("green")
wn.setup(width=600, height=600)

# Bind key press events
wn.listen()
for i in range(1, 10):
    bind_key(str(i))

duration = 30
game_over = False
wn.ontimer(end_game, duration * 1000)
move_mole()
wn.exitonclick()

Python相关问答推荐

Python 3.12中的通用[T]类方法隐式类型检索

Select 用a和i标签包裹的复选框?

连接两个具有不同标题的收件箱

查找两极rame中组之间的所有差异

无法通过python-jira访问jira工作日志(log)中的 comments

如何找到满足各组口罩条件的第一行?

更改键盘按钮进入'

如何根据一列的值有条件地 Select 前N组?

转换为浮点,pandas字符串列,混合千和十进制分隔符

* 动态地 * 修饰Python中的递归函数

如何获取Python synsets列表的第一个内容?

判断Python操作:如何从字面上得到所有decorator ?

递归函数修饰器

我可以不带视频系统的pygame,只用于游戏手柄输入吗?''

如何从数据框列中提取特定部分并将该值填充到其他列中?

Pythonquests.get(Url)返回Colab中的空内容

一维不匹配两个数组上的广义ufunc

是否需要依赖反转来确保呼叫方和被呼叫方之间的分离?

try 在单个WITH_COLUMNS_SEQ操作中链接表达式时,使用Polars数据帧时出现ComputeError

大Pandas 中的群体交叉融合