项目的要求很简单:

  模拟出十字路口的交通控制情况;

  考虑东、西、南、北四个方向,每条路分为两个车道,每个路口设置一盏显示灯。为简单起见, 每种灯显示时间为8秒。

  当东西(或南北)方向红灯时,所有车辆(除了消防车、救护车、警车)均排队等待,当东西(或南北)方向绿灯时,所有车辆按序行驶(不准超车)。

制作这个小框体程序我选择的平台是JAVA,实现结果效果图如下所示:

  首先分析整个项目题目上的要求,在十字路口上通过的车辆可以抽象为两类:普通车辆和特殊车辆(包括警车,消防车,救护车等),所谓普通的车辆和特殊种类的车辆之间的差别是是否需要在红绿灯路口之前进行等待操作,特殊车辆享有优先权并且可以直接通过路口,而普通的车辆必须严格遵守交通规则。

由于整个题目的环境假定为交通十字路口,那么有如下几个隐式的条件要求:

(1)不失一般性的,任意车辆在前方有车辆在等待的情况下必须也进行等待操作。

(2)车辆与车辆之间无论是正面还是侧面之间都不允许发生碰撞且最好保持一个“安全距离”,换句话讲,一个严格的要求是车辆之间不允许发生重叠。

(3)红绿灯按照一个既定的规律进行变换,控制普通车辆的行进与停止

(4)车辆的次序或者方向要实现随机分配,即整个路口可以处理各种车辆位置的情况

在这个项目之中我们不妨假设车辆的行进路径只有单方向,即不会出现车辆转弯的状况,这样一来就大大简化了整个项目的难度。所以因为所有车辆都是直行,所以在整个十字路口的范围内我们需要一定数量的信号来处理路口内部车辆行进的分配问题,其次是红绿灯的分配也需要一个信号量来处理车辆和红绿灯变换之间的关系。

如右图所示,MyMutex.center是表示整个十字路口正中央的信号辆所代表的位置,东西南北是个方向分别在这个信号量表示中为上下左右四个方向,每个方向有4条道路,其中的道路两两并行,每组方向相反。举个具体的例子就是(车辆靠右侧通行)北(上)边最右侧的车道驶来的车辆与西(左)边最左侧的车道驶来的车辆可能会在图中的MyMutex.center[0][0]处相遇,在相遇的同时只有一辆车辆允许通行,若已经有车辆通过该交汇处,那么已经进入并且占有信号量的车

辆优先通过,反之亦然。

在上述的条件的约束之下,我们决定使用可视化界面来实现整个十字路口车辆分配的问题。

不妨把车辆抽象成为矩形,利用java.awt库下的类做出两个模拟的车辆的模样,分别代表特殊车辆和普通车辆。(特殊车辆一律用警车图案来概括)

那么车辆行驶的过程就是车辆图案的平移过程,经过草图设计我们暂定车辆LOGO的大小为30*50(道路的宽度为50)也就是说会在车辆的两侧个留出10pixel的矩形作为所谓安全距离,整个车辆的平移的过程经过测试评估最终确定为每0.2s移动10像素,会留下较好的动画效果和观察准度。

接下来是实现整个界面底层的环节:

(1)所有车辆模型的实质是java.awt库内的矩形和线条,车辆模型的移动的实质就是线条和矩形的移动过程,但是在移动的过程之中,首先需要图案进行旋转处理以使之对应东西走向上的车辆,为了避免反复重复计算出每个线条的位置,我们做出8个容器来存储每个方向上每个车道上的车辆初始线条位置,从次之后的每次绘制只需要在容器中取出每个线条再对之进行比较简单的平移操作即可。

(2)我们整个界面的动画是通过不断调用JComponent类的repaint()方法来实现的,所以我们首先需要重写paint()方法,从P/V操作的角度考虑,对于每一条路径上的车辆可能会处理的情况如下所示:

(3)整个界面的宏观角度来看,整个程序的流程过程图如下所示:

(4)根据上述设计,个人感觉java中的synchronized关键字不太适合这个项目,因为直接使用synchronized很有使得两个同时相碰的车辆发生死锁现象,所以我的解决方法是根据java代码执行的特点,将八个线程的运行run() 函数内容直接依次排序,实质上是相当于给八个线程设定了默认的优先级这样一来就解决了死锁的现象。

