1 / 46

OOSDL

OOSDL. 靜宜大學資工系 蔡奇偉 副教授 2006-2007. 內容大綱. 前言 組成類別 CPoint, CRect, CSurface CScreen CSDLApp, CGameApp 範例. 前言. Object-Oriented SDL 把一些 SDL 資料型態封裝成類別,使其更容易使用。 提供 Game Programming Framework ,以簡化遊戲程式的開發。. 組成類別. 基本型態: CPoint: 二維的點座標,主要用於儲存位置資訊。 CRect: 封裝 SDL_Rect 型態的矩形類別。

ebowman
Download Presentation

OOSDL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. OOSDL 靜宜大學資工系 蔡奇偉 副教授 2006-2007

  2. 內容大綱 • 前言 • 組成類別 • CPoint, CRect, CSurface • CScreen • CSDLApp, CGameApp • 範例

  3. 前言 • Object-Oriented SDL • 把一些 SDL 資料型態封裝成類別,使其更容易使用。 • 提供 Game Programming Framework,以簡化遊戲程式的開發。

  4. 組成類別 • 基本型態: • CPoint: 二維的點座標,主要用於儲存位置資訊。 • CRect: 封裝 SDL_Rect 型態的矩形類別。 • CSurface: 封裝 SDL_Surface 型態的繪圖頁類別。 • CJoysticks: 封裝 SDL_Joystick 型態的搖桿類別。 • Clock & Timer 時鐘與定時器 • Framework: • CSDLApp: 簡單 SDL 應用程式的 framework • CGameApp: 基本的遊戲程式 framework • CScreen: 遊戲螢幕

  5. CPoint 類別 struct DECLSPEC CPoint { CPoint (Sint16 x = 0, Sint16 y = 0); void Set (Sint16 x, Sint16 y); bool operator== (const CPoint &pt); bool operator!= (const CPoint &pt); bool InsideRect (CRect &r); };

  6. CRect 類別 class DECLSPEC CRect : public SDL_Rect 成員函式 CRect (Sint16 x = 0, Sint16 y = 0, Uint16 w = 0, Uint16 h = 0); void Set (Sint16 x, Sint16 y, Uint16 w, Uint16 h); bool operator== (const CRect &r); bool operator!= (const CRect &r); bool IsEqualSize (const CRect &r); bool IsNonEqualSize (const CRect &r); bool ContainPoint (CPoint &pt);

  7. Sint16 Left (); Sint16 Top (); Sint16 Right (); Sint16 Bottom (); Uint16 width (); Uint16 Height (); Width Top Height Botom Left Right

  8. CSurface CSurface (); CSurface (SDL_Surface *pSurface); CSurface (CSurface &cs); // Copy construction ~CSurface () operator SDL_Surface * () const; SDL_Surface * GetSDLSurfacePtr () const; CSurface& operator= (const CSurface &cs); CSurface& operator= (SDL_Surface *pSurface);

  9. // Create a blank surface. bool Create (Uint32 flags, int width, int height, int depth =32, Uint32 Rmask = SDL_RMASK, Uint32 Gmask = SDL_GMASK, Uint32 Bmask = SDL_BMASK, Uint32 Amask = SDL_AMASK); // Create a CSurface from pixel data. bool Create (void *pixels, int width, int height, int pitch, int depth = 32, Uint32 Rmask = SDL_RMASK, Uint32 Gmask = SDL_GMASK, Uint32 Bmask = SDL_BMASK, Uint32 Amask = SDL_AMASK); // Load an image file bool LoadImage (const char *file, bool bDisplayFormat = true); // Save CSurface to a BMP file int SaveBMP (const char *file);

  10. int Width (); int Height (); bool Lock (); void Unlock (); Uint32 GetPixel (int x, int y); void PutPixel (int x, int y, Uint32 pixel);

  11. // Color conversion Uint32 MapRGB (Uint8 r, Uint8 g, Uint8 b); Uint32 MapRGBA (Uint8 r, Uint8 g, Uint8 b, Uint8 a); void GetRGB (Uint32 pixel, Uint8 &r, Uint8 &g, Uint8 &b); void GetRGBA (Uint32 pixel, Uint8 &r, Uint8 &g, Uint8 &b, Uint8 &a);

  12. // Colorkey bool SetColorKey (Uint32 key, bool useRLE = true) bool SetColorKey (Uint8 r = 0, Uint8 g = 0, Uint8 b = 0, bool useRLE = true) bool ClearColorKey (); bool HasColorKey (); // Alpha bool SetAlpha (Uint8 alpha, bool useRLE = true) bool ClearAlpha () bool HasAlpha ()

  13. // Clipping CRect void SetClipRect (CRect &rect); void ResetClipRect (); void GetClipRect (CRect &rect); // Fill surface bool Fill (Uint32 color); bool Fill (Uint8 r, Uint8 g, Uint8 b); // Fill part of surface bool FillRect(CRect &rect, Uint32 color); bool FillRect(CRect &rect, Uint8 r, Uint8 g, Uint8 b);

  14. // Blit this surface to another surface bool Blit (SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); bool Blit (SDL_Rect *srcrect, SDL_Surface *dst, CPoint &position); bool Blit (CSurface &dst, Sint16 x, Sint16 y); // Blit this surface to the screen surface bool Show (CRect &srcrect, CRect &rect); bool Show (CRect &srcrect, CPoint &position); bool Show (CRect &srcrect, Sint16 x, Sint16 y); bool Show (Sint16 x, Sint16 y);

  15. CScreen 類別 CScreen (int width, int height, int bpp, Uint32 flags); virtual bool Show (CSurface &surface, SDL_Rect *srcrect, SDL_Rect *dstrect); virtual bool Present (); bool isDirty (); void SetDirty (); void ResetDirty (); void SetBackgroundColor (Uint32 color); void SetBackgroundColor(m_pSurface->MapRGB(r,g,b)); void Clear (); void Clear (Uint32 color);

  16. CSDLApp • void SetScreen (CScreen *pScreen = NULL); • 若參數為 NULL,則使用預設的螢幕物件(640x480x32, 軟性螢幕繪圖頁, 視窗畫面)。 • void SetCaption (const char *title, • const char *icon = NULL); • 若採用視窗螢幕,此函式可用來設定視窗的標題與 icon。 • void GetCaption(char **title, char **icon); • 若採用視窗螢幕,此函式可用來取得視窗的標題與 icon 。

  17. virtual bool InitializeSDL ( • Uint32 flags = SDL_INIT_VIDEO); • 初始化 SDL 函式庫。預設的旗標值只啟動 Video 子系統。此成員函式必須是第一個被呼叫的函式。 • virtual bool InitializeApp (); • 你應該改寫此成員函式,在其中加入所需的應用程式初始化設定。 • virtual void BeforePollEvent (); • 如果你的應用程式在處理事件之前,需做某些計算,你可以改寫此成員函式。 • virtual bool AppMain (); • 遊戲迴圈中的主要程式碼。 • virtual bool QuitApp (); • 改寫此成員函式來處理結束程式前的清理動作。

  18. 事件處理的相關成員函式 virtual bool ProcessNextEvent (); virtual void SetApplication (void *pTheApp);

  19. virtual void OnKeyDown (const SDL_keysym &keysym); virtual void OnKeyUp (const SDL_keysym &keysym); virtual void OnMouseMotion (Uint8 state, Uint16 x, Uint16 y, Sint16 xrel, Sint16 yrel); virtual void OnMouseButtonDown (Uint8 button, Uint16 x, Uint16 y); virtual void OnMouseButtonUp (Uint8 button, Uint16 x, Uint16 y); virtual void OnUser (Uint8 type, int code, void *data1, void *data2); virtual void OnQuit ();

  20. // Joystick events virtual void OnJoyAxis (Uint8 which, Uint8 axis, Sint16 value); virtual void OnJoyButtonDown (Uint8 which, Uint8 button); virtual void OnJoyButtonUp (Uint8 which, Uint8 button); virtual void OnJoyHat (Uint8 which, Uint8 hat, Uint8 value); virtual void OnJoyBall (Uint8 which, Uint8 ball, Sint16 xrel, Sint16 yrel);

  21. virtual void OnActiveEvent (Uint8 gain, Uint8 state); virtual void OnResize (int w, int h); virtual void OnExpose (); virtual void OnSysWM ();

  22. void PumpEvents (); int WaitEvent (); int PeepEvents (int numevents, SDL_eventaction action, Uint32 mask); int PollEvent (); int PushEvent (SDL_Event *event); void SetEventFilter (SDL_EventFilter filter); SDL_EventFilter GetEventFilter (); Uint8 EventState (Uint8 type, int state);

  23. Uint8 EnableEvent (Uint8 type); Uint8 DisableEvent (Uint8 type); Uint8 QueryEvent (Uint8 type); Uint8 *GetKeyState (int *numkeys); SDLMod GetModState (); void SetModState (SDLMod modstate); char *GetKeyName (SDLKey key); int EnableUNICODE (); int DisableUNICODE (); int QueryUNICODE ();

  24. int EnableKeyRepeat ( • int delay = SDL_DEFAULT_REPEAT_DELAY, • int interval = SDL_DEFAULT_REPEAT_INTERVAL); • int DisableKeyRepeat (); • Uint8 GetMouseState (int *x, int *y); • Uint8 GetRelativeMouseState (int *x, int *y); • Uint8 GetAppState (); • int JoystickEventState (int state);

  25. CSDLApp 的遊戲迴圈(Game Loop) InitializeApp(); while (!m_bQuit) { BeforePollEvent(); m_bQuit = ProcessNextEvent(); if (m_bQuit) break; AppMain(); } QuitApp();

  26. 最簡單的 OOSDL 程式 • #include "oosdl.h“ • CSDLApp myApp; • int main (int argc, char* argv[]) • { • myApp.InitializeSDL(); • myApp.SetScreen(); • myApp.Run(); • return EXIT_SUCCESS; • }

  27. 使用 CSDLApp 的步驟 • 宣告一個繼承 CSDLApp 的類別,在其中依所需,改寫相關的成員函式,譬如: • class CMyApp : public CSDLApp • { • // 宣告本類別所需的成員函式與資料成員 • // 依所需地改寫 CSDLApp 中的成員函式 • };

  28. 範例: oosdl04.cpp class CMySDLApp : public CSDLApp { protected: virtual bool InitializeApp (); private: CSurface background, ball; }; bool CMySDLApp::InitializeApp () { background.LoadImage ("bkg01.bmp"); ball.LoadImage ("ball.bmp"); background.Show(0, 0); ball.SetColorKey(0, 0, 0); ball.Show(192, 112); return true; } 改寫以加入本程式所需的初始化設定 本程式所需的資料成員

  29. 在主函式中,定義一個 CMyApp 的物件,譬如: • int main( int argc, char* argv[] ) • { • CMySDLApp myApp; • // 其他項目 • }

  30. 在主函式中,開始呼叫 CMySDLApp 的成員函式 InitializeSDL(),譬如: • int main( int argc, char* argv[] ) • { • CMySDLApp myApp; • myApp.InitializeSDL(); • // 其他項目 • }

  31. 接下來呼叫 CMySDLApp 的成員函式 SetScreen(),譬如: • int main( int argc, char* argv[] ) • { • CMySDLApp myApp; • myApp.InitializeSDL(); • myApp.SetScreen(); • // 其他項目 • }

  32. SetScreen() 將選擇 640x480 的視窗為螢幕物件。你可以用以下的方式將螢幕設成 1024x768 的視窗: • myApp.SetScreen(new CScreen(1024,768,0, • SDL_SWSURFACE | SDL_ANYFORMAT)); • CScreen 建構函式的宣告如下: • CScreen::CScreen (int width, int height, int bpp, Uint32 flags); • 其中的參數意義和 SDL_SetVideoMode() 相同。

  33. 最後呼叫 CMySDLApp 的成員函式 Run(),譬如: • int main( int argc, char* argv[] ) • { • CMySDLApp myApp; • myApp.InitializeSDL(); • myApp.SetScreen(); • // 其他項目 • myApp.Run(); • return EXIT_SUCCESS; • }

  34. 範例: 加入事件的處理 (oosdl07.cpp) class CMySDLApp : public CSDLApp { protected: virtual bool InitializeApp (); virtual bool AppMain (); // Events virtual void OnKeyDown (const SDL_keysym &keysym); virtual void OnKeyUp (const SDL_keysym &keysym); private: CSurface background, ball; int ball_x, ball_y; int ball_xvel, ball_yvel; int ball_speed, ball_speed_inc; };

  35. bool CMySDLApp::InitializeApp () • { • background.LoadImage("bg.png"); • ball.LoadImage("ball.png"); • ball.SetColorKey(0, 0, 0); • ball_x = (SCREEN_WIDTH - BALL_WIDTH) /2; • ball_y = (SCREEN_HEIGHT - BALL_HEIGHT) /2; • ball_xvel = 0; • ball_yvel = 0; • ball_speed = 1; • ball_speed_inc = 0; • background.Show(0, 0); • ball.Show(ball_x, ball_y); • return true; • }

  36. inline void restrict (int &x, int min, int max) • { • if (x < min) • x = min; • else if (x > max) • x = max; • } • bool CMySDLApp::AppMain () • { • if (ball_speed_inc != 0) • { • ball_speed += ball_speed_inc; • if (ball_speed < 1) • ball_speed = 1; • }

  37. if (ball_xvel != 0 || ball_yvel !=0) • { • int x_old = ball_x, y_old = ball_y; • ball_x += ball_xvel; • ball_y += ball_yvel; • restrict(ball_x, 0, SCREEN_WIDTH - BALL_WIDTH); • restrict(ball_y, 0, SCREEN_HEIGHT - BALL_HEIGHT); • if (ball_x != x_old || ball_y != y_old) • { • background.Show(0, 0); • ball.Show(ball_x, ball_y); • } • } • return true; • }

  38. void CMySDLApp::OnKeyDown (const SDL_keysym &keysym) • { • switch (keysym.sym) • { • case SDLK_UP: ball_yvel = -ball_speed; break; • case SDLK_DOWN: ball_yvel = ball_speed; break; • case SDLK_LEFT: ball_xvel = -ball_speed; break; • case SDLK_RIGHT: ball_xvel = ball_speed; break; • case SDLK_EQUALS: ball_speed_inc = 1; break; • case SDLK_MINUS: ball_speed_inc = -1; break; • case SDLK_HOME: • ball_x = (SCREEN_WIDTH - BALL_WIDTH) /2; • ball_y = (SCREEN_HEIGHT - BALL_HEIGHT) /2; • break; • default: • CMySDLApp::OnKeyDown(keysym); • } • }

  39. void CMySDLApp::OnKeyUp (const SDL_keysym &keysym) • { • switch (keysym.sym) • { • case SDLK_UP: • if (ball_yvel < 0) ball_yvel = 0; • break; • case SDLK_DOWN: • if (ball_yvel > 0) ball_yvel = 0; • break; • case SDLK_LEFT: • if (ball_xvel < 0) ball_xvel = 0; • break; • case SDLK_RIGHT: • if (ball_xvel > 0) ball_xvel = 0; • break; • case SDLK_EQUALS: • if (ball_speed_inc > 0) ball_speed_inc = 0; • break; • case SDLK_MINUS: • if (ball_speed_inc < 0) ball_speed_inc = 0; • break; • } • }

  40. int main( int argc, char* argv[] ) { CMySDLApp myApp; myApp.InitializeSDL(); myApp.SetScreen(); myApp.SetCaption(WINDOW_TITLE); myApp.Run(); return EXIT_SUCCESS; }

  41. CGameApp • 繼承 CSDLApp,並加入以下的修改 • 其中呼叫 SDL_Init (SDL_EVERYTHING) • 加入遊戲時鐘與定時器 • 預設為 Fixed Frame Rate,每秒約為 30 張畫格 • 可用下面的方法改為 Variable Frame Rate: • CMyGameApp myGameApp(false);

  42. 範例: oosdl13.cpp class BallObj : public CSurface { public: BallObj () : CSurface(), m_x(0), m_y(0) {} void SetPosition (Uint16 x, Uint16 y) { m_x = x; m_y = y; } bool Show() { return CSurface::Show(m_x, m_y); } private: Uint16 m_x, m_y; // ball screen position };

  43. class CMyGameApp : public CGameApp { public: CMyGameApp() : CGameApp() {} ~CMyGameApp () {} protected: virtual bool InitializeApp (); virtual bool AppMain (); private: BallObj redball, blueball; };

  44. bool CMyGameApp::InitializeApp () { m_pScreen->SetBackgroundColor(0, 0, 0); redball.SetPosition(0, 0); redball.LoadImage("redball.png"); redball.SetColorKey(0, 0, 0); blueball.SetPosition((SCREEN_WIDTH-BALL_WIDTH)/2, (SCREEN_HEIGHT-BALL_HEIGHT)/2); blueball.LoadImage("blueball.png"); blueball.SetColorKey(0, 0, 0); return true; }

  45. bool CMyGameApp::AppMain () • { • const float PERIOD = 6.0; // period in second • const float RADIUS = 200; // in pixels • // angular increment • double angle_inc = 2.0*M_PI* • m_pGameClock->GetFrameDefaultTime()/PERIOD; • int nFrame = m_pGameClock->GetFrameNumber()-1; • int x = RADIUS * cos(nFrame*angle_inc) - BALL_WIDTH/2 + SCREEN_WIDTH/2; • int y = RADIUS * sin(nFrame*angle_inc) - BALL_HEIGHT/2 + SCREEN_HEIGHT/2; • // Update ball position and then show it. • redball.SetPosition(x, y); • m_pScreen->Clear(); • redball.Show(); • blueball.Show(); • return true; • }

  46. int main( int argc, char* argv[] ) { CMyGameApp myGameApp; myGameApp.InitializeSDL(); myGameApp.SetScreen(); myGameApp.SetCaption(WINDOW_TITLE); myGameApp.Run(); return EXIT_SUCCESS; }

More Related