Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail


Ответ
 
Опции темы
Старый 28.01.2020, 13:16   #1
Baumanetc
Новичок
Джуниор
 
Регистрация: 28.01.2020
Сообщений: 1
По умолчанию Анимация объекта в окне

Всем привет

Делаю небольшой проект с использованием WinAPI: в окне рисую дом, дерево и еще несколько объектов
Код:
#include <windows.h>
#include<time.h>
#include <iostream>
 
class TreePicture {
    void line(const HDC& dc, const int x1, const int y1, const int x2, const int y2) {
        MoveToEx(dc, x1, y1, 0);
        LineTo(dc, x2, y2);
    }
public:
    void show(const HWND& hwnd, const HDC& dc, const int X, const int Y);
};

class House {
public:
    void show(const HWND& hwnd, const HDC& dc, const int X, const int Y);
};

void House::show(const HWND& hwnd, const HDC& dc, const int X, const int Y) {
    /*ФАСАД ДОМА*/
    HBRUSH  brush = CreateSolidBrush(RGB(254, 255, 220));
    SelectObject(dc, brush);
    Rectangle(dc, X, Y + 260, X + 130, Y + 400);
    DeleteObject(brush);

    /*ТРЕУГОЛЬНАЯ КРЫША*/
    POINT poly[3] = { {X,Y + 260 },{ X + 130 , Y + 260 },{X + 130 / 2, Y + 200} };
    brush = CreateHatchBrush(HS_DIAGCROSS, RGB(199, 214, 255));
    SelectObject(dc, brush);
    Polygon(dc, poly, 3);
    DeleteObject(brush);

    /*БОК КРЫШИ ПАРАЛЛЕЛОГРАММ*/
    POINT poly2[4] = { {X + 65,Y + 200 },{X + 280 , Y + 200 },{X + 345,Y + 260}, {X + 130, Y + 260 } };
    brush = CreateHatchBrush(HS_HORIZONTAL, RGB(0, 0, 255));
    SelectObject(dc, brush);
    Polygon(dc, poly2, 4);
    DeleteObject(brush);
 
    /*БОК ДОМА*/
    brush = CreateHatchBrush(7, RGB(200, 255, 200));
    SelectObject(dc, brush);
    Rectangle(dc, X + 345, Y + 260, X + 130, Y + 400);
    DeleteObject(brush);

    /*ДВЕРЬ*/
    brush = CreateSolidBrush(RGB(175, 75, 0));
    SelectObject(dc, brush);
    Rectangle(dc, X + 70, Y + 320, X + 110, Y + 400);
    DeleteObject(brush);

    /*ОКНА*/
    brush = CreateSolidBrush(RGB(200, 200, 200));
    SelectObject(dc, brush);
    Rectangle(dc, X + 10, Y + 300, X + 50, Y + 340);
    Rectangle(dc, X + 150, Y + 300, X + 190, Y + 340);
    Rectangle(dc, X + 220, Y + 300, X + 260, Y + 340);
    Rectangle(dc, X + 290, Y + 300, X + 330, Y + 340);
    DeleteObject(brush);

}

