前言
亂彈
常見的遊戲開發有c/c++(Unreal), C#(Unity)等, Pascal語言的也有(https://wiki.freepascal.org/Game_Engine),但是和前者對比不夠流行。 關於pascal的優勢,網上都說時易於教學,可以培養良好的程序習慣云云,我只是聽之而已。 如果說最後需要c++,爲什麼一開始就面對呢,非要用pascal繞一圈,得不償失的。 以上僅是個人觀點
爲什麼有這系列文章
在Pascal基礎系列文章第一篇我曾寫到閒的無聊,學習一下pascal
, 目前也是如此。 如果爲了學習遊戲開發,快速上手自然要用Unreal或者Unity。 從基礎做起,估計要學習圖形學之類的知識。 但是我是閒情偶記(記錄的記)
本系列關注於2D Code,不關注遊戲性(關卡設計等)以及遊戲相關資源(字體,美術,音樂音效等)的創建
環境
圖形庫選擇
Pascal是跨平臺的,如果要寫的程序也要跨平臺,可能需要使用OpenGL(相比Vulkan可以支持更多的舊設備)好一些。 但是爲了偷懶,決定使用SDL2。優點如下
- 使用廣泛, 資料衆多
- 上手簡單,跨平臺
編輯器: lazarus 平臺: ubuntu18.04
- 安裝sdl2
sudo apt install libsdl2-dev libsdl2-gfx-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-net-dev libsdl2-ttf-dev
- 安裝lazarus
sudo apt install lazarus make
- sdl2的pascal語言綁定
https://github.com/ev1313/Pascal-SDL-2-Headers下載後直接包含到項目中即可
概覽
開始之前需要了解遊戲的大體的運行機制
graph TD
A(初始化) --> B[獲取輸入]-->C[物理計算]-->D[渲染]-->E(結束)
D --> B
部分平臺的markdown不支持flowchart...........
這就是遊戲的基本框架,看起來很簡單.
第一個示例
創建一個窗口,5秒後會自動關閉
Program test01;
{$mode objfpc}{$H+}
Uses SysUtils,sdl2;
Var
pw : PSDL_Window;
pr : PSDL_Renderer;
Begin
// init
SDL_Init(SDL_INIT_VIDEO);
If SDL_WasInit(SDL_INIT_VIDEO)<>0 Then writeln('video init');
pw := SDL_CreateWindow('Hello',SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,450,
SDL_WINDOW_SHOWN);
pr := SDL_CreateRenderer(pw,-1,0);
// render
SDL_SetRenderDrawColor(pr,0,0,0,255);
SDL_RenderClear(pr);
SDL_RenderPresent(pr);
SDL_Delay(5000);
// clean
SDL_DestroyWindow(pw);
SDL_DestroyRenderer(pr);
SDL_Quit();
End.
接下來加入輸入部分(暫時忽略物理計算)
isRunning := true;
While isRunning Do
Begin
// handle input
If SDL_PollEvent(@e)=1 Then
Begin
Case e.Type_ Of
SDL_QUITEV: isRunning := false;
End;
End;
// TODO: do physics and then update
// render
SDL_SetRenderDrawColor(pr,0,0,0,255);
SDL_RenderClear(pr);
SDL_RenderPresent(pr);
End;
使用OOP來整理一下
Type TGame = Class
Private
pw : PSDL_Window;
pr : PSDL_Renderer;
Public
isRunning: boolean;
Procedure Init(title : String;x,y,h,w,flags:integer );
Procedure Render();
Procedure Update();
Procedure HandleEvents();
Procedure Clean();
End;
Var
g : TGame;
Begin
g := TGame.Create;
g.Init('Hello',SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,600,400,SDL_WINDOW_SHOWN);
While g.isRunning Do
Begin
g.HandleEvents;
g.Update;
g.Render;
End;
g.Clean;
g.Free;
End.
makefile
main:main.pas
fpc -gh -Fusdl2 -Fl. main.pas