Python交通灯仿真

引言

在Python的生态系统中,Turtle模块为图形编程提供了简单直观的方式。本项目旨在利用Turtle模块创建一个有趣的交通灯模拟器,结合倒计时效果。我将分步解释这个项目。
先放上最终效果图:
在这里插入图片描述
这个源码也放我仓库了
GitHub hewei2723/LBE

首先对于三种交通灯有四种情况:
红(Red)黄(Yellow)绿(Green)无信号(B)
红灰灰 灰黄灰 灰灰绿
我用rbb byb bbg来代替,
我本来想直接一个点一个点的变换的,但是发现turtle不行,所以就给每个状态打包绘制,就跟遥控器的滚码一样
红灰灰 灰黄灰 灰灰绿 分别代表红灯 黄灯 绿灯三个状态。
红灯行 绿灯停,黄灯亮了等一等,交通灯切换是直接用覆盖来变化的。当红灯开始时会画三个圆圈
红 灰 灰
然后黄灯会直接覆盖在红灯上,效果如图:
在这里插入图片描述

函数 draw_traffic_light

这个是专门用来画三个灯的函数

def draw_traffic_light(x, y, radius, color, label):
    t.penup()
    t.goto(x, y - radius)  # 移动到圆心位置
    t.pendown()
    t.speed(50)
    
    # 画圆
    t.color("black", color)
    t.begin_fill()
    t.circle(radius)
    t.end_fill()
    
    # 添加文字说明
    t.penup()
    t.goto(x, y - radius - 20)  # 调整文字位置
    t.pendown()
    t.write(label, align="center", font=("Arial", 10, "normal"))

作用:

  • 绘制一个交通灯的圆形灯和相关状态文字。
  • 接受参数:位置(x, y)、半径、颜色、标签。

效果

在这里插入图片描述

思维:

  • 使用Turtle模块的circle函数绘制圆形。
  • 考虑文字的位置,使用write函数添加文字说明。

函数 rbb

def rbb():
    draw_traffic_light(50, 100, traffic_light_radius, "red", "红灯禁止通行")
    draw_traffic_light(150, 100, traffic_light_radius, "gray", "")
    draw_traffic_light(250, 100, traffic_light_radius, "gray", "")
    countdown_timer(5)
    byb()
    bbg()

作用:

  • 模拟红灯状态。
  • 调用draw_traffic_light绘制红灯、灰色灯(不可见)、灰色灯。
  • 调用countdown_timer进行倒计时。
  • 调用其他两个状态函数。

思维:

  • 状态的变迁和倒计时函数的嵌套调用。
  • 灰色灯表示状态切换时的过渡。

函数 byb

def byb():
    draw_traffic_light(50, 100, traffic_light_radius, "gray", "")
    draw_traffic_light(150, 100, traffic_light_radius, "yellow", "黄灯请等待")
    draw_traffic_light(250, 100, traffic_light_radius, "gray", "")
    countdown_timer(3)

作用:

  • 模拟黄灯状态。
  • 调用draw_traffic_light绘制灰色灯、黄灯、灰色灯。
  • 调用countdown_timer进行倒计时。

思维:

  • 通过灰色灯表示状态切换时的过渡。

函数 bbg

def bbg():
    draw_traffic_light(50, 100, traffic_light_radius, "gray", "")
    draw_traffic_light(150, 100, traffic_light_radius, "gray", "")
    draw_traffic_light(250, 100, traffic_light_radius, "green", "绿灯可以通行")
    countdown_timer(5)
    byb()
    rbb()

作用:

  • 模拟绿灯状态。
  • 调用draw_traffic_light绘制灰色灯、灰色灯、绿灯。
  • 调用countdown_timer进行倒计时。
  • 调用其他两个状态函数。

思维:

  • 通过灰色灯表示状态切换时的过渡。
  • 状态的循环切换。

函数 drawGapdrawLine

def drawGap():
    turtle.penup()
    turtle.fd(5)

