C#培训2019-10-12 Form窗体画图 Drawing

用到窗体上画图形,是由于要做河内塔动画,需要体现圆盘动的过程

因此用到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;

这样运动结束就可以跳出循环了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是红绿灯的窗体应用程序代码: ```csharp using System; using System.Drawing; using System.Windows.Forms; namespace TrafficLightApp { public partial class Form1 : Form { private Timer timer; private int count = 0; public Form1() { InitializeComponent(); // 创建 Timer 控件 timer = new Timer(); timer.Interval = 1000; timer.Tick += Timer_Tick; timer.Start(); } private void Timer_Tick(object sender, EventArgs e) { count++; // 根据计数器的值,控制红绿灯的显示 switch (count % 3) { case 0: pictureBoxRed.BackColor = Color.Gray; pictureBoxYellow.BackColor = Color.Gray; pictureBoxGreen.BackColor = Color.Green; break; case 1: pictureBoxRed.BackColor = Color.Red; pictureBoxYellow.BackColor = Color.Gray; pictureBoxGreen.BackColor = Color.Gray; break; case 2: pictureBoxRed.BackColor = Color.Gray; pictureBoxYellow.BackColor = Color.Yellow; pictureBoxGreen.BackColor = Color.Gray; break; } } } } ``` 在窗体设计器中,放置三个 PictureBox 控件,分别用于显示红、黄、绿三个灯。在窗体的构造函数中,创建 Timer 控件并设置其 Tick 事件。在 Tick 事件中,根据计数器的值(模 3),控制红绿灯的显示。在这里,我们将计数器每秒加 1,红灯亮 1 秒,黄灯亮 1 秒,绿灯亮 1 秒,然后重复这个过程。 需要注意的是,我们这里使用了三个 PictureBox 控件来显示红、黄、绿三个灯的状态,这些控件的背景色会根据状态变化而变化。这种方式相对简单,但也有一些缺点,比如不太容易实现灯的闪烁等效果。如果需要更加灵活的灯光控制,可以考虑使用 GDI+ 绘制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值