代码分享: ## 由于作业Deadline还没有到我就先发布一些关键的绘制部分的代码块,等到Deadline一过就把源码全部展示出来 ##

(1)paint()函数重载后的写法

    public void paint(Graphics g){
super.paint(g);
Graphics2D g2=(Graphics2D)g;
/////Traffic Lights
g2.setPaint(Color.black);
g2.fill(signalpane);
g2.setPaint(Color.red.darker());
g2.fill(redsignal);
g2.setPaint(Color.green.darker());
g2.fill(greensignal); /////PaintRoad
g2.setPaint(Color.gray.brighter());
Rectangle2D roadh=new Rectangle2D.Float(250,0,200,700);
Rectangle2D roadv=new Rectangle2D.Float(0,250,700,200);
g2.fill(roadh);
g2.fill(roadv); ///// /////Graphics Defination
g2.setPaint(Color.black);
g.drawLine(250, 0, 250, 700);
g.drawLine(350, 0, 350, 700);
g.drawLine(450, 0, 450, 700);
g.drawLine(0, 250, 700, 250);
g.drawLine(0, 350, 700, 350);
g.drawLine(0,450,700, 450);
g2.setPaint(Color.gray.darker());
g.drawLine(300,0,300,700);
g.drawLine(400,0,400,700);
g.drawLine(0,300,700,300);
g.drawLine(0,400,700,400);
Rectangle2D centerroad=new Rectangle2D.Float(250,250,200,200);
///////////////////////Road Drawing
///////////////////////Color can be attached
g2.setPaint(Color.gray.brighter());
g2.fill(centerroad);
g2.setPaint(Color.black);
g2.draw(centerroad);
////////////////////////Specail Car Outline painting
////////////////////////Located from 500,20 size 30,50
///////////////////////Combined by llright,rlight,specialCarOut,specialCarIn,specialCarLightLeft,specialCarLightRight
g2.fill(specialCarOut);
g2.setPaint(Color.gray);
g2.draw(specialCarLightLeft);
g2.draw(specialCarLightRight);
g2.draw(specialCarOut);
g2.setPaint(Color.white);
g2.fill(specialCarIn);
g2.setPaint(Color.red);
g2.fill(specialCarLightLeft);
g2.setPaint(Color.blue);
g2.fill(specialCarLightRight);
g2.setPaint(Color.yellow);
g2.fill(sllight);
g2.fill(srlight);
//////////////////////////////////////Normal Car Outline Painting
//////////////////////////////////////Located from 550,20 size 30,50 g2.setPaint(Color.gray);
g2.draw(normalCarIn);
g2.draw(normalCarOut);
g2.setPaint(Color.red);
g2.fill(normalCarOut);
g2.setPaint(Color.magenta);
g2.fill(normalCarIn);
g2.setPaint(Color.yellow);
g2.fill(nllight);
g2.fill(nrlight);
//////////////////
/////////////////Painting Finished
/////////////////For switch to change
if(bLight==true){
g2.setPaint(Color.green.brighter());
g2.fill(greensignal);
g2.setPaint(Color.black);
g2.fill(redsignal);
}else{
g2.setPaint(Color.black);
g2.fill(greensignal);
g2.setPaint(Color.red.brighter());
g2.fill(redsignal);
} ////Testing Field ////nn
Iterator iter=northCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////sn
iter=snorthCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////ns
iter=southCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////ss
iter=ssouthCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
///ne
iter=eastCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////se
iter=seastCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
/////nw
iter=westCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
////sw
iter=swestCars.iterator();
while(iter.hasNext()){
Car c=(Car)iter.next();
paintCar(g2,c);
}
///////////////////Testtttting!!!!!! ///////////////////
}

(2)线条/图案容器

public static Vector<Car> northCars=new Vector<>();
public static Vector<Car> southCars=new Vector<>();
public static Vector<Car> eastCars=new Vector<>();
public static Vector<Car> westCars=new Vector<>();
public static Vector<Car> snorthCars=new Vector<>();
public static Vector<Car> ssouthCars=new Vector<>();
public static Vector<Car> seastCars=new Vector<>();
public static Vector<Car> swestCars=new Vector<>();
public static boolean bLight=true;

