Сделать Windows MF C Game L oop Быстрее - PullRequest
0 голосов
/ 26 мая 2020

Я создаю бильярд, и у меня большие проблемы с туннелированием на высоких скоростях. Я решил, что использование линейной интерполяции для анимации немного поможет, но проблема не устранена. Чтобы увидеть это, я нарисовал круг на нескольких предыдущих позициях, где находился объект. При максимальной скорости, которую может перемещать мяч, путь выглядит следующим образом: enter image description here

Конечно, эти приращения продвижения слишком велики даже после использования линейной интерполяции.

В каждом кадре местоположение каждого объекта обновляется в зависимости от количества времени, прошедшего с момента последнего отображения окна. Я заметил, что среднее время перерисовки окна составляет от 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 для всех игровых элементов, которые используют графический объект, который они получают в качестве аргумента.

...