Game C++ SDL – Bài 3: Kiến trúc cơ bản project game C++ SDL

  Chào mừng các bạn đến với chủ đề học lập trình game c++ SDL.

Bài số 3 này chúng ta sẽ cùng xây dựng và kiến trúc một project chuẩn để bắt đầu nghiên cứu về kỹ thuật lập trình game với ngôn ngữ c++ và thư viện sdl

Khi đã cấu hình được một project và load được 1 image như bài số 1 và số 2 rồi. Thì bây giờ các bạn sẽ sửa lại project đó theo một kiến trúc phân hàm như sau,

1. Include 4 thư viện chính cơ bản như sau:
#include <windows.h>
#include <string>
#include <SDL.h>
#include <SDL_image.h>
2. Khai báo biến const để định dạng các thông sốcố định.
const int SCREEN_WIDTH = 1200;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;

Như vậy trong bài số 2 chúng ta fixed cứng giá trị thì bây giờ chúng ta dùng biến constant để lưu trữ nó tiện cho việc thay đổi.

3. Chúng ta đưa biến quản lý screen và quản lý background thành các biến global.

Ngoài ra chúng ta dùng thêm một biến quản lý sự kiện.

SDL_Surface *g_screen = NULL;
SDL_Surface *g_bkground = NULL;
SDL_Event g_even;
4. Chia các chức năng chính về các hàm riêng biệt.

Áp dụng phương pháp lập trình module hóa

a. Viết một hàm Init để khởi tạo các thuộc tính ban đầu.
bool Init()
{
  if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
  {
    return false;
  }
  g_screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
  if (g_screen == NULL)
  {
    return false;
  }
  return true;
}

Sau này những khởi tạo ban đầu về font chữ, audio cũng sẽ được gọi ở hàm này.

 

b. Viết một hàm LoadImage để thực hiện việc load các image 
SDL_Surface* LoadImage(std::string file_path)
{
  SDL_Surface * load_image = NULL;
  SDL_Surface* optimize_image = NULL;
  load_image = IMG_Load(file_path.c_str());
  if (load_image != NULL)
  {
    optimize_image= SDL_DisplayFormat(load_image);
    SDL_FreeSurface(load_image);
  }
  return optimize_image;
}
c. Viết một hàm ApplySurface thực hiện load Image vào màn hình screen.
void ApplySurface(SDL_Surface* src, SDL_Surface* des, int x, int y)
{
  SDL_Rect offset;
  offset.x = x;
  offset.y = y;
  SDL_BlitSurface(src, NULL, des, &offset);
}
d. Viết một hàm giải phóng các đối tượng biến global
void CleanUp()
{
  SDL_FreeSurface(g_screen);
  SDL_FreeSurface(g_bkground);
}

 

e. Cuối cùng trong hàm main

+ Chúng ta gọi hàm Init và kiểm tra nếu thành công thì tiếp tục

+ Chúng ta gọi hàm load image để đọc image và trả kết quả vào biến g_background

+ Apply kết quả trong background vào screen. Để load image lên windows.

+ Tạo vòng lặp liên tục cập nhật image, và bắt sự kiện.

+ Hàm Update screen (SDL_Lip) sẽ liên tục cập nhật windows và giữ chương trình ở trạng thái liên tục chạy.

+ Chỉ khi có sự kiện quit thì nó mới dừng lại.

+ Khi có sự kiện quit. Chương trình kết thúc thì gọi hàm CleanUp để giải phóng cho các biến.

int main(int arc, char* argv[])
{
  bool is_quit = false;
  if (Init() == false)
   return 0;

  g_bkground = LoadImage("bkground.png");
  if (g_bkground == NULL)
  {
    return 0;
  }

  ApplySurface(g_bkground, g_screen, 0, 0);

  while (!is_quit) 
  {
    while (SDL_PollEvent(&g_even)) 
    {
      if (g_even.type == SDL_QUIT)
      {
        is_quit = true;
        break;
      }
    }
    if ( SDL_Flip(g_screen) == -1)
    return 0;
  }
  CleanUp();
  SDL_Quit();
  return 1;
}

 

