天天看點

SDL Guide 中文譯版 序言

SDL即Simple DirectMedia Layer,類似DirectX,是完整的遊戲、多媒體開發包,但不同的是它跨越幾乎所有的平台,有各種語言的接口,多種語言的文檔,而這一切都是廣大志願者完成的。目前擴充部分還沒有正式的文檔,以下為核心部分文檔的向導部分。

SDL為友善制作能跨躍Linux、BSD、MacOS、Win32和BeOS平台,使用本地高性能媒體接口,并且讓您可以隻需使用一份源代碼級API而設計。SDL是相當低層的API,但使用它可以讓你以極大的靈活性寫出完全跨平台的程式。

 SDL:http://www.libsdl.org/

SDLdoc項目即要重新編寫SDL文檔并同步更新。項目組有使用SDL的志願者組成。

Sam Lantinga, [email protected]

Martin Donlon, [email protected]

Mattias Engdeg?rd

Julian Peterson

Ken Jordan

Maxim Sobolev

Wesley Poole

Michael Vance

Andreas Umbach

Andreas Hofmeister

SDL由八個子系統組成——音頻、CDROM、事件處理、檔案I/O、遊戲杆、線程、記時器和視訊。使用前必須調用SDL_Init或SDL_InitSubSystem初始化。SDL_Init必須早于其他所有SDL調用,它将自動初始化事件處理、檔案I/O和線程子系統,并根據參數選擇啟動其他子系統。例如,初始化預設和視訊子系統:

初始化預設、視訊和記時器子系統:

SDL_Init對應SDL_Quit(和SDL_QuitSubSystem)。SDL_Quit關閉所有子系統,必須在程式關閉前調用。

除此之外,我們還必須進行錯誤處理。很多SDL函數傳回一個值訓示成功與否。例如SDL_Init失敗時傳回-1。每當SDL出錯時,錯誤資訊被儲存,并可用SDL_GetError取得。

視訊是最常用的部分,也是SDL最完整的子系統。下面的初始化過程是每個SDL程式都要做的,即使可能有些不同。

如果你希望某種色深(顔色數)但如果使用者的顯示器不支援也可以接受其他色深,使用加SDL_ANYFORMAT參數的SDL_SetVideoMode。您還可以用SDL_VideoModeOK來找到與請求模式最接近的模式。

當SDL已經初始化,視訊模式已經選擇,下面的函數将讀取并顯示指定的BMP檔案。

下面兩個函數實作在圖像平面的像素讀寫。它們被細心設計成可以用于所有色深。記住在使用前要先鎖定圖像平面,之後要解鎖。

在像素值和其紅、綠、藍值間轉換,使用SDL_GetRGB()和SDL_MapRGB()。

SDL可以在多種平台(Linux/X11, Win32, BeOS, MacOS Classic/Toolbox, MacOS X, FreeBSD/X11 and Solaris/X11)上建立和使用OpenGL上下文。這允許你在OpenGL程式中使用SDL的音頻、事件、線程和記時器,而這些通常是GLUT的任務。

和普通的初始化類似,但有三點不同:必須傳SDL_OPENGL參數給SDL_SetVideoMode;必須使用SDL_GL_SetAttribute指定一些GL屬性(深度緩沖區位寬,幀緩沖位寬等);如果您想使用雙緩沖,必須作為GL屬性指定

除了初始化,在SDL程式中使用OpenGL和其他情況基本相同,是同樣函數和資料類型。但是如果您使用雙緩沖,則必須用SDL_GL_SwapBuffers()來交換前後緩沖,而不是glxSwapBuffers()(GLX)或SwapBuffers()(Windows)。

使用遊戲杆的第一步是初始化遊戲杆子系統。即在SDL_Init時使用參數SDL_INIT_JOYSTICK。

此例啟動SDL并帶視訊和遊戲杆支援。

至此,我們可以假定初始化以完成。但我們還需指導有沒有、有幾個遊戲杆。即使您指導有一個遊戲杆可用,也最好經常檢查,因為這樣可以幫助檢測遊戲杆被拔掉的情況。

檢查遊戲杆的函數是SDL_NumJoysticks()。此函數簡單的傳回系統中遊戲杆的數量。下一步是決定使用者想用哪一個。當然,如果隻有一個就不用決定了。SDL_JoystickName取得系統賦給遊戲杆的名字。遊戲杆用序号指定,第一個為0,最後一個為SDL_NumJoysticks - 1。

SDL使用事件架構,遊戲杆可以觸發四種事件。

SDL_JoyAxisEvent 軸改變

SDL_JoyBallEvent 軌迹球坐标改變

SDL_JoyHatEvent hat(sorry,在下不解何為hat)方向改變

