2013-03-19 4 views
1

Я сейчас программирую игру в Понге. У меня большая часть игры завершена, но я столкнулся с раздражающей проблемой. Я использую dispatcherTimer с приоритетом, установленным в Send и time span, установленным в 1 миллисекунду. Я анимация прямоугольника, используя до dx = 9 и dy = 9, чтобы заставить мяч двигаться достаточно быстро. Из-за больших прыжков в пикселях шарик появляется на экране вместо гладкого хода. Согласно математике за 1 миллисекунду за цикл этот шар должен перемещаться МНОГО быстрее, чем он есть. Мне нужно обновлять мяч чаще и перемещать его меньше ...Как сделать быструю плавную анимацию в C# с помощью WPF

Есть ли предложения по лучшему методу для этого? Вот отрывок из того, что у меня есть ...

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); 
} 
+0

Просто случайная мысль, но если вы обновляете визуал в обработчике галочки, вы можете попробовать позвонить InvalidateVisual на холст или мяч потом – JerKimball

+2

Чувак, я не знаю, что вы делаете, но это не так вы должны ввести код в WPF. ваш код выглядит слишком winforms, а также нет никакого способа получить обновление 1 мс, которое вы после. регулярная ставка для любого пользовательского интерфейса составляет от 30 до 60 кадров в секунду. –

+2

Разрешение минимального минимального таймера составляет 15 мс. 1 мс будет равно 1000 кадров в секунду. Попробуйте что-то более реалистичное, например, от 50 до 100 мс, что будет 20 или 10 кадров в секунду. У вас все еще будут проблемы с повторяемостью. –

ответ

0

Вместо того, чтобы делать движение в обратном вызове таймера, вы можете использовать один из методов анимации, которые встроены в WPF.

Начало чтения Property Animation Techniques Overview, возможно, с особым вниманием к последнему разделу Анимация в рамке: обход системы анимации и синхронизации.

Затем вы можете перейти на How to: Render on a Per Frame Interval Using CompositionTarget.

Смежные вопросы