Черепаха не отвечает на ввод

Я пытаюсь создать игровой тетрис, используя модуль черепахи в python, но у меня возникают некоторые проблемы.

Раньше у меня была проблема, когда некоторые блоки, составляющие мою квадратную фигуру, двигались слева направо, но не все. Я понял, что проблема заключалась в том, что скрипт получал входные данные игрока в середине цикла for, обновляя позиции в функции update_pos() после того, как некоторые блоки уже были перемещены.

Мое решение состояло в том, чтобы отключить ввод игрока во время цикла for, который обновляет блоки, сказав:

scn.onkeypress(None, "a")
scn.onkeypress(None, "d")

Но как только я это сделал, блоки больше не двигались ни влево, ни вправо. Все, что я мог предположить, это то, что ввод игрока никогда не восстанавливался должным образом, но я не уверен, почему.

import turtle
import time
import random

last_check = time.time()
spawn_pos = (-12.5, 345)
interval = 2.5
x_input, y_input = 0, 0
colors = ["red", "yellow", "green", "blue"]

scn = turtle.Screen()
scn.setup(1280, 720)

brick = turtle.Turtle()
brick.penup()
brick.pencolor("black")
brick.speed(0)
brick.shape("square")
brick.shapesize(1.05, 1.05, 1.5)

def update_pos(current_shape):
    global x_input, y_input
    scn.onkeypress(None, "a")
    scn.onkeypress(None, "d")
    for a in range(4):
        current_shape[a][1].setpos((current_shape[a][1].xcor() + x_input), (current_shape[a][1].ycor() + y_input - 25))
    x_input, y_input = 0, 0
    scn.onkeypress(move_left, "a")
    scn.onkeypress(move_right, "d")


def spawn_square():
    shape = [[(0, 0)], [(25, 0)], [(25, -25)], [(0, -25)]]
    brick.fillcolor("yellow")
    brick.setpos(spawn_pos)
    move_bricks(shape)
    return(shape)

def move_bricks(shape):
    for i in range(4):
        brick.fillcolor(colors[i])
        shape[i].append(brick.clone())
        shape[i][1].setpos((shape[i][1].xcor() + shape[i][0][0]), (shape[i][1].ycor() + shape[i][0][1]))

def move_left():
    global x_input
    x_input -= 25

def move_right():
    global x_input
    x_input += 25

scn.onkeypress(move_left, "a")
scn.onkeypress(move_right, "d")
scn.listen()

current_shape = spawn_square()

while True:
    if time.time() - last_check > interval:
        last_check = time.time()
        if current_shape[3][1].ycor() <= -300:
            y_input = 600
        update_pos(current_shape)

person J05HUA    schedule 24.07.2020    source источник


Ответы (1)


Некоторые проблемы с вашим кодом:

  • Вы не обновляете рисунок немедленно на основе пользовательского ввода, вы ждете вертикальной перерисовки. Таким образом, пользователь не получает обратную связь о результате своих действий.

  • Вы использовали цикл таймера, который потенциально блокировал события. (Например, попробуйте закрыть окно, оно задерживается до следующей вертикальной перерисовки.) Я изменил это, чтобы вместо этого использовать событие таймера черепахи, чтобы все работало вместе лучше.

Я переработал ваш код ниже, чтобы он работал так, как вы предполагали:

from turtle import Screen, Turtle

SPAWN_POS = (-12.5, 370)
INTERVAL = 1000  # milliseconds
COLORS = ['red', 'yellow', 'green', 'blue']

x_input, y_input = 0, 0

def update_pos(shape):
    global x_input, y_input

    for a in range(4):
        shape[a][1].setpos((shape[a][1].xcor() + x_input), (shape[a][1].ycor() + y_input))

    x_input, y_input = 0, 0

    screen.update()

def spawn_square():
    shape = [[(0, 0)], [(25, 0)], [(25, -25)], [(0, -25)]]
    move_bricks(shape)

    return shape

def move_bricks(shape):
    for i in range(4):
        brick.fillcolor(COLORS[i])
        shape[i].append(brick.clone())
        shape[i][1].setpos((shape[i][1].xcor() + shape[i][0][0]), (shape[i][1].ycor() + shape[i][0][1]))

    screen.update()

def move_left():
    global x_input

    x_input -= 25
    update_pos(current_shape)

def move_right():
    global x_input

    x_input += 25
    update_pos(current_shape)

def drop_bricks():
    global y_input

    screen.onkeypress(None, 'a')
    screen.onkeypress(None, 'd')

    if current_shape[3][1].ycor() <= -300:
        y_input = 600
    else:
        y_input -= 25

    update_pos(current_shape)

    screen.onkeypress(move_left, 'a')
    screen.onkeypress(move_right, 'd')

    screen.ontimer(drop_bricks, INTERVAL)

screen = Screen()
screen.setup(1280, 720)
screen.tracer(False)
screen.listen()

brick = Turtle()
brick.penup()
brick.shape('square')
brick.shapesize(1.05, 1.05, 1.5)
brick.setpos(SPAWN_POS)

current_shape = spawn_square()

drop_bricks()

screen.mainloop()
person cdlane    schedule 25.07.2020