用到窗体上画图形,是由于要做河内塔动画,需要体现圆盘动的过程
因此用到using System.Drawing;
、 using System.Drawing.Drawing2D;
中的Rectangle
类进行画矩形。
1、画图时遇到问题,若是新建一个 graphics 画图,当移动图形后刷新,以前打的图形就没了。
解决方案:要实时绘图,即将绘图命令放在 paint 中,可以 override paint 或者写一个Form1_Paint
方法例如:
首先注册事件
this.Paint += new System.Windows.Forms.PaintEventHandler( this.Form1_Paint );
然后将绘图方法写在Form1_Paint
方法中
void Form1_Paint( object sender, PaintEventArgs e )
{
e.Graphics.Clear( this.BackColor );
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;//若有可以更平滑,减少闪烁
Draw( e.Graphics );
}
Draw( e.Graphics );
方法是绘图的内容
private void DrawPegs( Graphics e )
{
//这里是对rectangleList中的每一个Rectangle进行绘制,当rectangleList改变了,绘制的图也就变了
int nCount = rectangleList.Count;
foreach( Rectangle rectangle in rectangleList ) {
e.FillRectangle( Brushes.LightGreen, rectangle );
e.DrawRectangle( Pens.Green, rectangle );
}
//m_isMoving是用来判断是否在运动过程的标志,
if( m_isMoving ) {
e.FillRectangle( Brushes.LightGreen, m_MovingDiskRect );
e.DrawRectangle( Pens.Green, m_MovingDiskRect );
}
}
这里就引入几个全局变量
bool m_isMoving = false;
用来判断每次刷新时是否要刷新m_MovingDiskRect
的位置
Rectangle m_MovingDiskRect;
是重新创建了一个矩形,来表示原来的矩形从一个地方移动到另一个地方中间的过程。
Rectangle[] m_PegLocation = new Rectangle[ 3 ];
表示柱子的位置信息,由于盘子的数量变多,柱子的长度一定要随着盘子数量而变化。
Stack<int>[] m_PegStack = new Stack<int>[ 3 ];
用一个堆栈数组来表示每一个柱子上盘子的个数与宽度信息。
2 Stack 堆栈的使用
此处用一个堆栈数组来表示每一个柱子上盘子的宽度信息。每次在移动之前先将堆栈中要移动Index下(从哪个柱子)的宽度pop出去,移动后再push到要移动Index下(移动到哪个柱子)进去。
也就是说用一个 长度为3的 Stack数组 来表示了当前柱子上盘子的数量的实时变化。
申明堆栈
Stack<int>[] m_PegStack = new Stack<int>[ 3 ];
3、计算每次运动过程多久才结束时,利用 Time类
在 while(true)循环中加入判断时间到了才跳出;
TimeSpan elapsed = DateTime.Now - start_time;
if( elapsed.TotalSeconds > seconds )
break;
而seconds
即用来判断的总时间,等于总的距离除以每秒移动多少距离
float seconds = dist / pixels_per_second;
当然,在while(true)循环之前要先取系统时间
DateTime start_time = DateTime.Now;
这样运动结束就可以跳出循环了。