Первая анимация

Xakep, номер #044, стр. 044-060-2


Цикл сообщений

Теперь надо подправить наш цикл обработки сообщений. Раньше он был неэффективен, потому что выглядел так:

while (GetMessage(msg, 0, 0, 0)) do

begin

end;

Здесь мы получали очередное сообщение от ОС с помощью GetMessage и обрабатывали его. А что если сейчас нет для нас сообщений? Программа просто застывала на вызове функции GetMessage и могла ждать бесконечно.

Для компьютерной графики более эффективно будет использовать функцию PeekMessage, которая проверяет, есть ли для нас сообщение. Если есть, то она возвращает true, а если нет, то результатом будет false. С использованием этой функции логика обработки сообщений изменяется так:

1. Запускаем бесконечный цикл (while true do).

2. На каждом этапе цикла проверяем с помощью PeekMessage, есть ли для нас сообщения.

3. Если нет, то можем заниматься своими делами, если да, то обрабатываем их.

4. Возвращаемся на пункт 2 и снова проверяем наличие сообщений.

while true do

begin

if PeekMessage(msg,0,0,0,PM_REMOVE)=false then

begin

// Для нас нет сообщений, и здесь мы можем

// заниматься анимацией

end

else

begin

translatemessage(msg);

dispatchmessage (msg);

end;

end;

Анимация

Теперь нужно написать логику движения самолета там, где я поставил комментарии в нашем новом обработчике событий. Напиши вместо комментариев следующее:

x:=x+1; //Увеличиваю позицию Х самолета

if X-LastXState>10 then

begin

State:=State+incparam; // Изменяю состояние

if State=6 then // Если уже 6-е состояние, надо уменьшать

incparam:=-1; // Приращение отрицательное

if State=0 then // Если 0-е состояние, надо увеличивать

incparam:=1; // Приращение положительное

LastXState:=x; // Запомнить текущую позицию самолета

end;

SendMessage(Handle, WM_PAINT, 0, 0); // Перерисовать

Здесь в первой строке кода я увеличиваю значение переменной Х на 1. После этого я проверяю, если переменная Х - LastXState больше 10, значит самолет уже пролетел 10 пикселей, и можно менять его состояние (выводить следующий спрайт). Для этого я увеличиваю значение переменной State на значение, записанное в incparam.

После этого проверяю состояние. Если переменная State равно 6, значит мы отображаем последний спрайт, и дальше некуда. Поэтому я изменяю приращение incparam на отрицательное, и в следующий раз переменная State будет уменьшаться. Ну а если State равна нулю, то приращение изменяю на положительное.

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

Отображение

Математику анимации мы уже сделали, теперь нужно вывести на экран сам самолет в уже рассчитанную позицию. Функция вывода не изменилась, и мы будем использовать все ту же BltFast, но небольшая косметическая операция все же произойдет:

Назад на стр. 044-060-1  Содержание  Вперед на стр. 044-060-3