(3)车辆坐标容器

    protected static Vector<Shape> northshape=new Vector<>();
protected static Vector<Shape> southshape=new Vector<>();
protected static Vector<Shape> eastshape=new Vector<>();
protected static Vector<Shape> westshape=new Vector<>();
protected static Vector<Shape> snorthshape=new Vector<>();
protected static Vector<Shape> ssouthshape=new Vector<>();
protected static Vector<Shape> seastshape=new Vector<>();
protected static Vector<Shape> swestshape=new Vector<>();

(4)actionPerformed接口方法实现

    public void actionPerformed(ActionEvent e){
Object source=e.getSource();
if(source==timer){
Iterator it;
////nn
it=northCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==700)it.remove();
if(car.y==250){
if(bLight==true)continue;///Stop
//}else if(car.y==250){
if(MyMutex.center[0][0]==0)MyMutex.center[0][0]--;else continue;///Stop
}else if(car.y==340){
MyMutex.center[0][0]++;
}else if(car.y==300){
if(MyMutex.center[1][0]==0)MyMutex.center[1][0]--;else continue;///Stop
}else if(car.y==390){
MyMutex.center[1][0]++;
}else if(car.y==350){
if(MyMutex.center[2][0]==0)MyMutex.center[2][0]--;else continue;
}else if(car.y==440){
MyMutex.center[2][0]++;
}else if(car.y==400){
if(MyMutex.center[3][0]==0)MyMutex.center[3][0]--;else continue;
}else if(car.y==490){
MyMutex.center[3][0]++;
}
car.y+=10;
}
///////ns
it=snorthCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==700)it.remove();
if(car.y==250){
//if(bLight==true)continue;///Stop
//}else if(car.y==250){
if(MyMutex.center[0][1]==0)MyMutex.center[0][1]--;else continue;///Stop
}else if(car.y==340){
MyMutex.center[0][1]++;
}else if(car.y==300){
if(MyMutex.center[1][1]==0)MyMutex.center[1][1]--;else continue;///Stop
}else if(car.y==390){
MyMutex.center[1][1]++;
}else if(car.y==350){
if(MyMutex.center[2][1]==0)MyMutex.center[2][1]--;else continue;
}else if(car.y==440){
MyMutex.center[2][1]++;
}else if(car.y==400){
if(MyMutex.center[3][1]==0)MyMutex.center[3][1]--;else continue;
}else if(car.y==490){
MyMutex.center[3][1]++;
}
car.y+=10;
}
/////sn
it=southCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==0)it.remove();
if(car.y==450){
if(bLight==true)continue;///Stop
//}else if(car.y==450){
if(MyMutex.center[3][3]==0)MyMutex.center[3][3]--;else continue;///Stop
}else if(car.y==360){
MyMutex.center[3][3]++;
}else if(car.y==400){
if(MyMutex.center[2][3]==0)MyMutex.center[2][3]--;else continue;///Stop
}else if(car.y==310){
MyMutex.center[2][3]++;
}else if(car.y==350){
if(MyMutex.center[1][3]==0)MyMutex.center[1][3]--;else continue;
}else if(car.y==260){
MyMutex.center[1][3]++;
}else if(car.y==300){
if(MyMutex.center[0][3]==0)MyMutex.center[0][3]--;else continue;
}else if(car.y==210){
MyMutex.center[0][3]++;
}
car.y-=10;
}
////ss
it=ssouthCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.y==0)it.remove();
if(car.y==450){
//if(bLight==true)continue;///Stop
//}else if(car.y==450){
if(MyMutex.center[3][2]==0)MyMutex.center[3][2]--;else continue;///Stop
}else if(car.y==360){
MyMutex.center[3][2]++;
}else if(car.y==400){
if(MyMutex.center[2][2]==0)MyMutex.center[2][2]--;else continue;///Stop
}else if(car.y==310){
MyMutex.center[2][2]++;
}else if(car.y==350){
if(MyMutex.center[1][2]==0)MyMutex.center[1][2]--;else continue;
}else if(car.y==260){
MyMutex.center[1][2]++;
}else if(car.y==300){
if(MyMutex.center[0][2]==0)MyMutex.center[0][2]--;else continue;
}else if(car.y==210){
MyMutex.center[0][2]++;
}
car.y-=10;
}
///ne
it=eastCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==0)it.remove();
if(car.x==450){
if(bLight==false)continue;///Stop
//}else if(car.x==450){
if(MyMutex.center[0][3]==0)MyMutex.center[0][3]--;else continue;///Stop
}else if(car.x==360){
MyMutex.center[0][3]++;
}else if(car.x==400){
if(MyMutex.center[0][2]==0)MyMutex.center[0][2]--;else continue;///Stop
}else if(car.x==310){
MyMutex.center[0][2]++;
}else if(car.x==350){
if(MyMutex.center[0][1]==0)MyMutex.center[0][1]--;else continue;
}else if(car.x==260){
MyMutex.center[0][1]++;
}else if(car.x==300){
if(MyMutex.center[0][0]==0)MyMutex.center[0][0]--;else continue;
}else if(car.x==210){
MyMutex.center[0][0]++;
}
car.x-=10;
}
//se
it=seastCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==0)it.remove();
if(car.x==450){
//if(bLight==false)continue;///Stop
//}else if(car.x==450){
if(MyMutex.center[1][3]==0)MyMutex.center[1][3]--;else continue;///Stop
}else if(car.x==360){
MyMutex.center[1][3]++;
}else if(car.x==400){
if(MyMutex.center[1][2]==0)MyMutex.center[1][2]--;else continue;///Stop
}else if(car.x==310){
MyMutex.center[1][2]++;
}else if(car.x==350){
if(MyMutex.center[1][1]==0)MyMutex.center[1][1]--;else continue;
}else if(car.x==260){
MyMutex.center[1][1]++;
}else if(car.x==300){
if(MyMutex.center[1][0]==0)MyMutex.center[1][0]--;else continue;
}else if(car.x==210){
MyMutex.center[1][0]++;
}
car.x-=10;
}
//nw
it=westCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==700)it.remove();
if(car.x==250){
if(bLight==false)continue;///Stop
//}else if(car.x==250){
if(MyMutex.center[3][0]==0)MyMutex.center[3][0]--;else continue;///Stop
}else if(car.x==340){
MyMutex.center[3][0]++;
}else if(car.x==300){
if(MyMutex.center[3][1]==0)MyMutex.center[3][1]--;else continue;///Stop
}else if(car.x==390){
MyMutex.center[3][1]++;
}else if(car.x==350){
if(MyMutex.center[3][2]==0)MyMutex.center[3][2]--;else continue;
}else if(car.x==440){
MyMutex.center[3][2]++;
}else if(car.x==400){
if(MyMutex.center[3][3]==0)MyMutex.center[3][3]--;else continue;
}else if(car.x==490){
MyMutex.center[3][3]++;
}
car.x+=10;
}
///sw
it=swestCars.iterator();
while(it.hasNext()){
Car car=(Car)it.next();
if(car.x==700)it.remove();
if(car.x==250){
//if(bLight==false)continue;///Stop
//}else if(car.x==250){
if(MyMutex.center[2][0]==0)MyMutex.center[2][0]--;else continue;///Stop
}else if(car.x==340){
MyMutex.center[2][0]++;
}else if(car.x==300){
if(MyMutex.center[2][1]==0)MyMutex.center[2][1]--;else continue;///Stop
}else if(car.x==390){
MyMutex.center[2][1]++;
}else if(car.x==350){
if(MyMutex.center[2][2]==0)MyMutex.center[2][2]--;else continue;
}else if(car.x==440){
MyMutex.center[2][2]++;
}else if(car.x==400){
if(MyMutex.center[2][3]==0)MyMutex.center[2][3]--;else continue;
}else if(car.x==490){
MyMutex.center[2][3]++;
}
car.x+=10;
}
adjust();
repaint();
}else if(source==timerLight){
bLight=!bLight;
if(bLight)hint.setText("Now Right-Left Road is Accessible!");
else hint.setText("Now Up-Down Road is Accessible!");
}else if(source==testTimer){
//northCars.add(new Car(0,0,260,50));
//snorthCars.add(new Car(0,1,310,50));
//southCars.add(new Car(1,0,440,650));
//ssouthCars.add(new Car(1,1,410,650));
//eastCars.add(new Car(2,0,650,260));
//seastCars.add(new Car(2,1,650,310));
//westCars.add(new Car(3,0,50,440));
//swestCars.add(new Car(3,1,50,410));
}else if(source==westn){
westCars.add(new Car(3,0,50,440));
}else if(source==wests){
swestCars.add(new Car(3,1,50,410));
}else if(source==eastn){
eastCars.add(new Car(2,0,650,260));
}else if(source==easts){
seastCars.add(new Car(2,1,650,310));
}else if(source==northn){
northCars.add(new Car(0,0,260,50));
}else if(source==norths){
snorthCars.add(new Car(0,1,310,50));
}else if(source==southn){
southCars.add(new Car(1,0,440,650));
}else if(source==souths){
ssouthCars.add(new Car(1,1,410,650));
} /////Swtich Table For Source Handling }

