Я создаю бильярд, и у меня большие проблемы с туннелированием на высоких скоростях. Я решил, что использование линейной интерполяции для анимации немного поможет, но проблема не устранена. Чтобы увидеть это, я нарисовал круг на нескольких предыдущих позициях, где находился объект. При максимальной скорости, которую может перемещать мяч, путь выглядит следующим образом: ![enter image description here](https://i.stack.imgur.com/Pd18p.jpg)
Конечно, эти приращения продвижения слишком велики даже после использования линейной интерполяции.
В каждом кадре местоположение каждого объекта обновляется в зависимости от количества времени, прошедшего с момента последнего отображения окна. Я заметил, что среднее время перерисовки окна составляет от 70 до 80 мс. Мне бы очень хотелось, чтобы эта игра работала со скоростью 60 кадров в секунду, так что это примерно в 4 или 5 раз дольше, чем я ищу.
Есть ли способ изменить частоту перерисовки окна? Вот как я сейчас перерисовываю экран
#include "pch.h"
#include "framework.h"
#include "ChildView.h"
#include "DoubleBufferDC.h"
const int FrameDuration = 16;
void CChildView::OnPaint()
{
CPaintDC paintDC(this); // device context for painting
CDoubleBufferDC dc(&paintDC); // device context for painting
Graphics graphics(dc.m_hDC); // Create GDI+ graphics context
mGame.OnDraw(&graphics);
if (mFirstDraw)
{
mFirstDraw = false;
SetTimer(1, FrameDuration, nullptr);
LARGE_INTEGER time, freq;
QueryPerformanceCounter(&time);
QueryPerformanceFrequency(&freq);
mLastTime = time.QuadPart;
mTimeFreq = double(freq.QuadPart);
}
LARGE_INTEGER time;
QueryPerformanceCounter(&time);
long long diff = time.QuadPart - mLastTime;
double elapsed = double(diff) / mTimeFreq;
mLastTime = time.QuadPart;
mGame.Update(elapsed);
}
void CChildView::OnTimer(UINT_PTR nIDEvent)
{
RedrawWindow(NULL, NULL, RDW_UPDATENOW);
Invalidate();
CWnd::OnTimer(nIDEvent);
}
РЕДАКТИРОВАТЬ : По запросу, вот как выполняется фактическое рисование:
void CGame::OnDraw(Gdiplus::Graphics* graphics)
{
// Draw the background
graphics->DrawImage(mBackground.get(), 0, 0,
mBackground->GetWidth(), mBackground->GetHeight());
mTable->Draw(graphics);
Pen pen(Color(500, 128, 0), 1);
Pen penW(Color(1000, 1000, 1000), 1);
this->mCue->Draw(graphics);
for (shared_ptr<CBall> ball : this->mBalls)
{
ball->Draw(graphics);
}
for (shared_ptr<CBall> ball : this->mSunkenSolidBalls)
{
ball->Draw(graphics);
}
for (shared_ptr<CBall> ball : this->mSunkenStripedBalls)
{
ball->Draw(graphics);
}
this->mPowerBar->Draw(graphics);
}
Game :: OnDraw будет вызывать Draw для всех игровых элементов, которые используют графический объект, который они получают в качестве аргумента.