Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИГС / Lab_02 / labor_02pm.doc
Скачиваний:
10
Добавлен:
17.04.2018
Размер:
699.9 Кб
Скачать

Перемещение по экрану графических вставок из bmp-файлов в win программах. Использование двух контекстов памяти.

Организовать движение отдельных блоков растрового изображения по экрану в Windows-программах значительно легче, чем в соответствующихDOS-программах. Здесь уже имеются готовыеAPI-функции, которые позволяют легко осуществить эти действия.

Возьмем за основу программу mov08.cpp. Новую программу назовемmov09.

Рисование динамических и статических объектов программы происходит в основном контексте памяти hdcMem. Растровое изображение изbmp-файла помещается в дополнительный контекст памятиhdcMem2.

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

Затем начинается рисование в основном контексте памяти, где уже содержится растровое изображение. После того, как все графические объекты приложения будут нарисованы в основном контексте памяти, этот контекст копируется на контекст экрана с помощью функции BitBlt().

Приведем фрагмент кода копирования блока растрового изображения из выбранного места вспомогательного контекста в определенное место основного контекста. Этот фрагмент находится в функции Move_OnTimer().

static int nPixel = 0;

BitBlt(hdcMem, xn1,yn1,xn2-xn1,yn2-yn1, hdcMem2, nPixel++,yn1, SRCCOPY);

if(nPixel+(xn2-xn1)>nRight-nLeft)

nPixel = 0;

Здесь берется блок изображения с размером xn2-xn1 пикселей по горизонтали и пикселейyn2-yn1 по вертикали. Во вспомогательном контексте этот блок имеет координаты левого верхнего углаnPixel,yn1. Этот блок копируется в основной контекст с координатами левого верхнего углаxn1,yn1.

Координата блока nPixelпо горизонтальной оси меняется на единицу на каждом шаге движения. При этом выделенный блок движется от левой границы растрового изображения до правой границы изображения. Потом все повторяется.

Координаты окна вагона в пикселях xn1,yn1,xn2,yn2 вычисляются в функцииMove_OnCreate(). В этой функции задаются координаты окна вагона xW1,yW1,xW2,yW2в мировых координатах.

Аналогично DOS-программе, здесь для рисования окна и занавески используются функцииWindowWagon()иCurtain().

Компилируем, запускаем программу mov09.exe, и результат работы этой программы показан на Рис.39.

Рис. 39.

Результат работы программы mov09.cpp.

Использование набора bmp-файлов для создания эффекта движения. Чтение bmp-файлов из ресурсов программы.

Если создать набор bmp-файлов, соответствующих разным стадиям движения графического объекта, то изображения, хранящиеся в этих файлах, можно использовать для получения движущегося фона. На этом движущемся фоне можно моделировать движение других графических объектов.

Для примера беремScreensaverс движущимся кораблем. С помощью него создаются 50 кадров движения корабля, которые помещаются в файлыShip10.bmp, Ship11.bmp, , Ship59.bmp. Новую программу поместим в файлmov10.cpp. В файле ресурсовmov10.rcпоместим следующие строчки.

Bitmap10 BITMAP "BMP\ship10.bmp"

Bitmap11 BITMAP "BMP\ship11.bmp"

Bitmap58 BITMAP "BMP\ship58.bmp"

Bitmap59 BITMAP "BMP\ship59.bmp"

В функции Move_OnCreate() создаем массив имен bitmap-ресурсов Bitmap10, Bitmap11, , Bitmap59, описанных в файле ресурсов. Ниже приводятся строчки соответствующего кода.

//заполняем массив имен bitmap-ресурсов nameShip[k]

//имена следущего вида: Bitmap10, Bitmap11, ... Bitmap59

//всего 50 имен

char is[3] = "";

char ssss[20] = "";

for( k=0; k<50; k++)

{

itoa(k+10,is,10);

strcpy(ssss,"Bitmap");

strcat(ssss,is);

strcpy(nameShip[k],ssss);

}