Tips:如果有任何问题欢迎联系我或者留下评论

<JAVA图像学习笔记>十字路口交通模拟--操作系统模拟课后小项目的更多相关文章

  1. <JAVA图像学习笔记>关于Graphics/Graphics2D以及简单的几何图像制作(一个简单钟表的实现)

    题外话:正好赶上OperatingSystem的作业要做一个模拟线程/进程调度的问题,决定用JAVA实现才发现这些内容和之前学过的GUI制作是两码事儿- -b 通过学习java.swing库的Acti ...

  2. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  4. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  5. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  6. Android(java)学习笔记233: 远程服务的应用场景(移动支付案例)

    一. 移动支付:       用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...

  7. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  8. Android(java)学习笔记176: 远程服务的应用场景(移动支付案例)

    一. 移动支付:       用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...

  9. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

随机推荐

  1. Project Euler:Problem 89 Roman numerals

    For a number written in Roman numerals to be considered valid there are basic rules which must be fo ...

  2. 知其一不知其二之Jenkins Hacking

    转自安全脉搏 本文首发安全脉搏 感谢大王叫我来巡山 的投递 转载请注明来源 大多安全工作者听到jenkins都会知道有个未授权的命令执行 但是如果Script页面要授权才能访问呢 或者你的用户没有Ov ...

  3. ext tree展开时的一些技巧

    加入子节点的时候.我们须要展开父节点.并选中刚加入好的节点. 这时候会有一个问题. 我用的ext-js-4.2起码有一种问题. 节点内部会混乱.要么多加一个. 要么层级会发生故障. 随后我发现一个窍门 ...

  4. TCP/IP详解 卷一(第四、五章 ARP、RARP)

    数据链路如 以太网都有自己的寻址机制(MAC)地址,而IP层使用的是IP地址. 当一台主机把以太网数据发送定位于同一局域网上的另一台主机时,是根据MAC地址来确定目的接口的.设备驱动程序从不检查IP数 ...

  5. 解析iscroll-小demo

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  6. Html5 播放Hls格式视频

    二群号为766718184 ,博主提供Ffmpeg.GB28181视频教程 播放地址: http://www.iqiyi.com/u/1426749687  移动端Html5支持Hls格式视频播放,创 ...

  7. node.js ----NPM使用介绍

    NPM 使用介绍 NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从 ...

  8. Cocoapods完整使用篇

    温馨提示:在篇文章中所使用的Xcode版本为Xcode7.   一.什么是CocoaPods? 简单来说,就是专门为iOS工程提供对第三方库的依赖的管理工具,通过CocoaPods,我们可以单独管理每 ...

  9. mysql日期格式转化

    select DATE_FORMAT( '20170701', '%Y-%m-%d'); 先挖坑

  10. JVM完全指南

    JVM完全指南     一:虚拟机内存图解   JAVA程序运行与虚拟机之上,运行时需要内存空间.虚拟机执行JAVA程序的过程中会把它管理的内存划分为不同的数据区域方便管理.     虚拟机管理内存数 ...