SDL_JoyButtonEvent 按鈕按下或釋放

所有啟動的遊戲杆都會觸發事件。為了收到事件,首先要用SDL_ENABLE調用SDL_JoystickEventState,以允許事件。其次要啟動指定的遊戲杆,用SDL_JoystickOpen()。

遊戲杆對象的指針隻在查詢和關閉遊戲杆時有用。

現在為了響應事件,我們需要一個消息循環。所有的SDL程式至少要接受系統退出消息。設想我們的消息循環象這樣:

要響應遊戲杆事件,隻需添加一個case。軸檢測得有些技巧,因為大部分事件是垃圾。搖杆動一點就會有事件。是以必須設定一個門檻值,并且忽略未達到門檻值的事件。一般10%是個比較好的門檻值。

另一個技巧是上下和左右是兩組不同的運動。最重要的軸是軸0(左右)和軸1(上下)。按如下方法作不同處理:

理想情況下,應該用event.jaxis.value來調整一些值。例如你在用遊戲杆控制飛船,将搖杆推一點則慢速前進,推很多則快速前進。這樣設計會使使用者的體驗更好。如果你的遊戲杆有更多的軸,可用于其他控制,用法完全一樣,event.jaxis.axis會有不同的值。

按鈕檢測很簡單,因為隻有按下和放開兩個狀态。按下時SDL_JOYBUTTONDOWN觸發,放開時SDL_JOYBUTTONUP觸發。event.jbutton.button訓示是哪個按鈕。

最後,程式結束時用SDL_JoystickClose()關閉遊戲杆。例如關閉前面啟動的0号遊戲杆:

軌迹球消息包含X和Y方向的改變量。

此例檢測第一個軌迹球。坐标改變量在event.jball.xrel和event.jball.yrel中。

最後是hat事件。hat隻報告方向。我們通過位掩碼檢測:

預定義的組合:

除了遊戲杆的數量,還可查詢:

SDL_JoystickNumAxes 軸數量

SDL_JoystickNumButtons 按鈕數量

SDL_JoystickNumBalls 軌迹球數量

SDL_JoystickNumHats hat數量

隻需将啟動遊戲杆時得到的指針傳給這些函數即可。

SDLKey 枚舉類型,每一個符号代表一個鍵,如SDLK_a、SDLK_SPACE,在SDL_keysym.h中定義。

SDLMod 枚舉類型,類似SDLKey,但用于修飾鍵,如Control、Alt、Shift,可以組合。

SDL_keysym

用于按鍵和放開消息。scancode是硬體相關鍵碼。除非你有特殊用途,否則忽略。sym訓示鍵,mod為修飾鍵集合,例如KMOD_NUM | KMOD_CAPS | KMOD_LSHIFT 為Numlock、Capslock和左Shift組合。最後unicode為對應字元。注意,僅當是按鍵消息時unicode才有效,放開消息時無效。Unicode變換必須用SDL_EnableUNICODE()打開。

SDL_KeyboardEvent

描述一個鍵盤消息。type訓示按鍵(SDL_KEYDOWN)或放開(SDL_KEYUP)。state是備援的,和含義type相同隻是符号不同(SDL_PRESSED,SDL_RELEASED)。

使用消息循環用SDL_PollEvent()從消息隊列裡讀取,并用switch-case檢測SDL_KEYUP和SDL_KEYDOWN。下面是個基本的例子。

我們已經知道要用SDL_Init和SDL_SetVideoMode初始化,但我們還得用另外兩個函數取得必要資訊。要調用SDL_EnableUNICODE(1)以允許unicode變換,還要用SDL_GetKeyName将SDLKey轉換成可列印字元。注意:小于0x80的unicode字元直接映射到ASCII碼。下例用到這一點。

鍵盤消息僅在鍵的狀态在按下和放開間變化時才觸發。

設想你用光标鍵控制飛船運動以改變眼前看到的太空景象,當你按左鍵并希望鏡頭向左轉時。看看下面的代碼,并注意它為什麼是錯的。

問題在于你必須按100次左以便得到100次鍵盤消息,才能向左轉100像素。正确的方法是收到事件時設定标志,根據标志來移動。

如您所見,我們用了兩個變量alien_xvel和alien_yvel來表示飛船的運動,并在響應鍵盤消息時更新它們。

注:重複的例子沒有列出

将圖像畫到螢幕上有三種方式:1.建立一個圖像平面并用SDL_BlitSurface傳送到螢幕;2.在系統記憶體建立視訊平面并調用SDL_UpdateRect;3.在顯存建立視訊平面并調用SDL_LockSurface。最好的方法是混合方式:

繼續閱讀