Và khi thực hiện xong, chúng ta build project chạy thử.

Chương trình sẽ ra kết quả như sau nếu thành công.

 

+ Do có vòng while nên chúng ta ko cần gọi hàm trễ 5000 như bài số 2 và chương trình sẽ chạy mãi mãi cho đến khi chúng ta sử dụng ESC hoặc ấn vào nút destroy.

Thực hành bằng video để làm từng bước dễ hiểu

____________________________________________________________________

Pass Pham

14 thoughts on “Game C++ SDL – Bài 3: Kiến trúc cơ bản project game C++ SDL

  • 27 March, 2019 at 10:48 pm
    Permalink

    em chạy cơ mà báo là ========== Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========, cho em hỏi cách sửa vs ạ

    Reply
    • 28 March, 2019 at 9:27 am
      Permalink

      em vào group post bài lên anh check cho

      Reply
    • 28 October, 2020 at 6:08 am
      Permalink

      cái đó ko cần sửa đâu

      Reply
  • 8 May, 2019 at 8:40 am
    Permalink

    1>—— Build started: Project: CodeSoanSan, Configuration: Debug Win32 ——
    1>Main.cpp
    1>MSVCRTD.lib(initializers.obj) : warning LNK4098: defaultlib ‘msvcrt.lib’ conflicts with use of other libs; use /NODEFAULTLIB:library
    1>SDLmain.lib(SDL_win32_main.obj) : error LNK2019: unresolved external symbol __imp__fprintf referenced in function _ShowError
    1>SDLmain.lib(SDL_win32_main.obj) : error LNK2019: unresolved external symbol __imp____iob_func referenced in function _ShowError
    1>D:\04 Lap trinh C\LibSdl2 game\Code Chuan\CodeSoanSan\Debug\CodeSoanSan.exe : fatal error LNK1120: 2 unresolved externals
    1>Done building project “CodeSoanSan.vcxproj” — FAILED.
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    Reply
    • 9 May, 2019 at 9:56 am
      Permalink

      nếu em xài VS2017 thì em vào đọc bài 1 trong seri 1. đoạn gần cuối có note về VS2017 đó

      Reply
  • 16 April, 2020 at 6:32 am
    Permalink

    Em chạy mà nó giống bài 2 tự thoát ra là sao vậy ạ?
    em code trên VS 2019

    Reply
  • 16 April, 2020 at 7:11 am
    Permalink

    em sửa đc rồi ạ :)))

    Reply
    • 28 June, 2022 at 8:23 pm
      Permalink

      sửa sao v bạn mik chạy code nó lên r tắt lluoon

      Reply
  • 2 August, 2020 at 9:14 am
    Permalink

    ad ơi cho em hỏi là lúc em khởi chạy thì không hiện ảnh chỉ ra 1 màn hình đen ad giúp em với được không ạ

    Reply
    • 3 August, 2020 at 8:17 am
      Permalink

      Vừa có một bạn cũng bị lỗi như em, nguyên nhân là do đoạn code SDL_Flip gần cuối, để ngoài vòng while, nên nó ko đẩy được dữ liệu vào screen,
      em kiểm tra xem em có bị lỗi như vậy không
      Đúng là: Nó phải ở trong vòng while ?

      Reply
    • 11 February, 2021 at 9:03 am
      Permalink

      có thể do sai tên ảnh nha
      chú ý định dạng ảnh là png hay jpg nếu png thì đuôi ảnh là .png tương tư như jpg nha ^_^

      Reply
  • 29 November, 2020 at 8:19 pm
    Permalink

    Unhandled exception at 0x6812591F (SDL.dll) in Project2.exe: 0xC0000005: Access violation reading location 0x0000013C.
    loi nay la sao vay ad

    Reply
    • 1 December, 2020 at 6:16 am
      Permalink

      vào group facebook show lên nhé

      Reply
  • 14 October, 2021 at 4:20 pm
    Permalink

    cho em hỏi là tại sao em chạy chương trình vẫn ra ảnh bth nhưng mà đến khi em bấm phím ESC không được vậy ạ, em copy nguyên code của anh

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.