В минулому епізоді ми створили просту програму з використанням SDL 2.0, яка створювала вікно розміром 640х480 пікселів з заголовком "demo01" і голубим фоном. Вікно вміло реагувати на подію закриття. Всеь код, який відповідав за це, був одним цілим і не зовсім зрозуміло, як з нього можна отримати гру.
Сьогодні спробуємо розділити цей код на окремі логічні фрагменти і винести їх у відповідні підпрограми. Але спочатку давайте розглянемо з чого складається будь-яка гра, точніше, алгоритм, по якому працює будь-яка гра.
Після успішної ініціалізації потрібних даних та створення усіх об'єктів запускається бескінечний цикл, в якому перевіряється ввід даних від користувача і обробка відповідних подій, на основі цього прораховуються зміни в ігровій логіці та відбувається відображення поточного стану гри на екран. Коли користувач завершує гру, цикл переривається і відбувається очистка пам'яті та коректне завершення виконання. Тож давайте спробуємо виділити ці фрагменти і в нашій програмі.
Перший фрагмент буде відповідати за ініціалізацію, тому першу підпрограму так і назвемо. До неї перенесемо рядки коду від початку програми до початку циклу - саме в цих рядках ініціалізується SDL 2.0, створюються вікно та візуалізатор і встановлюється ознака виконання циклу. Також непогано було б цей код зробити не процедурою, а функцією, яка буде приймати на вхід параметри - розміри вікна та заголовок, а повертати true якщо все пройшло успішно і false коли щось пішло не по плану.
function Initialize(aCaption : PChar; _w,_h : Integer) : Boolean; begin result:=false; //ініціалізація бібліотеки SDL 2.0 if SDL_Init(SDL_INIT_EVERYTHING)>=0 then begin //успішна ініціалізація - створюємо вікно SDLWindow:=SDL_CreateWindow(aCaption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, _w, _h, SDL_WINDOW_SHOWN); //якщо вікно створене, створюємо візуалізатор if SDLWindow<>nil then begin SDLRenderer:=SDL_CreateRenderer(SDLWindow,-1,0); if SDLRenderer=nil then begin WriteLN('SDL error: ',SDL_GetError); Exit; end; end; //виділення пам'яті для структури обробки подій New(SDLEvent); //встановлення ознаки виконання циклу і його запуск isRun := true; result:=true; end; end;
Також перед запуском циклу буде перевірятись результат виконання цієї функції і запускатись він буде лише при успішному виконанні ініціалізації.
Наступний крок алгоритму - обробка подій. Винесемо цей фрагмент теж окремою процедурою. Окрім неї, в алгоритмі ще є обробка ігрової логіки, але оскільки в нас ще фактично ніякої ігрової логіки не задіяно, створимо для використання в майбутньому порожню процедуру:
procedure DoEvents; begin //намагаємось відловити подію закриття вікна if SDL_PollEvent(SDLEvent)=1 then begin if SDLEvent^.type_=SDL_QUITEV then isRun:=false; end; end; procedure GameLogic; begin //тут в майбутньому буде щось прораховуватись end;
Усі ігри виводять якусь картинку на екран. І хоча в нас ще немає що виводити, проте є код який відповідає за очищення вікна кольором фону. Отримуємо ще одну процедуру:
procedure Draw; begin //встановимо колір вікна в голубий SDL_SetRenderDrawColor(SDLRenderer,0,128,255,255); //очисстити вікно SDL_RenderClear(SDLRenderer); //показати вікно на екран SDL_RenderPresent(SDLRenderer); end;
І останній крок, який нам лишився - очистка пам'яті після завершення циклу.
procedure Cleanup; begin //прибрати за собою - в оберненому порядку створення Dispose(SDLEvent); SDL_DestroyRenderer(SDLRenderer); SDL_DestroyWindow(SDLWindow); SDL_Quit(); end;
Після усіх маніпуляцій з кодом програма стане наступною:
program demo02; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes { you can add units after this },sdl2; var SDLWindow : PSDL_Window; //вікно SDLRenderer : PSDL_Renderer; //візуалізатор SDLEvent : PSDL_Event; //події isRun : Boolean; //ознака виконання циклу //тут в кінцевому коді будуть підпрограми, описані вище begin if Initialize('Demo02',640,480) then while isRun=true do begin DoEvents; GameLogic; Draw; end; Cleanup; end.
Ну ось, тепер в нас починає вимальовуватись щось схоже на заготовку для гри, проте до справжньої гри ще досить далеко. В наступному епізоді спробуємо перевести отриманий код на ООП і сформувати основний клас для майбутнього фреймворку, який поступово будемо доповнювати.
На сьогодні буде достатньо, код проекту можна скачати на Github, а весь процес можна подивитись на відео:
Немає коментарів:
Дописати коментар