个人代码库の可移动 + 滑动 + 反弹按钮“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发表的文章版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号