def drawLine(draw):
    drawGap()
    turtle.pendown() if draw else turtle.penup()
    turtle.fd(40)
    drawGap()
    turtle.right(90)

作用:

  • 用于绘制数字显示的空隙和线段。
  • drawGap 绘制空隙,drawLine 绘制线段。

思维:

  • 控制Turtle画笔的抬起和放下,形成数字的显示效果。

效果

在这里插入图片描述

函数 drawDigitsdrawDate

def drawDigits(digit):
    # ...(略)
    
def drawDate(date, start_position=(330, 100)):
    # ...(略)

作用:

  • drawDigits 用于绘制数字的各个线段。
  • drawDate 用于绘制倒计时数字。

思维:

  • 利用drawLine函数,根据数字的每一位,绘制相应的线段。

函数 countdown_timer

def countdown_timer(time, start_position=(330, 100)):
    turtle.pensize(5)
    turtle.speed(50)
    drawDate(time, start_position)

作用:

  • 用于触发倒计时显示。

思维:

  • 控制Turtle的画笔粗细和速度,调用drawDate进行倒计时数字的显示。

主循环

# 主循环
t = turtle.Turtle()
t.hideturtle()
width = 500
height = 200
turtle.setup(width, height)
turtle.setworldcoordinates(0, 0, width, height)
num_lines = 4
line_spacing = width / (num_lines + 1)
t.speed(100)

for i in range(1, num_lines + 1):
    x = i * line_spacing
    t.penup()
    t.goto(x, 0)
    t.pendown()
    t.left(90)
    t.forward(height)
    t.right(90)

traffic_light_radius = 30
rbb()
turtle.mainloop()

作用:

  • 设置Turtle画布和坐标系。
  • 绘制交叉口的道路线。
  • 调用最初的交通灯状态函数。

思维:

  • 利用循环绘制道路线。

  • 通过Turtle模块的坐标系设置,确定交叉口的位置。

完整代码

import turtle
import time

def draw_traffic_light(x, y, radius, color, label):
    t.penup()
    t.goto(x, y - radius)  # 移动到圆心位置
    t.pendown()
    t.speed(50)
    
    # 画圆
    t.color("black", color)
    t.begin_fill()
    t.circle(radius)
    t.end_fill()
    
    # 添加文字说明
    t.penup()
    t.goto(x, y - radius - 20)  # 调整文字位置
    t.pendown()
    t.write(label, align="center", font=("Arial", 10, "normal"))

# 定义rbb函数,用于绘制交通灯
def rbb():
    # 绘制红色交通灯,位置为(50, 100),半径为traffic_light_radius,状态为"红灯禁止通行"
    draw_traffic_light(50, 100, traffic_light_radius, "red", "红灯禁止通行")
    # 绘制灰色交通灯,位置为(150, 100),半径为traffic_light_radius,状态为""
    draw_traffic_light(150, 100, traffic_light_radius, "gray", "")
    # 绘制灰色交通灯,位置为(250, 100),半径为traffic_light_radius,状态为""
    draw_traffic_light(250, 100, traffic_light_radius, "gray", "")
    # 调用countdown_timer函数,等待5秒
    countdown_timer(5)
    # 调用byb函数
    byb()
    # 调用bbg函数
    bbg()

# 定义byb函数,用于绘制交通灯
def byb():
    # 绘制灰色交通灯,位置为(50, 100),半径为traffic_light_radius,状态为""
    draw_traffic_light(50, 100, traffic_light_radius, "gray", "")
    # 绘制黄色交通灯,位置为(150, 100),半径为traffic_light_radius,状态为"黄灯请等待"
    draw_traffic_light(150, 100, traffic_light_radius, "yellow", "黄灯请等待")
    # 绘制灰色交通灯,位置为(250, 100),半径为traffic_light_radius,状态为""
    draw_traffic_light(250, 100, traffic_light_radius, "gray", "")
    # 调用countdown_timer函数,等待3秒
    countdown_timer(3)

