Làm thế nào để tạo ra một loại khớp rất cụ thể trong Farseer?


7

Biên tập

Vấn đề được giải quyết (xem câu trả lời của Drackir). Đây là bản demo về những gì tôi đã cố gắng đạt được với khớp này. Thông tin thêm về kịch bản về câu hỏi khác này .


Vấn đề

Tôi đang cố gắng tạo ra một loại khớp rất cụ thể trong Farseer hoạt động như thế này:

  • Các đối tượng phải luôn giữ khoảng cách giống nhau giữa chúng trong cả hai trục X và Y.
  • Dịch - Va chạm với một trong các đối tượng sẽ di chuyển toàn bộ nhóm lại với nhau, nhưng nhóm không được xoay - chỉ các đối tượng riêng lẻ có thể xoay quanh tâm của chúng do mô-men xoắn.
  • Xoay - Các đối tượng phải luôn có cùng một phép quay. Một vụ va chạm với một trong các đối tượng sẽ làm cho tất cả những người khác xoay cùng một lượng chính xác.

Đây là một hình ảnh:

nhập mô tả hình ảnh ở đây

Nếu không có cách nào để đạt được điều này với Farseer, tôi sẽ làm cách nào để mở rộng nó để tạo ra một kiểu tham gia mới hoạt động như thế này? Về cơ bản, tôi muốn mọi người cư xử như một "bản sao" của những người khác, nhưng với sự bù trừ cố định giữa họ.


Tôi không chắc chắn về hệ thống cụ thể này, nhưng bạn có thể tắt động học cho "bóng ma" và di chuyển / xoay nó bằng tay không?
Tetrad

Điều đó cũng sẽ vô hiệu hóa các va chạm trên con ma? Có lẽ ma không phải là sự tương tự tốt nhất cho nó - có lẽ là một bản sao.
David Gouveia

Tức là va chạm với bản sao cũng sẽ ảnh hưởng đến cơ thể chính (theo cách chính xác tương tự). Đề nghị của bạn sẽ làm việc trong trường hợp đó?
David Gouveia

Đánh bại tôi, có lẽ là không.
Tetrad

Câu trả lời:


6

Ok, sau khoảng hai giờ mày mò tôi đã xoay sở để làm điều này nhưng nó đòi hỏi phải thêm một số cơ thể phụ. Bạn có thể muốn trích xuất nội dung này thành một phương thức / lớp nhưng ý tưởng cơ bản là:

  1. Tạo những gì tôi gọi là cơ quan "chủ sở hữu" cho các đối tượng của bạn. Các cơ quan này chia sẻ kích thước và vị trí của các "đối tượng" của bạn nhưng không tham gia vào các vụ va chạm. Về cơ bản, chúng là bản sao.

    //Create "Main" (center) body
    _bodyMain = BodyFactory.CreateRectangle(World, 5f, 5f, 1f);
    _bodyMain.BodyType = BodyType.Dynamic;
    _bodyMain.Position = new Vector2(2, 2);
    //Create "MainHolder"
    _bodyMainHolder = BodyFactory.CreateRectangle(World, 5f, 5f, 1f);
    _bodyMainHolder.BodyType = BodyType.Dynamic;
    _bodyMainHolder.CollisionCategories = Category.None; //Prevents collisions
    _bodyMainHolder.Position = new Vector2(2, 2);
    _bodyMainHolder.IsSensor = true;
    //See http://farseerphysics.codeplex.com/discussions/222524 for why they're sensors
    _bodyMainHolder.FixedRotation = true;
    //Note: Only add FixedRotation for the main one, leave it off of the other
    //      holders. I'll explain later.
  2. Đính kèm mỗi người giữ vào "mainHolder" bằng cách sử dụng a WeldJoint. Điều này sẽ ngăn họ di chuyển khỏi nhau. Trên FixedRotationmainHolder ngăn chúng quay. Tôi không biết có lỗi trong trò hề hay không nhưng nếu bạn thêm một WeldJointvà cả hai cơ thể FixedRotation == truethì khớp không hoạt động bình thường. Đây là lý do tại sao chỉ có chủ sở hữu chính có .FixedRotation = true.

    //Weld the holders together so they don't move. Assumes another holder is defined
    //  for the object on the right side (bodyRightHolder).
    JointFactory.CreateWeldJoint(World, _bodyMainHolder, _bodyRightHolder,
    _bodyRightHolder.Position - _bodyMainHolder.Position, Vector2.Zero);
  3. Đính kèm các đối tượng "đối tượng" của bạn với chủ sở hữu tương ứng của họ bằng RevoluteJoints. Điều này khóa các đối tượng của bạn với chủ sở hữu nhưng cho phép chúng xoay tự do.

    //Lock the actual bodies to the holders
    JointFactory.CreateRevoluteJoint(World, _bodyMainHolder, _bodyMain, Vector2.Zero);
    JointFactory.CreateRevoluteJoint(World, _bodyRightHolder, _bodyRight, Vector2.Zero);
  4. Làm cho các vật thể thật của bạn xoay khớp với nhau bằng cách gắn một khớp góc. Lưu ý: bạn không phải gắn khớp góc với từng cặp đối tượng. Chỉ cần thêm một khớp góc vào thân chính và thân kia và các phép quay sẽ dịch trên tất cả các đối tượng.

    //Make them rotate the same as each other
    JointFactory.CreateAngleJoint(World, _bodyMain, _bodyRight);

