Графика DirectX в Delphi
Шрифт:
Map4.WrapScrollDown(MapScrollSpeed); end; if KeyDown(DIK_ESCAPE) then begin // Выход
GameScreen.FadeTo(255, 255, 255, 0); // Эффект угасания
GameScreen.FadeOut(4) ;
f rmDD.Close;
end;
end;
Обрабатывается нажатие нескольких клавиш одновременно, образы можно передвигать по диагонали.
Вывод осуществляется в задний буфер, каждая карта отсекается по своему сектору:
function TfrmDD.UpdateFrame : HRESULT;
var
Windowl : TRECT; //
Window2 : TRECT;
Windows : TRECT;
Window4 : TRECT;
begin
SetRect (Windowl, 0, 0, 320, 240) ; // Четыре равные части экрана
SetRect (Window2, 320, 0, 640, 240);
SetRect (Window3, 0, 240, 640, 480); SetRect (Window4, 320, 240, 640, 480);
GameInput.Update; // Обновить данные о клавиатуре
OpdateKeys; // Обслужить нажатые клавиши
// Вывод в задний кадр четырех карт, отсекаемых по секторам
Map1.DrawClipped(GameScreen.GetAppBackBuffer, Windowl);
Map2.DrawClipped(GameScreen.GetAppBackBuffer, Window2);
МарЗ.DrawClipped(GameScreen.GetAppBackBuffer, Window3);
Map4.DrawClipped(GameScreen.GetAppBackBuffer, Window4);
Result := GameScreen.Flip; // Переключение страниц
end;
Для восстановления поверхностей используется метод Restore.
В продолжение нашего знакомства с библиотекой CDX разберем проект каталога Ех15, помогающий постигнуть создание анимации. В качестве фона здесь используются те же круги, что и в предыдущем примере, которые сменяют друг друга на экране.
Существует одна переменная, связанная с фоном, в нее загружаются различные фрагменты растра:
GameMap := CDXMap.CDXMap(Landscape, GameScreen); // Создание лоскута
GameMap.CreateMap(MapSizeX, MapSizeY, 1) ;
GameMap.MoveTo(0, 0) ; Tile := 1;
for i := 0 to 63 do // Цикл заполнения карты
for j := 0 to 62 do begin // разными фрагментами
GameMap.SetTile (i, j, Tile);
Tile := Tile + 1;
if Tile > 4 then Tile := 1;
end;
Через некоторый промежуток времени экран заполняется новым фоном:
var
Delay : Integer =0; // Счетчик кадров
function TfrmDD.UpdateFrame : HRESULT;
var
wrk : TRECT; // Прямоугольник экрана
i, j, Tile : Integer;
begin
Game Input.Update;
UpdateKeys;
SetRect (wrk, 0, 0, ScreenWidth, ScreenHeight);
// Вывести текущее состояние фона
GameMap.DrawClipped (GameScreen.GetAppBackBuffer, wrk);
Inc (Delay);
if Delay > 40 then begin // Прошло 40 кадров
for i := 0 to 62 do
for j := 0 to 62 do begin
Tile := GaraeMap.GetTile(i, j); // Получить номер фрагмента
Inc (Tile); // Циклический сдвинуть в цепочке фрагментов
if Tile > 4 then Tile := 1;
GameMap.SetTile(i, j, Tile); // Задать новый фрагмент
end;
Delay := 0;
end;
Result := GameScreen.Flip;
end;
Код обработки клавиатуры в примере заметно короче по сравнению с предыдущим:
procedure UpdateKeys;
begin
if KeyDown(DIK_RIGHT) then GameMap.WrapScrollRight(MapScrollSpeed);
if KeyDown(DIK_LEFT) then GameMap.WrapScrollLeft(MapScrollSpeed);
if KeyDown(DIKJJP) then GameMap.WrapScrollUp(MapScrollSpeed);
if KeyDown(DIK_DOWN) then GameMap.WrapScrollDown(MapScrollSpeed);
if KeyDown(DIK_ESCAPE) then frmDD.Close;
end;
На
рис. 5.15 запечатлен момент работы нашего очередного примера (проекта каталога Ех16), в котором на экране выводятся координаты пользовательского курсора.Рис. 5.15. Пример вывода текста и обработки событий мыши
Для изображения курсора предназначена отдельная поверхность, для которой задается ключ:
GameCursor := CDXSurfасе.Create;
GameCursor.CreateCDXSurfaceFromFile(GameScreen,'Cur.bmp');
GameCursor.ColorKey(0);
Для заднего буфера задается конкретный шрифт:
GameScreen.GetAppBackBuffer.ChangeFont('Times', 16, 20, FW_BOLD);
Аналогично процедуре обработки клавиатуры, требуется процедура, связанная с событиями мыши. Обратите внимание, как организована прокрутка изображения:
procedure UpDateMouse;
var
TempX, TempY : Integer;
begin
TempX := GameInput.Mouse.X; // Смещение по осям
TempY := Gamelnput.Mouse.Y;
CurX := CurX + 3 * TempX; // Текущие координаты курсора
CurY := CurY + 3 * TempY;
// Анализ положения курсора вблизи границ экрана
if CurX < 0 then CurX := 0 else
if CurX > ScreenWidth - MapSizeX then CurX := ScreenWidth - MapSizeX;
if CurY < 0 then CurY := 0 else
if CurY > ScreenHeight - MapSizeY then CurY := ScreenHeight - MapSizeY;
if CurX = 0 then begin
if TempX < 0 then GameMap.WrapScrollLeft(-TempX);
end else
if CurX = ScreenWidth - MapSizeX then
if TempX > 0 then GameMap.WrapScrollRight(TempX);
if CurY = 0 then begin
if TempY < 0 then GameMap.WrapScrollUp(-TempY);
end else
if CurY = ScreenHeight - MapSizeY then
if TempY > 0 then GameMap.WrapScrollDown(TempY);
end;
Вывод текста на экран осуществляется с помощью метода TextxY заднего буфера:
function TfrmDD.UpdateFrame : HRESULT;
var
wrk : TRECT;
begin
Gamelnput.Update;
UpdateKeys;
UpdateMouse;
SetRect (wrk, 0, 0, ScreenWidth, ScreenHeight);
GameMap.DrawClipped (GameScreen.GetAppBackBuffer, wrk);