窗体(控件)移动的编程思想
一、方盒移动案例
1、工具
要想实现移动最主要的工具:计时器(=秒表)
2、为什么要使用计时器?它有什么功能?
要想让窗体移动 (右下左上四个方向) 并且向看到移动的过程,所以就要用计时器控制窗体根据间隔的时间移动的距离,实现窗体走向容器(显示器)的四个方向。
3、如何找到计时器,并开启关闭它?它有什么属性呢?
位置:视图==》工具箱==》timer,将它拉到Form1中就添加成功
开启:timer.Start();//因为Start是方法所以必须带括号;
关闭:timer.stop();
属性:Interval 事件的频率,以毫秒为单位
4、如何在代码中创建计时器事件?它有什么含义?
创建: 在Form1.cs设计窗口中双击timer1就会自动添加事件到代码中。
含义:根据间隔的事件重复执行这个事件中的代码(其实就是每当经过指定的时间间隔就会发生)
5、编程思想
(1)在c#中控件的移动都是由左上角开始的,左上角可以看作是一个坐标轴x和y,是0,0点(原点),当向右移动,x是加,向左移动x是减,当向上移动,y是减,向下移动y是加。
(2) 在窗体中没有Right右,Bottom下方向,只有Left左和Top上,所以,窗体向右和左移动的公为;
①this.left=this.left+20; 等于 this.left+=20;
②this.left=this.left-20; this.left-=20;
意思为 :
①控件左边缘与容器工作区左边缘之间的距离=控件左边缘与容器工作区左边缘之间的距离+20像素,就是让窗体(方盒)向右移动20像素的距离.
② 向左则为: 控件左边缘与容器工作区左边缘之间的距离=控件左边缘与容器工作区左边缘之间的距离-20像素,就是让窗体(方盒)向左移动20像素的距离.
(3)所以,窗体向下和上移动的公为:
①this.top=this.top+20; 等于 this.top+=20;
②this.top=this.top-20; this.top-=20;
意思为 :
①控件上边缘与容器工作区上边缘之间的距离=控件上边缘与容器工作区上边缘之间的距离+20像素,就是让窗体(方盒)向下移动20像素的距离.
② 向左则为: 控件上边缘与容器工作区上边缘之间的距离=控件上边缘与容器工作区上边缘之间的距离-20像素,就是让窗体(方盒)向上移动20像素的距离.
(4)当方盒移动到右或下或左或上边时会跑出显示器外,所以我们在它到跑到显示器工作区的时候就要让他停下来,然后再继续往规定的方向走。所以我们应作出相应的判断来让他停止再开始。
① if (this.Left+this.Width>=Screen.PrimaryScreen.WorkingArea.Width)
② if (this.Top+this.Height>= Screen.PrimaryScreen.WorkingArea.Height)
③ if (this.Left==0 )
④ if (this.Top==0)
①它是判断控件左边缘与容器工作区左边缘之间的距离+控件的宽度是否大于等于显示器工作区域的宽度。
②它是判断控件上边缘与容器工作区上边缘之间的距离+控件的宽度是否大于等于显示器工作区域的高度。
③判断控件上边缘与容器工作区上边缘之间的距离是否等于0
④判断控件上边缘与容器工作区上边缘之间的距离是否等于0
(3)我们该何时开启计时器呢?
这个案例我们要用到四个计时器timer1,timer2,timer3和timer4,所以当我们要让方盒从原点出发,就必须在Form1_Load中开启timer1,然后到显示器右边工作区的时候要让它停下来,这时候判断就派上用场了,当①判断结果为真(成立时)关闭计时器timer1,然后等它刚停下来我们我让他往下走,所以这个时候我们要让他停下来,当①判断结果为真时我们就开启计时器timer2,这样依次到第四个计时器timer又回到(0,0)点即原点,我们再让他在重新开始移动,所以就要开启计时器timer1.
6、实际操作
如下:
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;
namespace _20200406Study02
{
public partial class Form1 : Form
{
private readonly RectangleF path;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.None;//设置窗体(控件)的边框样式为无边框
this.Location = new Point(0, 0);//设置窗体的位置为显示器左上角的原点
this.Size = new Size(100, 100);//设置窗体的宽为100.高位100
this.BackColor = Color.Red;//设置窗体的颜色位红色
this.Opacity = 0.7;//设置窗体的不透级别为0.7,则透明度为0.3
timer1.Start();//开启计时器timer1
}
private void timer1_Tick(object sender, EventArgs e)
{
this.Left += 20;//控件向右移动20像素
//this.left表示设置控件左边缘与容器工作区左边缘之间的距离
if (this.Left+this.Width>=Screen.PrimaryScreen.WorkingArea.Width)
//判断控件左边缘与容器工作区左边缘之间的距离+控件的宽度是否大于等于显示器工作区域的宽度
//this.width表示设置控件的高度
// Screen.PrimaryScreen.WorkingArea.Width表示获取显示器工作区域的宽度
{
timer1.Stop();//关闭计时器timer1
timer2.Start();//开启计时器timer1
}
}
private void timer2_Tick(object sender, EventArgs e)
{
this.Top += 20;//控件向下移动20像素
if (this.Top+this.Height>= Screen.PrimaryScreen.WorkingArea.Height)
//判断控件上边缘与容器工作区上边缘之间的距离+控件的高度是否大于等于显示器工作区域的高度
//this.top表示设置控件上边缘与容器工作区上边缘之间的距离
//Screen.PrimaryScreen.WorkingArea.Height表示获取显示器工作区的高度
{
timer2.Stop();//关闭计时器timer2
timer3.Start();//开启计时器timer3
}
}
private void timer3_Tick(object sender, EventArgs e)
{
this.Left -= 20;//控件向左移动20像素
if (this.Left==0 )//判断控件上边缘与容器工作区上边缘之间的距离是否等于0
{
timer3.Stop();//关闭计时器timer3
timer4.Start();//开启计时器timer4
}
}
private void timer4_Tick(object sender, EventArgs e)
{
this.Top-=20;//控件向上移动20像素
if (this.Top==0)//判断控件上边缘与容器工作区上边缘之间的距离是否等于0
{
timer4.Stop();//关闭计时器timer4
timer1.Start();//开启计时器timer1
}
}
}
}
二、气泡碰撞案例
1、编程思想
(1)学会画圆(3个步骤)
②
GraphicsPath path = new GraphicsPath();//定义一个GraphicPath类型的对象,实则就是创建了一个类
方法后要加括号
这个对象定义好后不能使用,因为缺少工具,此时我们可以将鼠标指向GraphicsPath就会出现一个💡图标,点击三角会出现三行代码,这时我们选择第二个,并将右边也进行此次操作。
如下,是设置好后的代码:
System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
然后,将 System.Drawing.Drawing2D 放到最上边的工具箱代码中,注意要加上using。
如下,是添加好后的代码:
using System.Drawing.Drawing2D;
③
path.AddEllipse(0, 0, 200, 200);//向当前路径中添加一个椭圆
①
this.Region = new Region(path);//设置与控件相关联的窗口区域
要想使用 System.Drawing.Drawing2D必须先定义一个GraphicsPath类型的对象
将定义的GraphicsPath 类型的对象path入方法中
(2)规律
当气泡从左上角原点移动时,它有两种情况:
①碰撞到下边==》然后往右或者往上碰撞==》然后延申。。。。
②碰撞到右边==》然后往下或者往左碰撞==》然后延申。。。。
注:
这种方法写完以后它不会继续循环,只会停留到哪个方向,所以我们可以根据气泡碰撞的方向来打开其他的计时器,做到循环碰撞。
2、实际操作
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.Drawing.Drawing2D;
namespace _20200408Study3
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{
//设置窗体的初始属性
this.FormBorderStyle = FormBorderStyle.None;//设置窗体的边框样式为无边框
this.Location = new Point(0,0);//设置窗体的坐标为原点
this.Size = new Size(200, 200);//设置窗体的宽高为200px
this.BackColor = Color.Blue;//设置窗体的背景颜色为蓝色
// this.Opacity = 0.8;//设置窗体的不透明级别为0.8
this.BackgroundImage = Image.FromFile("E:/C#/C#文件/20200408Study3/20200408Study3/img/timg.jpg");//插入图片
//画圆(三步骤)
GraphicsPath path = new GraphicsPath();//定义一个GraphicPath类型的对象②
path.AddEllipse(0, 0, 200, 200);//向当前路径中添加一个椭圆
this.Region = new Region(path);//设置与控件相关联的窗口区域①
timer1.Start();//开启timer1
}
//添加第 一 个计时器
//向 右 和 下 端碰撞
private void timer1_Tick(object sender, EventArgs e)
{
this.Left += 15;
this.Top += 15;
// 右
if (this.Left+this.Width>=Screen.PrimaryScreen.WorkingArea.Width)//判断控件左边缘与容器工作区左边缘之间的距离+控件的宽度是否大于等于显示器的宽度
{
timer1.Stop();//关闭计时器1
timer4.Start();
}
// 下
if (this.Top+this.Height>=Screen.PrimaryScreen.WorkingArea.Height)//判断控件上边缘与容器工作区上边缘之间的距离+控件的高度是否大于等于显示器的高度
{
timer1.Stop();
timer2.Start();//打开计时器2
}
}
//添加第 二 个计时器
//向 右 上 端碰撞
private void timer2_Tick(object sender, EventArgs e)
{
this.Left += 15;
this.Top -= 5;
// 右
if (this.Left+this.Width>=Screen.PrimaryScreen.WorkingArea.Width)//判断控件左边缘与容器工作区左边缘之间的距离+控件的宽度是否大于等于显示器的宽度
{
timer2.Stop();//关闭计时器2
timer3.Start();
}
// 上
if (this.Top<=0)//判断控件上边缘与容器工作区上边缘之间的距离是否小于等于0
{
timer2.Stop();
timer1.Start();//打开计时器1
}
}
//添加第 三 个计时器
//向 左 上 端碰撞
private void timer3_Tick(object sender, EventArgs e)
{
this.Left -= 10;
this.Top -= 15;
// 左
if (this.Left<=0)//判断控件左边缘与容器工作区左边与之间的距离是否小于等于0
{
timer3.Stop();//关闭计时器3
timer2.Start();//打开计时器2
}
// 上
if (this.Top<=0)//判断控件上边缘与容器工作区上边缘之间的距离是否大于等于显示器的高度
{
timer3.Stop();
timer4.Start();
}
}
//添加第 四 个计时器
//向 左 下 端碰撞
private void timer4_Tick(object sender, EventArgs e)
{
this.Left -= 10;
this.Top += 15;
// 左
if (this.Left<=0)//判断控件左边缘与容器工作区左边与之间的距离是否小于等于0
{
timer4.Stop();//关闭计时器4
timer1.Start();
}
// 下
if (this.Top+this.Height>=Screen.PrimaryScreen.WorkingArea.Height)//判断控件上边缘与容器工作区上边缘之间的距离+控件的高度是否大于等于显示器的高度
{
timer4.Stop();
timer3.Start();
}
}
}
}
3、总结
这两种案例都是利用4个计时器的方法并不断关闭打开的方法来实现循环移动碰撞,所以程序比较繁琐。