个人代码库の可移动 + 滑动 + 反弹按钮“c#相关代码”
为了实现滑动的功能,需要用到【Timer对象】的帮助。为此需要在【窗体类的构造函数】里面添加一下代码:
//必须要在此显式声明这个用于滑动的Timer控件,才能减少每次调用的延迟。 myTimer = new Timer(); myTimer.Interval = intTimerInterval; myTimer.Tick += new System.EventHandler(this.myTimer_Tick);
以下代码直接绑定到你想要添加此功能的按钮的相应事件上即可:
#region 可移动 + 滑动 + 反弹按钮“相关代码” #region 变量声明区 /// <summary> /// 设定单击哪个按键可以移动按钮 /// </summary> MouseButtons MouseButton = MouseButtons.Right; //传递当前的按钮。 Button btnTemp = null; //用于滑动的计算的计时器。 Timer myTimer = null; //计时器的每次触发间隔(毫秒单位) int intTimerInterval = 20; //按钮滑动的帧数,越大过渡越平滑。 static int intNum = 30; //帧数的临时变量 int intTimer = intNum; //移动前后的时间。 DateTime datBegin,datEnd; //移动前后的坐标 Point poiBegin,poiEnd; //加速度以0.12倍数变小 //阻力的加速度 double intB = 0.12; //滑动的增幅大小,越大则滑动速度越快越远。 //末速度 double xV; double yV; //X和Y的加速度。 double xA; double yA; //记录当前鼠标相对于按钮的位置。 Point mouse_offset = new Point(); bool bolMove=false; //是否允许反弹 bool bolReturn = true; #endregion #region 相关事件区 private void Button_MouseDown(object sender , MouseEventArgs e) { if ( e.Button == MouseButton ) { btnTemp = (Button)sender; //bolMove = true; //将当前鼠标相对于“窗体”左上角的坐标赋值给mouse_offset mouse_offset = e.Location; //记下系统时间。以便计算速度 datBegin = DateTime.Now; poiBegin = btnTemp.Location; } } private void Button_MouseUp(object sender , MouseEventArgs e) { if ( bolMove && e.Button == MouseButton ) { //bolMove = false; //记下末后的坐标 poiEnd = ( (Button)sender ).Location; datEnd = DateTime.Now; #region 加速度相关公式 //开始计算X和Y的加速度。 //S=VoT+1/2AT*T //末速度V = VoT + AT //当Vo = 0时,A = 2S/(T*T);V = 2S/T #endregion int xS = poiEnd.X - poiBegin.X; int yS = poiEnd.Y - poiBegin.Y; double t = datEnd.Subtract(datBegin).TotalMilliseconds; xA = ( 2 * xS ) / ( t * t ); yA = ( 2 * yS ) / ( t * t ); xV = ( 2 * xS ) / t; yV = ( 2 * yS ) / t; //重置为默认帧数。 intTimer = intNum; //启动Timer控件,开始缓缓滑动… myTimer.Enabled = true; } } private void Button_MouseMove(object sender , MouseEventArgs e) { if ( e.Button == MouseButton ) { bolMove = true; //将相对屏幕坐标转换为相对工作区的坐标。 int left = PointToClient(Control.MousePosition).X - mouse_offset.X; int top = PointToClient(Control.MousePosition).Y - mouse_offset.Y; //左右可能越界 if ( left < 0 ) left = 0; if ( left > this.Width ) left = this.Width - ( (Button)sender ).Width; //上下可能越界 if ( top < 0 ) top = 0; if ( top > this.Height ) top = this.Height - ( (Button)sender ).Height; ( (Button)sender ).Left = left; ( (Button)sender ).Top = top; } } private void myTimer_Tick(object sender , EventArgs e) { //只要进入滑动模式,则代表鼠标(手动)移动的停止。 if ( bolMove ) bolMove = false; if ( intTimer == 0 || xA == 0 || yA == 0 ) { myTimer.Enabled = false; } else { intTimer--; if ( xA < 0 ) btnTemp.Left = btnTemp.Left - (int)( xA * xV * 1000 ); else btnTemp.Left = btnTemp.Left + (int)( xA * xV * 1000 ); if ( yA < 0 ) btnTemp.Top = btnTemp.Top - (int)( yA * yV * 1000 ); else btnTemp.Top = btnTemp.Top + (int)( yA * yV * 1000 ); xA = xA * ( 1 - intB ); yA = yA * ( 1 - intB ); //左右可能越界,改变符号后实现碰壁之后自动“反弹”; if ( btnTemp.Left < 0 ) { btnTemp.Left = 0; if ( bolReturn ) { xA = -xA; xV = -xV; } } if ( btnTemp.Left > this.Width - btnTemp.Width ) { btnTemp.Left = this.Width - btnTemp.Width; if ( bolReturn ) { xA = -xA; xV = -xV; } } //上下可能越界 if ( btnTemp.Top < 0 ) { btnTemp.Top = 0; if ( bolReturn ) { yA = -yA; yV = -yV; } } if ( btnTemp.Top > this.Height - btnTemp.Height ) { btnTemp.Top = this.Height - btnTemp.Height; if ( bolReturn ) { yA = -yA; yV = -yV; } } } } #endregion #endregion
作者:Asion Tang
凡是没有注明[转载]的文章,本Blog发表的文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。