Простая анимация на С ++ - PullRequest
       0

Простая анимация на С ++

0 голосов
/ 15 октября 2011

Хорошо, поэтому я пробовал некоторые базовые анимационные вещи (если вы могли бы даже назвать это анимацией) в окнах.Я перепутал с параметрами TextOut (координаты для текста) без анимации.Как в основном, он напечатал бы "привет" в нескольких разных местах один раз, и после этого казалось, что ничего не происходит.Проблема в том, что текст рисуется на экране, а текст предыдущего вызова InvalidateRect не удаляется с экрана.Кроме того, если в TextOut в качестве параметров добавить несколько простых значений возрастающих рядов (например, 1,2,3,4,5 и т. Д.), Такой проблемы не возникает.

#include <Windows.h>

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
struct point
{
    double x;
    double y;
    double t;
};


point obj={30,30,1};

int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPWSTR cmdLine,int cmdShow)
{
    WNDCLASSEX windowsClass={0};



    windowsClass.hCursor=LoadCursor(NULL,IDC_ARROW);
    windowsClass.cbSize=sizeof(WNDCLASSEX);
    windowsClass.hInstance=hInstance;
    windowsClass.lpfnWndProc=WndProc;
    windowsClass.cbClsExtra=NULL;
    windowsClass.style=CS_HREDRAW | CS_VREDRAW;
    windowsClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    windowsClass.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH);
    windowsClass.lpszClassName="Devjeet's Window";

    if(!RegisterClassExA(&windowsClass))
        return -1;
    HWND hWnd = CreateWindowExA(NULL,"Devjeet's Window","Animation V1 By Devjeet",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,400,400,NULL,NULL,hInstance,NULL);

    if(!hWnd)
        return -1;
    ShowWindow(hWnd,cmdShow);


    MSG msg={0};

    while(msg.message!=WM_QUIT)
    {
        if(PeekMessage(&msg,0,0,0,PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return static_cast<int>(msg.wParam);
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hDC;
    PAINTSTRUCT paintStruct;

    switch(message)
    {

    case WM_PAINT:
        hDC=BeginPaint(hWnd,&paintStruct);

        TextOut(hDC,(int)(obj.x),(int)(obj.y),"Hello",sizeof("Hello"));
        obj.y=(double)(30*obj.t+(obj.t*obj.t*9.8/2));
        obj.x=(double)(30*obj.t+(obj.t*obj.t*9.8/2));
        obj.t+=.8;


        EndPaint(hWnd,&paintStruct);
        if(obj.y>100.0)
        {
            obj.x=30.0;
            obj.y=30.0;
            obj.t=1.0;
        }

        Sleep(800);
        InvalidateRect(hWnd,NULL,TRUE);
        break;
    case WM_DESTROY:
        PostQuitMessage(NULL);
        break;
    default:
        return DefWindowProc(hWnd,message,wParam,lParam);
        break;
    }
    return 0;
}

1 Ответ

1 голос
/ 15 октября 2011

Во-первых: никогда, никогда не звоните Sleep от своего подручного WM_PAINT.Вы заблокируете свой пользовательский интерфейс.

Рекомендуемый способ сделать простую анимацию в Windows - это использовать SetTimer и обработать сообщение WM_TIMER.Ваш обработчик WM_TIMER определяет, где должен быть ваш спрайт, и вызывает InvalidateRect.Вы можете сделать недействительным все окно или только старые и новые позиции перемещенного спрайта.

В ответ на InvalidateRect Windows отправит вам сообщение WM_PAINT, позволяющее перекрасить окно..

Что касается того, почему он не стирает старый: вы указали NULL_BRUSH в качестве фона окна, что означает, что обработчик WM_ERASEBKGND по умолчанию (где Windows будет стирать содержимое вашего окна) ничего не делает.Вам либо нужно обработать WM_ERASEBKGND самостоятельно (чтобы стереть окно, используя - например - FillRect), либо вам также необходимо обработать эту часть в обработчике WM_PAINT.

Ohи причина того, что простой прирост позиции работает, вероятно, потому что (если я правильно помню), TextOut сотрет фон ограничительной рамки для данного текста.Поскольку это, вероятно, на пару пикселей больше, чем текст, предыдущий текст будет удален, если он находится всего в пикселе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...