个人代码库の可移动 + 滑动 + 反弹按钮“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

[By:Asion Tang] 博客园 标签: c#个人代码库
作者:Asion Tang
凡是没有注明[转载]的文章,本Blog发表的文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/AsionTang/p/1893716.html