void TreePicture::show(const HWND& hwnd, const HDC& dc, const int X, const int Y) {
    HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
    SelectObject(dc, brush);
    line(dc, X, Y, X, Y - 150); //Высота ствола, рисование идёт снизу к верху.

    /*Рисуем ветки*/
    line(dc, X, Y - 75, X - 50, Y - 75 - 15);
    Ellipse(dc, X - 70, Y - 105, X - 40, Y - 105 + 30); //Подгоняем листья

    line(dc, X, Y - 95, X - 50, Y - 95 - 15);
    Ellipse(dc, X - 75, Y - 120, X - 50, Y - 120 + 15); //Подгоняем листья
    Ellipse(dc, X - 50, Y - 130, X - 35, Y - 120 + 15); //Подгоняем листья

    Ellipse(dc, X - 10, Y - 150, X + 10, Y - 150 + 15); //Подгоняем листья

    line(dc, X, Y - 60, X + 80, Y - 165);  //Ветви
    line(dc, X, Y - 90, X + 30, Y - 135);
    line(dc, X + 25, Y - 95, X + 85, Y - 100);
    line(dc, X + 50, Y - 130, X + 55, Y - 170);

    Ellipse(dc, 15 + X + 55, 15 + Y - 170, 15 + X + 75, 15 + Y - 190); //листва
    Ellipse(dc, 15 + X + 34, 15 + Y - 180, 15 + X + 46, 15 + Y - 200);
    Ellipse(dc, 25 + X + (-5), 25 + Y - 120, 25 + X + 7, 25 + Y - 144);
    Ellipse(dc, 15 + X + 55, 15 + Y - 103, 15 + X + 75, 15 + Y - 127);
    Ellipse(dc, 15 + X + 10, 15 + Y - 140, 15 + X + 28, 15 + Y - 158);

    DeleteObject(brush);

};

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    static char szAppName[] = "HelloWin";
    HWND        hwnd;
    MSG         msg;
    WNDCLASSEX  wndclass;

    wndclass.cbSize = sizeof(wndclass);
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&wndclass);

    hwnd = CreateWindow(szAppName,        // window class name
        "Дом на берегу озера",   // window caption
        WS_OVERLAPPEDWINDOW,     // window style
        CW_USEDEFAULT,           // initial x position
        CW_USEDEFAULT,           // initial y position
        CW_USEDEFAULT,           // initial x size
        CW_USEDEFAULT,           // initial y size
        NULL,                    // parent window handle
        NULL,                    // window menu handle
        hInstance,               // program instance handle
        NULL);         // creation parameters

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    HDC         hdc;
    PAINTSTRUCT ps;
    RECT        rect;
    static int cx, cy;

    switch (iMsg)
    {
    case WM_CREATE:
        srand((int)time(0));

        return 0;
    case WM_SIZE:
        cx = LOWORD(lParam);
        cy = HIWORD(lParam);
        return 0;

    case WM_PAINT: {
        hdc = BeginPaint(hwnd, &ps);
        GetClientRect(hwnd, &rect);
 
        HBRUSH brush;

        brush = CreateHatchBrush(HS_BDIAGONAL, RGB(0, 255, 0));
        SelectObject(hdc, brush); //Выбираем кисть
        RECT WinCoord = {}; //Массив координат окна 
        GetWindowRect(hwnd, &WinCoord); //Узнаём координаты

        Rectangle(hdc, 0, 0, WinCoord.right, WinCoord.bottom);
        DeleteObject(brush);

        brush = CreateSolidBrush(RGB(0, 0, 255)); //Создаём кисть определённого стиля и цвета
        SelectObject(hdc, brush); //Выбираем кисть
        Rectangle(hdc, 0, 0, WinCoord.right, 170); //Рисуем новый прямоугольник, который будет небом
        DeleteObject(brush); //Очищаем память от созданной, но уже ненужной кисти

        brush = CreateSolidBrush(RGB(255, 255, 0)); //Создаём кисть определённого стиля и цвета
        SelectObject(hdc, brush); //Выбираем кисть
        Ellipse(hdc, WinCoord.right - 200, 20, WinCoord.right - 300, 120);
        DeleteObject(brush); //Очищаем память от созданной, но уже ненужной кисти
 
        brush = CreateSolidBrush(RGB(30, 46, 234)); //Создаём кисть определённого стиля и цвета
        SelectObject(hdc, brush); //Выбираем кисть
        Ellipse(hdc, 399, 312, 400 + 399, 312 + 140); //Озеро.
        DeleteObject(brush); //Очищаем память от созданной, но уже ненужной кисти
         
        brush = CreateSolidBrush(RGB(255, 255, 255)); //Создаём кисть определённого стиля и цвета
        SelectObject(hdc, brush); //Выбираем кисть
        Ellipse(hdc, 700, 30, 900, 100); //Облако.
        DeleteObject(brush); //Очищаем память от созданной, но уже ненужной кисти
 
        /*РИСУЕМ ДЕРЕВО*/
        TreePicture Tree;
        Tree.show(hwnd, hdc, 80, 440);
        Tree.show(hwnd, hdc, 270, 256);
        Tree.show(hwnd, hdc, 70, 247);
 
        /*РИСУЕМ ДОМ*/
        House house;
        house.show(hwnd, hdc, 410, -90);
 
        ReleaseDC(hwnd, hdc); //Освобождаем общий или оконный (не влияющий на класс или локальность) контекст устpойства, делая его доступным для дpугих пpикладных задач. 
 
        return 0;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
 
        return 0;
    }
 
    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}
Может кто-нибудь помочь сделать что-то типа анимации облака? Идея такая:
По нажатию левой кнопки мыши облако начинает двигаться влево. Если нажать еще раз, то облако останавливается
Baumanetc вне форума Ответить с цитированием
Старый 28.01.2020, 13:58   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,039
По умолчанию

Вместо того, чтоб рисовать константами, используйте переменные:
Ellipse(hdc, 700, 30, 900, 100) заменить на Ellipse(hdc, cloud_x, cloud_y, cloud_x + 200, cloud_y + 70)

Потом сделайте таймер, который вычисляет новые координаты и инициирует перерисовку.

Потом сделайте реагирование на нажатие и запускает/останавливает таймер.
waleri вне форума Ответить с цитированием
Ответ

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Анимация на модальном окне Alex870 HTML и CSS 1 13.08.2015 20:09
Поиск Handle'a объекта типа "Edit" в окне стороннего приложения TRIZER Win Api 6 12.07.2012 15:59
CLR. Ошибка C3918. Как вызвать из объекта обработчик, переданный родителю объекта от деда? Stilet Общие вопросы .NET 0 15.01.2011 18:49
С помощью методов и свойств объекта осуществляется управление терминалом. Имя (идентификатор) объекта User>lia Общие вопросы Delphi 4 16.01.2009 17:37
Как поменять одну из текстур объекта не меняя все остальные и без повторной загрузки объекта в GLScene DomKr@t Мультимедиа в Delphi 0 14.12.2008 02:52