标签:
运行界面:
1.进入:
在进入菜单里我们主要就是设计模拟电梯运动。
在每一层的上下按钮可以直接用button控件,显示的文字是楼层号;然后通过获取控件上的文本信息哪一层叫的电梯;
当点击电梯按钮时弹出一个窗体,这个窗体内是一些复选按钮,来表示选择了哪些楼层;
可以用一个控件来表示电梯,用button控件的位置的改变来表示电梯的运动。
界面如下:
2.总控台:
在总控台中设置电梯运动一层的时间,电梯的停留的时间等。
3.退出
就是退出了。。。
电梯具体实施:
根据和结对伙伴韩天中的讨论,我们决定如果电梯不工作时,1,4号电梯将分别停留在1和21层,而2,3号电梯将分别停留在10,11层这样可以尽量减少乘客的等待时间。电梯位置的初始化在窗体还未创建时完成,用窗体的Load事件,因为在一开始设计窗体时是将所有电梯的位置放在0层,所有电梯的当前楼层都是初始化为0,故要在事件中遍历所有的button控件,控件上的文字是“电梯1,“电梯2”,”电梯3“,”电梯4“的button控件的位置发生改变,用switch...case...语句来实现。具体代码如下
private void Bulding_Load(object sender, EventArgs e) { //将一号电梯初始化在一楼,二号电梯在10楼,三号电梯在11楼,四号电梯在20楼 foreach (Control oneCtr in this.Controls) { Button btnElevator = oneCtr as Button;//将control转换成checkbox if (btnElevator != null) { string btntext = btnElevator.Text; Point p = new Point(); switch (btntext) { case "电梯1": { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; currentFloor++; txtCurrentFloor.Text = (currentFloor).ToString(); break; } case "电梯2": { for (; currentFloor2 < 10; currentFloor2++) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; } txtCurrentFloor2.Text = (currentFloor2).ToString(); break; } case "电梯3": { for (; currentFloor3 < 11; currentFloor3++) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; } txtCurrentFloor3.Text = (currentFloor3).ToString(); break; } case "电梯4": { for (; currentFloor4 < 20; currentFloor4++) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; } txtCurrentFloor4.Text = (currentFloor4).ToString(); break; } } } } //取消跨线程访问 Control.CheckForIllegalCrossThreadCalls = false; }
在具体的写电梯运动程序时,主要分成两大部分。
电梯内部设置按钮,能使电梯到达相应的楼层
注:以下代码都以电梯1为例
private void elevator1Move(object sender) { elevatorIn(); Button btnElevator = sender as Button; Point p = new Point(); if (Elevator.selFloorNum>=1) { if (currentFloor < Elevator.selectFloors[Elevator.selFloorNum - 1]) { for (int j = Elevator.selFloorNum-1; j >=0; j--)//选择好的楼层 { for (; currentFloor < Elevator.selectFloors[j] ; currentFloor++)//形成运动效果 { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; txtCurrentFloor.Text = (currentFloor+1).ToString(); // txtCurrentFloor2.Text = upnum; Thread.CurrentThread.Join(1000); // Thread.Sleep(1000 * setInf.perFloorTime);//将当前线程挂起(1000ms),不然看不到运动 } clearcbx(currentFloor); Elevator.selFloorNum--; Elevator.selectFloors[j] = -10; Thread.CurrentThread.Join(4000); // Thread.Sleep(4000 * setInf.perFloorTime); } } if (currentFloor >= Elevator.selectFloors[0] && Elevator.selectFloors[0]!=-10) { while (Elevator.selFloorNum!=-1) { while (currentFloor > Elevator.selectFloors[0] && Elevator.selectFloors[0]!=-10) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y + btnElevator.Size.Height; btnElevator.Location = p; txtCurrentFloor.Text = (currentFloor - 1).ToString(); // txtCurrentFloor2.Text = upnum; Thread.CurrentThread.Join(1000); //Thread.Sleep(1000 * setInf.perFloorTime);//将当前线程挂起(1000ms),不然看不到运动 currentFloor--; } clearcbx_D(currentFloor); Elevator.selectFloors[Elevator.selFloorNum] = -10; Elevator.selFloorNum--; Thread.CurrentThread.Join(4000); // Thread.Sleep(4000 * setInf.perFloorTime); } } } } private void elevatorIn() { ele.Visible = false; ele.ShowDialog(); }
在电梯运动时为了不影响其他按键的使用,因此要为电梯的运动创建一个线程,创建线程的代码如下:
private void btnElevator_Click( object sender, EventArgs e) { //创建一个移动电梯的线程,, Thread thr = new Thread(new ParameterizedThreadStart(elevator1Move));//能够传进来一个参数 //Thread thr = new Thread(elevatorMove(sender)); thr.IsBackground = true;//设置为后台线程 thr.Start(sender); }
到达楼层后将按钮变为未选择
private void clearcbx_D(int currentFloor) { clearcbx(currentFloor); for(int i = 0;i<Elevator.selFloorNum;i++) { Elevator.selectFloors[i] = Elevator.selectFloors[i + 1]; } } private void clearcbx(int currentFloor ) { foreach (Control oneCtr in ele .Controls) { CheckBox ckb = oneCtr as CheckBox;//将control转换成checkbox if(ckb!=null) { if (Convert.ToInt32(ckb.Text) == currentFloor) { ckb.Checked = false; break; } } } }
当到达楼层停留一段时间(用于乘客的上下),,直到将选择的楼层都都停留了一段时间
当所叫楼层是偶数时的代码如下:
Button btn = sender as Button; string temnum = btn.Text.Trim(); num = Convert.ToInt32(temnum);//获得所叫楼层的楼号 if(num%2 ==0)//偶数楼层叫电梯时 { int tempnum;//保存响应的电梯号 int tempnum1 = Math.Abs(num-currentFloor); int tempnum2 = Math.Abs(num - currentFloor3); int tempnum3 = Math.Abs(num - currentFloor4); if (tempnum1 < tempnum2) { if (tempnum1 < tempnum3) { tempnum = tempnum1;//1号电梯 } else tempnum = tempnum3;//3号电梯 } else { if (tempnum2 < tempnum3) { tempnum = tempnum2;//2号电梯 } else tempnum = tempnum3;//3号电梯 }
奇数楼层的响应代码类似。
在电梯运动过程中,逗留楼层也不仅仅只有电梯内部所选择的楼层,还要加上外部所叫楼层,到达所叫楼层也一样需要停留,另外当要要相应的电梯没有选择楼层或静止时只需将电梯运动到所叫楼层即可。在电梯运动的函数中做一些改动,就能达到响应外部楼层,新改动的电梯移动函数如下。
private void elevator1Move(object sender) { elevatorIn(); Button btnElevator = sender as Button; Point p = new Point(); if (Elevator.selFloorNum>=1) { if (currentFloor < Elevator.selectFloors[Elevator.selFloorNum - 1]) { for (int j = Elevator.selFloorNum-1; j >=0; j--)//选择好的楼层 { for (; currentFloor < Elevator.selectFloors[j] || currentFloor<num; currentFloor++)//形成运动效果 { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; txtCurrentFloor.Text = (currentFloor+1).ToString(); // txtCurrentFloor2.Text = upnum; Thread.CurrentThread.Join(1000); // Thread.Sleep(1000 * setInf.perFloorTime);//将当前线程挂起(1000ms),不然看不到运动 } clearcbx(currentFloor); Elevator.selFloorNum--; Elevator.selectFloors[j] = -10; Thread.CurrentThread.Join(4000); // Thread.Sleep(4000 * setInf.perFloorTime); } } if (currentFloor >= Elevator.selectFloors[0] && Elevator.selectFloors[0]!=-10) { while (Elevator.selFloorNum!=-1) { while (currentFloor > Elevator.selectFloors[0] && Elevator.selectFloors[0]!=-10) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y + btnElevator.Size.Height; btnElevator.Location = p; txtCurrentFloor.Text = (currentFloor - 1).ToString(); // txtCurrentFloor2.Text = upnum; Thread.CurrentThread.Join(1000); //Thread.Sleep(1000 * setInf.perFloorTime);//将当前线程挂起(1000ms),不然看不到运动 currentFloor--; } clearcbx_D(currentFloor); Elevator.selectFloors[Elevator.selFloorNum] = -10; Elevator.selFloorNum--; Thread.CurrentThread.Join(4000); // Thread.Sleep(4000 * setInf.perFloorTime); } } } else//没有选择楼层 { if (currentFloor < num) { for (; currentFloor < num; currentFloor++) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y - btnElevator.Size.Height; btnElevator.Location = p; txtCurrentFloor.Text = (currentFloor + 1).ToString(); //txtCurrentFloor2.Text = upnum; Thread.CurrentThread.Join(1000); // Thread.Sleep(1000 * setInf.perFloorTime);//将当前线程挂起(1000ms),不然看不到运动 } } else { while (currentFloor >num) { p.X = btnElevator.Location.X; p.Y = btnElevator.Location.Y + btnElevator.Size.Height; btnElevator.Location = p; txtCurrentFloor.Text = (currentFloor - 1).ToString(); //txtCurrentFloor2.Text = upnum; Thread.CurrentThread.Join(1000); //Thread.Sleep(1000 * setInf.perFloorTime);//将当前线程挂起(1000ms),不然看不到运动 currentFloor--; } } // clearcbx(currentFloor); // Elevator.selFloorNum--; // Elevator.selectFloors[j] = -10; Thread.CurrentThread.Join(4000); } } private void elevatorIn() { ele.Visible = false; ele.ShowDialog(); }
结对总结:
我们一起完成了结对作业,说是一起完成,但是还是韩天中同学完成了大部分,我对于C#完全不会,都是从头还是学习,对于编程我能做的很少,但是我也努力也学习了,非常感谢韩天中同学对我的帮助,韩天中同学性格很好也很乐于助人,再次感谢他!
另附:结对伙伴邹鹏华博客 http://www.cnblogs.com/zht01
结对项目代码详见:https://coding.net/u/zht01/p/Elevators/git
https://coding.net/u/fandaren/p/zuoye4/git
标签:
原文地址:http://www.cnblogs.com/fandaren/p/5372234.html