Đó là nó! Chỉ cần thêm mã bổ sung cho từng đối tượng / đối tượng khác mà bạn muốn và nó sẽ xử lý phần còn lại. Đây là một hình ảnh để minh họa thử nghiệm của tôi:Hình ảnh ví dụ của các cơ quan kiểm tra.

Ở đây bạn sẽ thấy các cơ thể màu xanh lá cây là chủ sở hữu. Chúng không xoay hoặc va chạm và được hàn lại với nhau. Các cơ thể màu vàng và đỏ là "đối tượng" của bạn (màu vàng là chính). Bạn có thể thấy rằng chúng được xoay theo cùng một lượng và đang xoay quanh các chủ sở hữu tương ứng của chúng. Ngoài ra, chỉ có các cơ thể màu đỏ và màu vàng tham gia vào các vụ va chạm. Tôi tin rằng điều này đáp ứng cả ba điều kiện của bạn ở trên.

Ví dụ làm việc

Nếu bạn tải lên giải pháp "Samples XNA" của Farseer và tìm SimpleDemo1.cs (dự án "Samples XNA"> "Samples"), tôi sẽ viết lại ( mã ở đây ) để kiểm tra.

Hi vọng điêu nay co ich. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi.


Có vẻ như vẫn còn một mảnh còn thiếu của câu đố. Làm thế nào để ngay lập tức di dời toàn bộ hệ thống đến một vị trí khác trên thế giới. Tôi cần phải có cái này để "bọc" các vật thể xung quanh viền màn hình. Chỉ cần đặt vị trí trên giá đỡ chính là không hoạt động.
David Gouveia

Không bao giờ trả lời câu hỏi trước, nó dường như hoạt động nếu di chuyển tất cả các chủ sở hữu và cơ quan chính cùng một lúc.
David Gouveia

Vui mừng được giúp đỡ và, vâng, bạn cần phải di dời tất cả các cơ thể. Bạn có thể xây dựng nó thành một lớp và lưu trữ các vị trí tương đối với cơ thể chính ( Vector2sự khác biệt giữa vị trí cơ thể và cơ thể chính). Sau đó định vị lại vị trí chính và chỉ cập nhật vị trí của chúng so với vị trí chính.
Richard Marskell - Drackir

Đó là khá nhiều những gì tôi đã làm. :)
David Gouveia

0

Thật không may, tôi không thể kiểm tra câu trả lời này vì tôi đang sử dụng điện thoại ngay bây giờ, vì vậy xin lỗi nếu nó không hoạt động như tôi mong đợi.

Tôi nghĩ rằng bạn có thể sử dụng một số khớp hiện có để đạt được những gì bạn muốn. Tạo một cơ thể không có hình học va chạm ở góc tam giác của bạn, sau đó bạn có thể sử dụng ba khớp khoảng cách để đạt được bản dịch bạn muốn. Sau đó, nếu bạn kết nối hai cơ thể có thể va chạm với nhau bằng khớp góc cố định, chúng sẽ xoay cùng nhau.


Hiện tại tôi cũng có một chút thời gian ngắn và sẽ thử nó vào tối nay. Nhưng mặc dù ví dụ của tôi chỉ có hai cơ thể, tôi thực sự sẽ cần một cái gì đó phức tạp hơn thế này, với 9 cơ thể được kết nối thay thế . Ý tưởng của bạn vẫn còn áp dụng?
David Gouveia

@David: Trông thật ... thú vị. Bạn có thể nói thêm về những gì bạn đang cố gắng đạt được với thiết lập này không? Tôi tự hỏi nếu có thể không có cách nào khác để đạt được những gì bạn muốn.
Ilmari Karonen

@IlmariKaronen Có một liên kết ở cuối câu hỏi của tôi với một câu hỏi khác mô tả chính xác những gì tôi đang cố gắng đạt được. Về cơ bản, tôi đang cố gắng xử lý vật lý một cách chính xác trong môi trường 2D, nơi các cơ thể có thể "quấn" xung quanh viền và xuất hiện đồng thời ở một số cạnh của màn hình.
David Gouveia

@Martin Tôi vẫn sẽ không có thời gian để kiểm tra cái này hôm nay, vì vậy tôi sẽ báo cáo lại vào ngày mai.
David Gouveia

Được rồi, tôi đã thử điều này ngay bây giờ nhưng không thể làm cho nó hoạt động. Vấn đề là tôi muốn ngăn toàn bộ hệ thống quay. 3 khớp khoảng cách (cũng có thể được thay thế bằng 2 khớp hàn) giữ cho hệ thống cứng nhưng không ngăn nó quay.
David Gouveia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.