首页 > 解决方案 > 每次我完成一行时,俄罗斯方块都会变慢(Python,Turtle)

问题描述

我正在尝试使用海龟库在 python 中制作俄罗斯方块,但我遇到了不知道如何解决的问题。游戏刚开始还不错,但每次玩完后都会变慢,5-6 次后就无法玩了。这是游戏视频(我还没有完成): https ://youtu.be/f8cENc-fP7E

这是完整的代码: https ://pastebin.com/kS8yGJQ7

但问题可能出在功能检查中:

def check():
    global pen2, pen3
    
    for i in range(len(blocks2)):
        blocksfordelete = []
        k = 0
        
        for j in range(len(blocks2)):
            if blocks2[i][1] == blocks2[j][1]:
                blocksfordelete.append(blocks2[j])
                k += 1
        
        if k == 13:
            for m in range(len(blocksfordelete)):
                pen4 = turtle.Turtle("square")
                pen4.shapesize(squaresize / 20)
                pen4.penup()
                pen4.color("white")
                pen4.goto(blocksfordelete[m][0], blocksfordelete[m][1])
                pen4.stamp()
                
            for n in blocksfordelete:
                if n in blocks2:
                    blocks2.remove(n)
 
            for x in blocks2:
                if x[1] > blocksfordelete[0][1]:
                    pen5 = turtle.Turtle("square")
                    pen5.shapesize(squaresize / 20)
                    pen5.penup()
                    pen5.color("white")
                    pen5.goto(x[0], x[1])
                    pen5.stamp()
 
                    pen6 = turtle.Turtle("square")
                    pen6.shapesize(squaresize / 20)
                    pen6.penup()
                    x[1] -= squaresize
                    pen6.color("black")
                    pen6.goto(x[0], x[1])
                    pen6.stamp()
 
            break

标签: pythonperformanceturtle-graphicstetris

解决方案


我发现您的代码存在一些性能问题。首先,您一遍又一遍地动态创建海龟。虽然从文档中不清楚,但海龟本质上是全局实体,除非您重置屏幕或退出海龟,否则它们永远不会消失。只创建您需要的并重复使用它们

其次,您使用冲压和清除来显示下落的乌龟,因为它侧向和向下移动。为此,我们可以简单地使用一只活海龟,并将海龟堆的标记代码留在屏幕底部。下面是您的代码,如上所述,以及许多调整:

from turtle import Screen, Turtle

SQUARE_SIZE = 30
CURSOR_SIZE = 20

WIDTH = 400 + SQUARE_SIZE/2
HEIGHT = 600 + SQUARE_SIZE/2

delay = 300
blocks1 = []
blocks2 = []

def start():
    blocks1.append([0, HEIGHT/2 + SQUARE_SIZE/2])
    pen_falling.showturtle()
    update()

def update():
    blocks1[0][1] -= 30

    if blocks1[0] in blocks2:
        blocks1[0][1] += SQUARE_SIZE
        pen_black.goto(blocks1[0])
        pen_black.stamp()
        blocks2.append(blocks1.pop(0))
        check()
        start()
    elif blocks1[0][1] == -HEIGHT/2 + 30:
        pen_black.goto(blocks1[0])
        pen_black.stamp()
        blocks2.append(blocks1.pop(0))
        check()
        start()
    else:
        pen_falling.goto(blocks1[0])
        screen.update()
        screen.ontimer(update, delay)

def down1():
    global delay
    delay = 50

def down2():
    global delay
    delay = 300

def right():
    if blocks1[0][0] < WIDTH/2 - SQUARE_SIZE:
        blocks1[0][0] += SQUARE_SIZE

        if blocks1[0] not in blocks2:
            pen_falling.goto(blocks1[0])
        else:
            blocks1[0][0] -= SQUARE_SIZE

def left():
    if blocks1[0][0] > -WIDTH/2 + SQUARE_SIZE:
        blocks1[0][0] -= SQUARE_SIZE

        if blocks1[0] not in blocks2:
            pen_falling.goto(blocks1[0])
        else:
            blocks1[0][0] += SQUARE_SIZE

def check():
    for i in range(len(blocks2)):
        blocksfordelete = []
        k = 0

        for block in blocks2:
            if blocks2[i][1] == block[1]:
                blocksfordelete.append(block)
                k += 1

        if k == 13:
            for block in blocksfordelete:
                pen_white.goto(block)
                pen_white.stamp()

            for block in blocksfordelete:
                if block in blocks2:
                    blocks2.remove(block)

            for block in blocks2:
                if block[1] > blocksfordelete[0][1]:
                    pen_white.goto(block)
                    pen_white.stamp()

                    block[1] -= SQUARE_SIZE

                    pen_black.goto(block)
                    pen_black.stamp()

            break

screen = Screen()
screen.setup(WIDTH, HEIGHT)
screen.title("Tetris")
screen.tracer(False)

pen_falling = Turtle('square')
pen_falling.hideturtle()
pen_falling.shapesize(SQUARE_SIZE / CURSOR_SIZE)
pen_falling.penup()
pen_falling.color('black')

pen_black = Turtle('square')
pen_black.hideturtle()
pen_black.shapesize(SQUARE_SIZE / CURSOR_SIZE)
pen_black.penup()
pen_black.color('black')

pen_white = Turtle('square')
pen_white.hideturtle()
pen_white.shapesize(SQUARE_SIZE / CURSOR_SIZE)
pen_white.penup()
pen_white.color('white')

screen.onkeypress(left, 'Left')
screen.onkeypress(right, 'Right')
screen.onkeypress(down1, 'Down')
screen.onkeyrelease(down2, 'Down')
screen.onkey(screen.bye, 'Escape')

screen.listen()

start()

screen.mainloop()

如果您仍然有性能问题,请告诉我,我会更深入地研究。

为了获得更高的性能,请考虑管理您的图章而不是覆盖它们。如果您跟踪方法返回的印章 IDstamp() ,则可以删除单个印章。

很好地使用onkeypress()vs.onkeyrelease()向下箭头键!


推荐阅读