# 定义bbg函数,用于绘制交通灯
def bbg():
    # 绘制灰色交通灯,位置为(50, 100),半径为traffic_light_radius,状态为""
    draw_traffic_light(50, 100, traffic_light_radius, "gray", "")
    # 绘制灰色交通灯,位置为(150, 100),半径为traffic_light_radius,状态为""
    draw_traffic_light(150, 100, traffic_light_radius, "gray", "")
    # 绘制绿色交通灯,位置为(250, 100),半径为traffic_light_radius,状态为"绿灯可以通行"
    draw_traffic_light(250, 100, traffic_light_radius, "green", "绿灯可以通行")
    # 调用countdown_timer函数,等待5秒
    countdown_timer(5)
    # 调用byb函数
    byb()
    # 调用rbb函数
    rbb()

def drawGap():
    turtle.penup()
    turtle.fd(5)

def drawLine(draw):
    drawGap()
    turtle.pendown() if draw else turtle.penup()
    turtle.fd(40)
    drawGap()
    turtle.right(90)

def drawDigits(digit):
    drawLine(True) if digit in [2, 3, 4, 5, 6, 8, 9] else drawLine(False)
    drawLine(True) if digit in [0, 1, 3, 4, 5, 6, 7, 8, 9] else drawLine(False)
    drawLine(True) if digit in [0, 2, 3, 5, 6, 8, 9] else drawLine(False)
    drawLine(True) if digit in [0, 2, 6, 8] else drawLine(False)
    turtle.left(90)
    drawLine(True) if digit in [0, 4, 5, 6, 8, 9] else drawLine(False)
    drawLine(True) if digit in [0, 2, 3, 5, 6, 7, 8, 9] else drawLine(False)
    drawLine(True) if digit in [0, 1, 2, 3, 4, 7, 8, 9] else drawLine(False)
    turtle.left(180)
    turtle.penup()
    turtle.fd(15)

# 定义一个函数,用于绘制日期,参数date为日期,start_position为日期位置,默认为(330, 100)
def drawDate(date, start_position=(330, 100)):
    # 抬起画笔
    turtle.penup()
    # 移动画笔到指定位置
    turtle.goto(start_position)
    # 设置画笔颜色
    turtle.pencolor("red")
    # 从日期开始,从后往前遍历,直到0
    for i in reversed(range(date + 1)):
        # 将日期转换为字符串
        num = str(i)
        # 遍历字符串中的每一个数字
        for n in num:
            # 调用drawDigits函数绘制数字
            drawDigits(eval(n))
            # 抬起画笔
            turtle.penup()
            # 向后移动40像素
            turtle.forward(40)
        # 清除画布
        turtle.clear()
        # 抬起画笔
        turtle.penup()
        # 移动画笔到指定位置
        turtle.goto(start_position)

# 定义一个函数countdown_timer,参数time和start_position,time为时间,start_position为坐标
def countdown_timer(time, start_position=(330, 100)):
    # 设置画笔宽度
    turtle.pensize(5)
    # 设置画笔速度
    turtle.speed(50)
    # 调用drawDate函数,参数time和start_position
    drawDate(time, start_position)

# 创建一个Turtle对象
t = turtle.Turtle()
# 隐藏Turtle对象
t.hideturtle()
# 设置画布宽度
width = 500
# 设置画布高度
height = 200
# 设置画布大小
turtle.setup(width, height)
# 设置画布坐标系
turtle.setworldcoordinates(0, 0, width, height)
# 设置画布行数
num_lines = 4
# 计算每行之间的间距
line_spacing = width / (num_lines + 1)
# 设置画笔速度
t.speed(2)

# 循环画线
for i in range(1, num_lines + 1):
    # 计算每行x坐标
    x = i * line_spacing
    # 画笔抬起
    t.penup()
    # 移动画笔到x坐标
    t.goto(x, 0)
    # 画笔落下
    t.pendown()
    # 画笔左转90度
    t.left(90)
    # 画笔向前移动画布高度
    t.forward(height)
    # 画笔右转90度
    t.right(90)

traffic_light_radius = 30
rbb()
turtle.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hewei2723

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值