Game C++ SDL – Bài 11: Xử lý Va Chạm – Áp dụng cho đạn và threats

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

Bài số 11 chúng ta sẽ tìm hiểu về kỹ thuật xử lý và chạm. Và sau đó chúng ta sẽ áp dụng để xử lý:

+ Va chạm giữa threats và đạn của MainObject

+ Threats bị tiêu diệt và đạn của Main Object cũng sẽ bị hủy.

1. LÝ THUYẾT CƠ BẢN.

Để xử lý được va chạm trong lập trình game. chúng ta cùng phần tích xem hai đối tượng sẽ va chạm nhau trong những hoàn cảnh nào.

Về bản chất. Mỗi đối tượng đều là một image và chúng có một bounding box dành cho nó.

Tôi có 2 đối tượng đại diện bởi hai hình màu đỏ và màu đen.

Chúng ta sẽ có các dạng va chạm như sau:

1 – 2 -3 -4 là bốn dạng cơ bản để kiểm tra va chạm giữa black và Red.

còn các dạng đánh dấu x sẽ là các trường hợp đặc biệt.

Nghĩa là nếu chúng ta check được 4 trường hợp 1 – 2 – 3 và 4 thì các trường hợp còn lại cũng ok.

l là left và r là right được tính bởi giá trị X

t là top và b là bottom được tính bởi giá trị Y

Case 1:  Hình 1. Ta có điều kiện. (L2 < r < R2) đồng thời ( T2 < b < B2)

Case 2: Hình 2. Ta có điều kiên. (L2 < l < R2) đồng thời ( T2 < b < B2)

Case 3: Hình 3. Ta có điều kiện. (L2 < l < R2)  đồng thời ( T2 < t < B2)

Case 4: Hình 4. Ta có điều kiện. (L2<  r < R2)  đồng thời ( T2 < t < B2)

 

Và nếu đối RED có kích thước nhỏ hơn đối tượng right, thì chúng ta lại thêm đoạn code làm ngược lại.

Một trường hợp đặc biệt khác đó là khi 2 đối tượng có kích thước bằng nhau, khi mà hai hình trùng nhau như tấm ảnh minh họa số 2.

Như vậy lúc đó dk xảy ra là:  l1 = l2 && r1 = r2  && t1 = t2 && b1 = b2

Như vậy chúng ta sẽ có 3 khoảng code để thực hiện việc check va chạm.

2. Các step thực hiện

a. Viết một hàm xử lý va chạm dành cho hai đối tượng trong phần xử lý chung: SDLCommonFunction.

b. Định nghĩa hàm xử lý va chạm như sau:

bool SDLCommonFunc::CheckCollision(const SDL_Rect& object1, const SDL_Rect& object2) 
{
  int left_a = object1.x;
  int right_a = object1.x + object1.w;
  int top_a = object1.y;
  int bottom_a = object1.y + object1.h;

  int left_b = object2.x;
  int right_b = object2.x + object2.w;
  int top_b = object2.y;
  int bottom_b = object2.y + object2.h;

  // Case 1: size object 1 < size object 2
  if (left_a > left_b && left_a < right_b)
  {
    if (top_a > top_b && top_a < bottom_b)
    {
      return true;
    }
  }

  if (left_a > left_b && left_a < right_b)
  {
    if (bottom_a > top_b && bottom_a < bottom_b)
    {
      return true;
    }
  }

  if (right_a > left_b && right_a < right_b)
  {
    if (top_a > top_b && top_a < bottom_b)
    {
      return true;
    }
  }

  if (right_a > left_b && right_a < right_b)
  {
    if (bottom_a > top_b && bottom_a < bottom_b)
    {
      return true;
    }
  }
  
  // Case 2: size object 1 < size object 2
  if (left_b > left_a && left_b < right_a)
  {
    if (top_b > top_a && top_b < bottom_a)
    {
      return true;
    }
  }

  if (left_b > left_a && left_b < right_a)
  {
    if (bottom_b > top_a && bottom_b < bottom_a)
    {
      return true;
    }
  }

  if (right_b > left_a && right_b < right_a)
  {
    if (top_b > top_a && top_b < bottom_a)
    {
      return true;
    }
  }

  if (right_b > left_a && right_b < right_a)
  {
    if (bottom_b > top_a && bottom_b < bottom_a)
    {
      return true;
    }
  }

   // Case 3: size object 1 = size object 2
  if (top_a == top_b && right_a == right_b && bottom_a == bottom_b)
  {
    return true;
  }

  return false;
}

 

Áp dụng cho việc xử lý va chạm với Bullet và Threats.

Block Code 1: Xử lý Threats

Block Code 2: Lấy danh sách các viên đạn được bắn ra bởi plane object

Block Code 3: Kiểm tra va chạm giữa từng viên đạn và từng threats.

Block Code 4: Khi va chạm có xảy ra. Thì p_threat được reset về vị trí ban đầu và đồng thời remove viên đạn hiện tại trong plane object

3. THỰC HÀNH

Và giờ tôi sẽ thực hành trên video

_______________________________________________________

Pass Pham

 

5 thoughts on “Game C++ SDL – Bài 11: Xử lý Va Chạm – Áp dụng cho đạn và threats

  • Pingback: Game C++ Phần 2 - Bài 13: Xử lý kỹ thuật va chạm trong game

  • 27 November, 2020 at 7:57 am
    Permalink

    Exception thrown at 0x681247D8 (SDL.dll) in SDL_games.exe: 0xC0000005: Access violation reading location 0xDDDDDE09.
    khi e ban ltuc vao threat game bị đứng và nó nhảy sang lỗi này lỗi gì v a

    Reply
    • 27 November, 2020 at 7:07 pm
      Permalink

      em vào group facebook đăng lên nhé

      Reply
  • 29 September, 2021 at 1:47 am
    Permalink

    Anh có thể gợi ý cách làm về va chạm giữa đạn threat với mainObject được không ạ?

    Reply
    • 17 October, 2021 at 9:18 am
      Permalink

      thực ra nó cũng như đạn main và threat. em check thêm một điều kiên trong vòng for threat, thì lấy ra danh sách các viên đạn của từng threat, for danh sách đạn, và lấy ra rect của đạn rồi gọi va chạm với mainobject

      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.