如何使用WPF在C#中进行快速平滑动画
我目前正在编写一个乒乓球游戏。我已经完成了大部分游戏,但我遇到了一个恼人的问题。我使用的是一个如何使用WPF在C#中进行快速平滑动画,c#,wpf,animation,timer,rectangles,C#,Wpf,Animation,Timer,Rectangles,我目前正在编写一个乒乓球游戏。我已经完成了大部分游戏,但我遇到了一个恼人的问题。我使用的是一个调度程序,优先级设置为发送,时间跨度设置为1毫秒。为了让球移动得足够快,我正在使用dx=9和dy=9为矩形设置动画。由于大像素跳跃,球在屏幕上出现跳跃,而不是平滑移动。根据数学计算,在每一个周期1毫秒内,这个球的移动速度应该比它现在快得多。我需要更频繁地更新球,移动球的距离要少一些 有没有关于更好的方法的建议?这里是我所拥有的一个片段 pongballTimer = new DispatcherTime
调度程序
,优先级设置为发送,时间跨度设置为1毫秒。为了让球移动得足够快,我正在使用dx=9和dy=9为矩形设置动画。由于大像素跳跃,球在屏幕上出现跳跃,而不是平滑移动。根据数学计算,在每一个周期1毫秒内,这个球的移动速度应该比它现在快得多。我需要更频繁地更新球,移动球的距离要少一些
有没有关于更好的方法的建议?这里是我所拥有的一个片段
pongballTimer = new DispatcherTimer(DispatcherPriority.Send);
pongballTimer.Tick += new EventHandler(pongballTimer_Tick);
pongballTimer.Interval = new TimeSpan(0, 0, 0, 0, _balldt);
private void pongballTimer_Tick(object sender, EventArgs e)
{
double pongtop = Canvas.GetTop(PongBall);
double pongleft = Canvas.GetLeft(PongBall);
double paddletop = Canvas.GetTop( RightPaddle );
double paddleleft = Canvas.GetLeft( RightPaddle );
if (pongleft + PongBall.Width > paddleleft)
{
if (((pongtop < paddletop + RightPaddle.Height) && (pongtop > paddletop)) ||
((pongtop + PongBall.Height < paddletop + RightPaddle.Height) &&
(pongtop + PongBall.Height > paddletop)))
{
_dx *= -1;
SetBalldy(pongtop, PongBall.Height, paddletop, RightPaddle.Height);
_rightpoint++;
lblRightPoint.Content = _rightpoint.ToString();
meHitSound.Play();
}
else // The ball went past the paddle without a collision
{
RespawnPongBall(true);
_leftpoint++;
lblLeftPoint.Content = _leftpoint.ToString();
meMissSound.Play();
if (_leftpoint >= _losepoint)
LoseHappened("You Lost!!");
return;
}
}
if (pongleft < 0)
{
meHitSound.Play();
_dx *= -1;
}
if (pongtop <= _linepady ||
pongtop + PongBall.Height >= PongCanvas.Height - _linepady)
{
meDeflectSound.Play();
_dy *= -1;
}
Canvas.SetTop(PongBall, pongtop + _dy);
Canvas.SetLeft(PongBall, pongleft + _dx);
}
pongballTimer=newdispatchermer(DispatcherPriority.Send);
pongballTimer.Tick+=新事件处理程序(pongballTimer_Tick);
pongballTimer.Interval=新的时间跨度(0,0,0,0,0,_-balldt);
私有void pongballTimer_Tick(对象发送方,事件参数e)
{
double-pongtop=Canvas.GetTop(PongBall);
double-pongleft=Canvas.GetLeft(PongBall);
double-palletop=Canvas.GetTop(右桨);
double-palleft=Canvas.GetLeft(右桨);
如果(pongleft+PongBall.Width>左侧)
{
如果((pongtop<桨叶顶部+右桨叶高度)&(pongtop>桨叶顶部))||
((乒乓球+乒乓球高度<桨顶+右桨高度)&&
(pongtop+PongBall.高度>桨叶顶部)))
{
_dx*=-1;
设置球位(pongtop,PongBall.高度,桨顶,右桨.高度);
_rightpoint++;
lblRightPoint.Content=_rightpoint.ToString();
meHitSound.Play();
}
否则//球没有撞到球拍就越过了球拍
{
重生球(真实);
_leftpoint++;
lblLeftPoint.Content=_leftpoint.ToString();
memissound.Play();
如果(\u leftpoint>=\u losepoint)
失败者(“你输了!!”);
返回;
}
}
如果(庞氏指数<0)
{
meHitSound.Play();
_dx*=-1;
}
如果(pongtop=PongCanvas.高度-_linepady)
{
meDeflectSound.Play();
_dy*=-1;
}
Canvas.SetTop(PongBall,pongtop+_-dy);
Canvas.SetLeft(PongBall,pongleft+dx);
}
您可以使用WPF中内置的一种动画技术,而不是在计时器回调中进行移动
开始阅读,可能需要特别注意每帧动画的最后一部分:绕过动画和计时系统
然后您可以继续。只是一个随机的想法,但是如果您在tick处理程序中更新视觉效果,您可以尝试在画布上调用InvalidateVisual或ball afterwards dude,我不知道您在做什么,但这不是您应该在WPF中编码的方式。您的代码看起来太winforms了,而且您也不可能有1毫秒的刷新时间。任何UI的常规速率都在30到60 fps之间。正常的最小计时器分辨率为15ms。1ms等于1000fps。尝试一些更现实的东西,比如50到100毫秒,这将是20或10 fps。你仍然会有一些重复性问题。我尝试了InvalidateVisual,但它似乎没有改变任何事情。我不是在追求1毫秒的刷新率…但我必须将计时器设置为1毫秒,以使我的球移动足够快。完全不合逻辑,我知道…我觉得计时器太不准确了。我只需要更新球更多的频率,移动它看起来更少。是的,我是WPF的新手,习惯于手工操作。