Zelle-graphics window — 克隆对象而不是移动

Zelle-graphics window — Cloning object instead of moving

我正在模拟交通灯和汽车。当灯变绿时,汽车应该移动。 (我知道实际的红绿灯不会从绿色跳到红色,或者从红色跳到黄色,但是......随它去吧)。该程序从用户那里获取关于红绿灯应该循环多长时间的输入;它首先保持红色 3 秒,然后循环显示其他颜色。

所以我的问题是,当我尝试移动汽车(此处由 Rectangle 对象表示)和车轮(两个 Circle 对象)时,图形 window 似乎创建一个全新的矩形,尽管我没有在我的程序中的任何地方调用 clone() 方法或任何东西。尝试 运行 程序 8 秒以上以查看。

为什么汽车矩形要复制自身而不是移动原件?

代码如下:

import sys
from graphics import *
import time

def drawCar(win):
    car = Rectangle(Point(0,510), Point(100,555))
    car.setFill(color_rgb(255,0,0))
    wheel1 = Circle(Point(15,565),10)
    wheel2 = Circle(Point(75,565),10)
    wheel1.setFill(color_rgb(0,0,0))
    wheel2.setFill(color_rgb(0,0,0))
    car.draw(win)
    wheel1.draw(win)
    wheel2.draw(win)

def drawTrack(win):
    rect = Rectangle(Point(0,575),Point(500,600))
    rect.setFill(color_rgb(0,0,0))
    rect.draw(win)
    drawCar(win)

def loop(x):
    # opens and titles a graphics window
    win = GraphWin("Traffic Light", 500,600)

    # creates 3 black circles for the window
    red = Circle(Point(250,100),80)
    yellow = Circle(Point(250,260),80)
    green = Circle(Point(250,420),80)

    # draw the car and track
    drawTrack(win)
    corner1 = Point(0,510)
    corner2 = Point(100,555)
    car = Rectangle(corner1,corner2)
    car.setFill(color_rgb(255,0,0))
    wheel1 = Circle(Point(15,565),10)
    wheel2 = Circle(Point(75,565),10)
    wheel1.setFill(color_rgb(0,0,0))
    wheel2.setFill(color_rgb(0,0,0))
    car.draw(win)
    wheel1.draw(win)
    wheel2.draw(win)

    # sets default colors of the circles
    red.setFill(color_rgb(255,0,0))
    yellow.setFill(color_rgb(0,0,0))
    green.setFill(color_rgb(0,0,0))
    red.draw(win)
    yellow.draw(win)
    green.draw(win)

    redCount = 1 # red light counter is automatically set to 1 because it starts with red by default
    yelCount = 0 # yellow and green light counters are set to 0
    greenCount = 0

    redSet = True
    yellowSet = False
    greenSet = False

    start = time.time()
    end = time.time() + x

    time.sleep(2) # wait 2 seconds while showing the red light (since the loop waits 1 additional second on the red), then begin the color-changing

    while (time.time() - start < end):
        if(time.time() + 1 > end): # if the time it will take to rest on the next light will make it go overtime
            break # then stop
        if redSet:
            print("Red, changing to yellow")
            red.setFill(color_rgb(0,0,0))
            yellow.setFill(color_rgb(255,255,0))
            yelCount += 1
            redSet = False
            yellowSet = True
            time.sleep(1) # hold the yellow light for 1 second
        elif yellowSet:
            yellow.setFill(color_rgb(0,0,0))
            green.setFill(color_rgb(0,255,0))
            greenCount += 1
            yellowSet = False
            greenSet = True
            time.sleep(1) # hold green light for 1 second
            #corner1.move(60,0)
            #corner2.move(60,0)
            car.move(60,0)
            wheel1.move(60,0)
            wheel2.move(60,0)
            print("Corners moved")
        elif greenSet:
            green.setFill(color_rgb(0,0,0))
            red.setFill(color_rgb(255,0,0))
            greenSet = False
            redSet = True
            time.sleep(1)
            redCount += 1
        else:
            break

    print("Red light hit ", redCount)
    print("Yellow light hit ", yelCount)
    print("Green light hit ", greenCount)

    # if the user clicks anywhere in the window
    win.getMouse()
    # then we close the window
    win.close()


def main():
    # prompts the user for a time limit
    x = float(input("How many seconds do you want the traffic light simulation to last? "))
    # prints confirmation
    print("Starting the loop for ", x, " seconds:")

    # begins the loop
    loop(x)


main()

问题是因为您绘制了两次汽车(和车轮)。
幸运的是,防止这种情况的修复很简单:

def drawTrack(win):
    rect = Rectangle(Point(0,575),Point(500,600))
    rect.setFill(color_rgb(0,0,0))
    rect.draw(win)
#    drawCar(win)  # Don't do this.

注意:执行此操作后,将不会调用函数 drawCar(),因此您可以 将其删除.另一种选择是保留它并替换 loop() 函数初始化部分中的代码行,这些代码行通过调用它来做同样的事情(从而使代码更加模块化)。