Lỗi logic va chạm 2 vật thể hình chữ nhật

Có anh nào biết SFML hoặc biết về làm game không giúp đỡ em với ạ.
Vấn đề hiện tại em đang xử lí va chạm giữa 2 vật thể hình chữ nhật. Tuy nhiên thì đối với va chạm 2 cạnh bên không sao nhưng khi va chạm 2 cạnh dưới thì phát sinh lỗi. Em dùng tạm cái hình để mô tả cho dễ hiểu vì em cũng chưa biết cách mô tả.


Em muốn nhân vật (màu đỏ) va chạm với wall(màu trắng viền đen) thì không di chuyển nữa mà dừng luôn ở vị trí va chạm nhưng khi va chạm trên dưới thì nó lại bị chuyển sang va chạm cạnh trái (em debug thấy được). Em đoán là sai ở điều kiện va chạm nhưng chưa nghĩ ra tại sao sai và sửa kiểu gì.
Điều kiện va chạm cạnh trái(mốc là tường) của em :

if(player.getGlobalBounds().left < walls[i].getGlobalBounds().left
   && player.getGlobalBounds().left + player.getGlobalBounds().width < walls[i].getGlobalBounds().left + walls[i].getGlobalBounds().width
   && player.getGlobalBounds().top < walls[i].getGlobalBounds().top + walls[i].getGlobalBounds().height
   && player.getGlobalBounds().top + player.getGlobalBounds().height > walls[i].getGlobalBounds().top
   ){
    currentVelocity.x *= -0.0 ;
    player.setPosition(walls[i].getGlobalBounds().left - player.getGlobalBounds().width , player.getGlobalBounds().top);
    std::cout << "left!" << i << std::endl;
}

Full code : https://pastebin.com/ui57M7Xb
P/s: Em cho vận tốc về 0 là do ban đầu em định đảo ngược vẫn tốc để cho vật thể chuyển động ngược nhưng khi gặp lỗi đổi về 0 cho dễ quan sát.
Có thắc mắc gì về câu hỏi của em mong mọi người cmt ạ.
Ai biết em sai ở đâu thì hướng dẫn em với ạ. Cảm ơn mọi người đã đọc :grin:

Edit 1 : Hiện tại em đã tìm ra được lí do lỗi là do khi W thì nhân vật dịch lên 1 đoạn và va chạm với vật thể. Tuy nhiên trong 1 số trường hợp nhất định thì pha đi lên trong tíc tắc đó lại khiến cho điều kiện va chạm bên trái thỏa mãn và làm vật dịch sang trái. Em đã thử đảo điều kiện check cạnh trên dưới lên trên nhưng làm thế thì va chạm cạnh trái phải là fail.

6 Likes

[OFF-TOPIC]

Trong đoạn trích code của em, em gọi khá nhiều player.getGlobalBound()walls[i].getGlobalBounds(). Không biết khi gán 2 object này vào biến riêng thì có tốt hơn không nhỉ, chứ gọi nhiều lần method(?) thì cũng khá tốn thời gian :thinking:

auto player_bound = player.getGlobalBounds();
auto wall_bound = walls[i].getGlobalBounds();
if(player_bound.left < wall_bound.left
   && player_bound.left + player_bound.width < wall_bound.left + wall_bound.width
   && player_bound.top < wall_bound.top + wall_bound.height
   && player_bound.top + player_bound.height > wall_bound.top
   ){
    currentVelocity.x *= -0.0 ;
    player.setPosition(wall_bound.left - player_bound.width , player_bound.top);
    std::cout << "left!" << i << std::endl;
}
6 Likes

Em cảm ơn anh ạ. Em sẽ chú ý việc này nhưng có lẽ mai mới sửa vào code được ạ. 🤦

2 Likes

Chào em,

Em có thể tham khảo thuật toán Swept AABB để xây dựng vật lí trong game của mình nhé.

8 Likes

Em cảm ơn anh/chị nhiều ạ. Em giải quyết được rồi ạ.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?