前言
交通信号灯十字路口通行原理图。
实际上归类为四大类:
- 南北双向直行
- 东西双向直行
- 一对黑色粗线的左转
- 一对红色粗线的左转。
状态逻辑图如下图所示:
- 假定通行顺序为:南北直行、南北左转、东西直行、东西左转。
- 南北行人只在南北车流绿灯和黄灯的时候可以通行,东西人行同理。
- 假设绿灯25s,黄灯5s,这二者决定红灯的时间。
- 四大类方向30s切换一次,总共循环为120s。
- 南北、东西行人通行时间一次循环内分别为30s。
一、运行效果
- 点击开始:
进入120s的整个循环中,第一部分南北直行绿灯在25s后变为黄灯持续5s,然后为红灯;第二部分南北左转灯对应变为绿灯并进行倒计时,然后黄灯,红灯;第三部分就是东西直行的绿灯黄灯红灯,第四部分是东西左转的绿黄红切换。
- 南北向、东西向行人在对应的时间切换绿灯和红灯。
- 停止按钮,停止计数器的计时。
- 思路:1秒的定时器计算时间,到了对应的时间阶段,触发界面的状态变化和倒计时。详情见代码。
二、界面设计
控件和命名图片中标出了同系列的第一个,其余的根据方向类推命名。
三、代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace TrafficLight
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int time = 0;//计时器
const int MAX_LOOP_TIME = 120;//120s时间为一次循环
//以下时间段分别为:南北直行绿灯25,南北直行黄灯5,南北左转绿灯25,南北左转黄灯5,东西直行绿灯25,东西直行黄灯5,东西左转绿灯25,东西左转黄灯5
int[] PassTime={25, 30, 55, 60, 85, 90, 115, 120};
//事件委托的方式触发
public delegate void delegateTrafficLight(int tm);
public event delegateTrafficLight EventTrafficLight;
private void btnStart_Click(object sender, EventArgs e)
{
timer1.Start();
//Thread threadLightChg = new Thread(LightChange);
//threadLightChg.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void timer1_Tick(object sender, EventArgs e)
{
//计时开始,进入循环,120s为一次循环
if (time < MAX_LOOP_TIME - 1) //119秒后置为0秒
{
time += 1;
if (EventTrafficLight != null)
{
EventTrafficLight(time);
}
}
else
{
time = 0;
if (EventTrafficLight != null)
{
EventTrafficLight(time);
}
txtStoN.Clear();
txtNtoS.Clear();
txtWtoE.Clear();
txtEtoW.Clear();
}
}
private void Form1_Load(object sender, EventArgs e)
{
this.EventTrafficLight += new delegateTrafficLight(LightChange);
}
public void LightChange(int time)
{
if (time < PassTime[0])
{
lbStoNStraight.BackColor = Color.Green;
lbStoNLeft.BackColor = Color.Red;
lbNtoSStraight.BackColor = Color.Green;
lbNtoSLeft.BackColor = Color.Red;
lbWtoEStraight.BackColor = Color.Red;
lbWtoELeft.BackColor = Color.Red;
lbEtoWStraight.BackColor = Color.Red;
lbEtoWLeft.BackColor = Color.Red;
lbPeopleNS1.BackColor = Color.Green;
lbPeopleNS2.BackColor = Color.Green;
lbPeopleNS3.BackColor = Color.Green;
lbPeopleNS4.BackColor = Color.Green;
lbPeopleWE1.BackColor = Color.Red;
lbPeopleWE2.BackColor = Color.Red;
lbPeopleWE3.BackColor = Color.Red;
lbPeopleWE4.BackColor = Color.Red;
//倒计时
txtStoN.Text = (PassTime[0] - time).ToString();
txtNtoS.Text = (PassTime[0] - time).ToString();
}
else if (time >= PassTime[0] && time < PassTime[1])
{
lbStoNStraight.BackColor = Color.Yellow;
lbStoNLeft.BackColor = Color.Red;
lbNtoSStraight.BackColor = Color.Yellow;
lbNtoSLeft.BackColor = Color.Red;
lbWtoEStraight.BackColor = Color.Red;
lbWtoELeft.BackColor = Color.Red;
lbEtoWStraight.BackColor = Color.Red;
lbEtoWLeft.BackColor = Color.Red;
lbPeopleNS1.BackColor = Color.Green;
lbPeopleNS2.BackColor = Color.Green;
lbPeopleNS3.BackColor = Color.Green;
lbPeopleNS4.BackColor = Color.Green;
lbPeopleWE1.BackColor = Color.Red;
lbPeopleWE2.BackColor = Color.Red;
lbPeopleWE3.BackColor = Color.Red;
lbPeopleWE4.BackColor = Color.Red;
//倒计时
txtStoN.Text = (PassTime[1] - time - 1).ToString();
txtNtoS.Text = (PassTime[1] - time - 1).ToString();
}
else if (time >= PassTime[1] && time < PassTime[2])
{
lbStoNStraight.BackColor = Color.Red;
lbStoNLeft.BackColor = Color.Green;
lbNtoSStraight.BackColor = Color.Red;
lbNtoSLeft.BackColor = Color.Green;
lbWtoEStraight.BackColor = Color.Red;
lbWtoELeft.BackColor = Color.Red;
lbEtoWStraight.BackColor = Color.Red;
lbEtoWLeft.BackColor = Color.Red;
lbPeopleNS1.BackColor = Color.Red;
lbPeopleNS2.BackColor = Color.Red;
lbPeopleNS3.BackColor = Color.Red;
lbPeopleNS4.BackColor = Color.Red;
lbPeopleWE1.BackColor = Color.Red;
lbPeopleWE2.BackColor = Color.Red;
lbPeopleWE3.BackColor = Color.Red;
lbPeopleWE4.BackColor = Color.Red;
//倒计时
txtStoN.Text = (PassTime[2] - time - 1).ToString();
txtNtoS.Text = (PassTime[2] - time - 1).ToString();
}
else if (time >= PassTime[2] && time < PassTime[3])
{
lbStoNStraight.BackColor = Color.Red;
lbStoNLeft.BackColor = Color.Yellow;
lbNtoSStraight.BackColor = Color.Red;
lbNtoSLeft.BackColor = Color.Yellow;
lbWtoEStraight.BackColor = Color.Red;
lbWtoELeft.BackColor = Color.Red;
lbEtoWStraight.BackColor = Color.Red;
lbEtoWLeft.BackColor = Color.Red;
lbPeopleNS1.BackColor = Color.Red;
lbPeopleNS2.BackColor = Color.Red;
lbPeopleNS3.BackColor = Color.Red;
lbPeopleNS4.BackColor = Color.Red;
lbPeopleWE1.BackColor = Color.Red;
lbPeopleWE2.BackColor = Color.Red;
lbPeopleWE3.BackColor = Color.Red;
lbPeopleWE4.BackColor = Color.Red;
//倒计时
txtStoN.Text = (PassTime[3] - time - 1).ToString();
txtNtoS.Text = (PassTime[3] - time - 1).ToString();
}
else if (time >= PassTime[3] && time < PassTime[4])
{
lbStoNStraight.BackColor = Color.Red;
lbStoNLeft.BackColor = Color.Red;
lbNtoSStraight.BackColor = Color.Red;
lbNtoSLeft.BackColor = Color.Red;
lbWtoEStraight.BackColor = Color.Green;
lbWtoELeft.BackColor = Color.Red;
lbEtoWStraight.BackColor = Color.Green;
lbEtoWLeft.BackColor = Color.Red;
lbPeopleNS1.BackColor = Color.Red;
lbPeopleNS2.BackColor = Color.Red;
lbPeopleNS3.BackColor = Color.Red;
lbPeopleNS4.BackColor = Color.Red;
lbPeopleWE1.BackColor = Color.Green;
lbPeopleWE2.BackColor = Color.Green;
lbPeopleWE3.BackColor = Color.Green;
lbPeopleWE4.BackColor = Color.Green;
//倒计时
txtWtoE.Text = (PassTime[4] - time - 1).ToString();
txtEtoW.Text = (PassTime[4] - time - 1).ToString();
}
else if (time >= PassTime[4] && time < PassTime[5])
{
lbStoNStraight.BackColor = Color.Red;
lbStoNLeft.BackColor = Color.Red;
lbNtoSStraight.BackColor = Color.Red;
lbNtoSLeft.BackColor = Color.Red;
lbWtoEStraight.BackColor = Color.Yellow;
lbWtoELeft.BackColor = Color.Red;
lbEtoWStraight.BackColor = Color.Yellow;
lbEtoWLeft.BackColor = Color.Red;
lbPeopleNS1.BackColor = Color.Red;
lbPeopleNS2.BackColor = Color.Red;
lbPeopleNS3.BackColor = Color.Red;
lbPeopleNS4.BackColor = Color.Red;
lbPeopleWE1.BackColor = Color.Green;
lbPeopleWE2.BackColor = Color.Green;
lbPeopleWE3.BackColor = Color.Green;
lbPeopleWE4.BackColor = Color.Green;
//倒计时
txtWtoE.Text = (PassTime[5] - time - 1).ToString();
txtEtoW.Text = (PassTime[5] - time - 1).ToString();
}
else if (time >= PassTime[5] && time < PassTime[6])
{
lbStoNStraight.BackColor = Color.Red;
lbStoNLeft.BackColor = Color.Red;
lbNtoSStraight.BackColor = Color.Red;
lbNtoSLeft.BackColor = Color.Red;
lbWtoEStraight.BackColor = Color.Red;
lbWtoELeft.BackColor = Color.Green;
lbEtoWStraight.BackColor = Color.Red;
lbEtoWLeft.BackColor = Color.Green;
lbPeopleNS1.BackColor = Color.Red;
lbPeopleNS2.BackColor = Color.Red;
lbPeopleNS3.BackColor = Color.Red;
lbPeopleNS4.BackColor = Color.Red;
lbPeopleWE1.BackColor = Color.Red;
lbPeopleWE2.BackColor = Color.Red;
lbPeopleWE3.BackColor = Color.Red;
lbPeopleWE4.BackColor = Color.Red;
//倒计时
txtWtoE.Text = (PassTime[6] - time - 1).ToString();
txtEtoW.Text = (PassTime[6] - time - 1).ToString();
}
else if (time >= PassTime[6])
{
lbStoNStraight.BackColor = Color.Red;
lbStoNLeft.BackColor = Color.Red;
lbNtoSStraight.BackColor = Color.Red;
lbNtoSLeft.BackColor = Color.Red;
lbWtoEStraight.BackColor = Color.Red;
lbWtoELeft.BackColor = Color.Yellow;
lbEtoWStraight.BackColor = Color.Red;
lbEtoWLeft.BackColor = Color.Yellow;
lbPeopleNS1.BackColor = Color.Red;
lbPeopleNS2.BackColor = Color.Red;
lbPeopleNS3.BackColor = Color.Red;
lbPeopleNS4.BackColor = Color.Red;
lbPeopleWE1.BackColor = Color.Red;
lbPeopleWE2.BackColor = Color.Red;
lbPeopleWE3.BackColor = Color.Red;
lbPeopleWE4.BackColor = Color.Red;
//倒计时
txtWtoE.Text = (MAX_LOOP_TIME - time - 1).ToString();
txtEtoW.Text = (MAX_LOOP_TIME - time - 1).ToString();
}
}
}
}
总结
重在理解交通信号灯的原理。
代码重点:
- 使用了定时器
- 使用了委托事件的触发方式
- 对常量和公共数组的应用
- 变量命名规范、代码整洁