В функцииMove_OnTimer()создаем контекст памяти с идентификаторомhdcMem. Загружаем в память bitmap-ресурс с номеромiBmpв виде битовой карты. Созданная битовая карта имеет идентификаторhBitmap. Номер ресурсаiBmpна каждом шаге увеличивается (флагflagBmp = 1) или уменьшается (флагflagBmp = 2) на единицу. Поэтому корабль движется или вперед или назад.

Выбираем битовую карту hBitmapв контекст памятиhdcMem. После этого можно рисовать другие графические объекты в памяти на этой битовой карте. В программе моделируется движение перископа подводной лодки и двух торпед. Когда торпеды сближаются на малое расстояние, движение объектов прекращается (флагflagEnd = 1).

Ниже приводится код функции Move_OnTimer().

//функция обрабатывает сообщение WM_TIMER

void Move_OnTimer(HWND hwnd)

{

//получаем идентификатор контекста экрана

HDC hdcWin = GetDC(hwnd);

//создаем контекст памяти совместимый с контекстом экрана

HDC hdcMem = CreateCompatibleDC(hdcWin);

//номер bitmap-ресурса

static int iBmp = 0;

int numberBmp;

if(flagEnd == 1)

numberBmp = 30;

else

numberBmp = iBmp;

//загружаем в память bitmap-ресурс из модуля exe-файла

//hInstApp - идентификатор экзепляра приложения

//nameShip[numberBmp] - идентификатор bitmap-ресурса (в файле ресурсов)

//hBitmap - идентификатор загруженного bitmap-ресурса

HBITMAP hBitmap = LoadBitmap(hInstApp, nameShip[numberBmp]);

//выбираем bitmap-объект hBitmap в контекст памяти hdcMem

HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);

if(flagBmp == 1)

{

iBmp++;

if(iBmp>49)

{

flagBmp = 2;

iBmp--;

}

}

if(flagBmp == 2)

{

iBmp--;

if(iBmp<0)

{

flagBmp = 1;

iBmp++;

}

}

if(tPer>6)

{

if(flagEnd == 0)

{

tP += dtP;

xP2 = TrajP(tP).x;

yP2 = TrajP(tP).y;

xP2b = TrajPb(tP).x;

yP2b = TrajPb(tP).y;

if(fabs(xP2)+fabs(yP2)<1)

flagEnd = 1;

fiP2 =atan2l(yP2-yP1,xP2-xP1);

fiP2b =atan2l(yP2b-yP1b,xP2b-xP1b);

TracP(hdcMem, tP, dtP);

Torpedo(hdcMem,PtP,9,xP1,yP1,xP2,yP2,fiP1,fiP2,kxP,kyP);

xP1 = xP2; yP1 = yP2; fiP1 = fiP2;

TracPb(hdcMem, tP, dtP);

Torpedo(hdcMem,PtPb,9,xP1b,yP1b,xP2b,yP2b,fiP1b,fiP2b,kxP,kyP);

xP1b = xP2b; yP1b = yP2b; fiP1b = fiP2b;

Periscope(hdcMem, 0);

}

else

{

Crash(hdcMem);

Periscope(hdcMem,0);

}

}

else

{

Periscope(hdcMem, ym(tPer));

tPer += dtPer;

}

//копируем изображение из контекста памяти hdcMem в контекст экрана hdcWin

BitBlt(hdcWin, 0, 0, nRight, mBottom, hdcMem, 0, 0, SRCCOPY);

SelectObject(hdcMem, hBitmapOld); //востанавливаем контекст памяти

DeleteObject(hBitmap); //убираем битовую карту

DeleteDC(hdcMem); //освобождаем контекст памяти

ReleaseDC(hwnd,hdcWin); //освобождаем контекст экрана

}

Компилируем, запускаем программу mov10.exe, и результат работы этой программы показан на Рис.40.

Рис. 40.

Результат работы программы mov10.exe.

Соседние файлы в папке Lab_02