2011-01-14 36 views
6

Tôi đang cố gắng thiết kế một thuật toán phát hiện va chạm cho một khách hàng Minecraft tùy chỉnh mà tôi đang thực hiện. Về cơ bản, toàn bộ thế giới được tạo thành từ các hình khối, và người chơi (hoặc máy ảnh) cần phải có khả năng đứng vững và di chuyển chống lại những khối này. Kết quả tôi muốn được minh họa trong hình ảnh này: imagePhát hiện va chạm bằng cách trượt trên mặt phẳng trong XNA

Dòng màu xanh lá cây là vector chuyển động của người chơi. Khi người chơi đang chải lên mặt phẳng của một trong các hình khối, tôi muốn vectơ thay đổi thành hình vuông góc với mặt phẳng. Tuy nhiên, vectơ nên giữ tất cả vận tốc của nó theo hướng của máy bay, nhưng mất tất cả vận tốc về phía mặt phẳng.

Tôi hy vọng tôi đã làm rõ câu hỏi của mình. Cách tốt nhất và hiệu quả nhất để thực hiện một hệ thống phát hiện va chạm như thế này là gì? Ngoài ra, một hệ thống như thế này có cho phép một thành phần trọng lực đơn giản không?

EDIT: Quên đề cập đến, các hình khối được lưu trữ trong mảng ba chiều, [x, y, z].

+0

Tôi thích câu hỏi này. Tôi khuyên bạn nên đăng lên gamedev.stackexchange.com. Tôi tưởng tượng đây là một vấn đề phổ biến trong phát triển trò chơi. –

+0

@BigDave - Ồ, tôi không biết có một trang web đặc biệt để phát triển trò chơi. Stack Exchange thực sự đang phát triển. – Bevin

Trả lời

1

Cách tiếp cận đơn giản để thực hiện điều này là phát hiện va chạm của quả bóng và mặt phẳng. Tính toán độ sâu thâm nhập, đây là khoảng cách mà quả bóng đã thực sự đi qua mặt phẳng, và đẩy bóng trở lại theo hướng bình thường của máy bay.

Điều này sẽ có tác dụng đưa bóng lên bề mặt của mặt phẳng. Nếu bạn làm điều này cho mỗi khung hình, quả bóng sẽ trượt dọc theo mặt phẳng một cách hiệu quả, giả sử tất nhiên là vector vận tốc của quả bóng không song song với bình thường của mặt phẳng.

Trường phát hiện va chạm lớn và phức tạp, và tùy thuộc vào trò chơi của bạn, bạn phải xác định điều gì là đủ cho yêu cầu của bạn về mức độ hiện thực mà bạn yêu cầu và yêu cầu hiệu suất. Bạn nên luôn luôn đi cho các giải pháp đơn giản mà cung cấp cho một phản hồi đủ thực tế, tùy thuộc vào trò chơi nó thường không phải là hoàn hảo.

Về cơ bản bạn nên phá vỡ phát hiện va chạm của bạn thành 2 giai đoạn thường được gọi là giai đoạn rộng và pha hẹp. Giai đoạn rộng có thể đơn giản như thực hiện kiểm tra hộp giới hạn nhanh để xác định va chạm tiềm ẩn và sau đó gửi những va chạm tiềm năng đến phát hiện va chạm pha hẹp để thực hiện các kiểm tra chi tiết hơn, nơi bạn xác định xem có xung đột hay không độ sâu va chạm. Nếu bạn có nhiều đối tượng thì pha rộng có thể sử dụng một số loại chỉ mục quadtree để chỉ chọn các khối trong vùng lân cận của đối tượng của bạn để thực hiện phát hiện xung đột.

+0

@ Chris Taylor - Vâng, tôi nghĩ nó có thể đơn giản như vậy. Làm thế nào để bạn nghĩ rằng tôi nên đi về tính toán nó? Tôi có nên lặp lại thông qua một tập nhỏ các khối và kiểm tra xem người chơi có đang giao nhau với một trong số chúng không? – Bevin

+0

@Bevin, trả lời của tôi cho câu hỏi phụ của bạn có một chút dài, vì vậy tôi vừa cập nhật câu trả lời với một chút thông tin. Hi vọng điêu nay co ich. –

+0

@ Chris Taylor - Vâng, tôi biết kích thước của người chơi, vì vậy tôi có thể chỉ đơn giản là lặp qua các khối được, nói rằng, nhiều nhất là 4 khối đi. Điều đó sẽ cung cấp đủ không gian để phát hiện. Làm cách nào để phát hiện người chơi đã giao nhau đến mức nào và bao nhiêu để đẩy anh ta ra khỏi khối? – Bevin

0

Trong một thế giới của khối hình khối Trục, điều này thực sự dễ dàng. Thật dễ dàng để nghĩ rằng bạn cần một cái gì đó phức tạp, nhưng trong thực tế nó thực sự đơn giản. Đây là từ kinh nghiệm sau khi viết bản sao minecraft của riêng tôi.

Đây là cách:

position.X += velocity.X; 
if(colliding()) 
    position.X -= velocity.X; 

position.Y += velocity.Y; 
if(colliding()) 
    position.Y -= velocity.Y; 

position.Z += velocity.Z; 
if(colliding()) 
    position.Z -= velocity.Z; 

Dưới đây là đoạn mã để tìm ra nếu bạn đang va chạm hay không:

bool colliding() 
{ 
    int minX = Position.X - size.X/2; 
    int minY = Position.Y - size.Y/2; 
    int minZ = Position.Z - size.Z/2; 

    int maxX = Position.X + size.X/2; 
    int maxY = Position.Y + size.Y/2; 
    int maxZ = Position.Z + size.Z/2; 

    for (int x = minX; x <= maxX; x++) 
    for (int y = minY; y <= maxY; y++) 
     for (int z = minZ; z <= maxZ; z++) 
     { 
     if(blockType[x, y, z] != 0) 
      return true; 
     } 

    return false; 
} 
+0

Điều này sẽ không hoạt động nếu trình phát không được căn chỉnh. Điều gì sẽ xảy ra nếu người chơi chỉ hơi cắt một trong các máy bay? Sau đó, ông sẽ được đẩy ra xa hơn cần thiết. – Bevin

+0

Người chơi có thể được coi là một hộp liên kết trục không rotationg vì mục đích va chạm. Nó hoạt động tốt. Tôi biết những gì bạn có ý nghĩa, nhưng nó không phải là đáng chú ý của người chơi. Tôi khuyến khích OP để thử. – Hannesh

Các vấn đề liên quan