Làm thế nào tôi có thể dễ dàng thực hiện swinging trong một trò chơi platformer?


9

Tôi đang phát triển một trò chơi trong đó người chơi có thể sử dụng dây thừng để xoay (giống như những gì Người nhện hoặc Bionic Commando đã làm) và tôi gặp vấn đề khi thực hiện hành vi này. Bất cứ ai có thể giúp tôi làm thế nào để làm điều này, ý tôi là các công thức vật lý và vv Cho đến bây giờ tôi đã đưa ra 3 ý tưởng. Một là sử dụng mùa xuân, nhưng nó tiêu tốn rất nhiều thời gian và đôi khi nó rất khó khăn. Hai người còn lại đang cố gắng tính bước tiếp theo (một thông qua tính toán năng lượng tiềm năng và một thông qua tính toán mô-men xoắn) và cả hai gần như sụp đổ bất cứ khi nào diễn viên đang cố gắng xoay.

Đây là mã tôi đã viết để tính mô-men xoắn:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

Có liên quan (về việc tạo ra một sợi dây): Phát hiện va chạm dây 2D
doppelgreener

@JonathanHobbs câu trả lời trong câu hỏi đó chính xác là cách tôi cố gắng thực hiện sợi dây của mình với một ngoại lệ, vì trường hợp va chạm là không mong muốn trong trường hợp của tôi, tôi đặt mọi bộ phận dây như một cảm biến để chúng có thể di chuyển tự do mà không bị kẹt vào nhau.
Ali1S232

Điều gì về con lắc đơn giản cho dây + một số hình ảnh động mà apish Ropeish? Tôi không tin rằng những trò chơi cũ như Bionic Commando có thứ gì khác ngoài con lắc.
dùng712092

@user mà ý tưởng con lắc nên hoạt động tốt. nhưng trong trường hợp của tôi, do chuyển động nhanh của người chơi hoặc do triển khai kém của tôi, nó đã không cho kết quả tốt.
Ali1S 232

@Gajet thử thực hiện một số bản vẽ gỡ lỗi cho đến khi bạn hiểu đúng không? Dòng con lắc này có thể được thực hiện dưới dạng một hộp đủ mỏng trong Box2D để va chạm (và có thể loại trừ nó khỏi vật lý và di chuyển bằng tay?).
dùng712092

Câu trả lời:


6

Nếu bạn muốn một cú xoay cứng, do đó, khoảng cách đến điểm xoay là không đổi, chỉ cần coi nhân vật là một điểm trên một vòng tròn có tâm ở điểm xoay. Cung cấp cho anh ta một tốc độ góc (dọc theo vòng tròn). Mỗi khung gia tốc góc phải là accelerationDueToGravity * cos(angleOfPlayerOnCircle)(với 0 độ nghiêng phải).

Nếu bạn muốn sợi dây dài hơn / ngắn hơn, bạn có thể sử dụng sơ đồ trên và chỉ cần thay đổi bán kính mỗi khung.


bạn trả lời là lần thử thứ hai của tôi nhưng nó di chuyển với tốc độ nhanh hơn nhiều nên tôi sẽ chỉnh sửa câu hỏi của mình và thêm mã của tôi để bạn có thể nhận ra vấn đề đang ở đâu.
Ali1S232

3

Sau nhiều lần thử tôi đã đi với box2d.

Có rất nhiều sự chấp thuận cho mô phỏng này hoặc ít nhất tôi đã tìm thấy 2:

  1. một là sử dụng một số hình dạng vòng tròn và kết nối chúng bằng các khớp ở xa.
  2. và một cái khác là hình chữ nhật cho chính chuỗi và sau đó gắn chúng bằng cách sử dụng khớp xoay

trong mỗi senario bạn phải có một ancher (trong trường hợp của tôi là một hộp tĩnh). Sẽ tốt hơn nếu bạn giảm trọng lượng của các bộ phận dây (bạn sử dụng hình dạng vòng tròn hoặc hình chữ nhật), ví dụ để có vật lý thực tế hơn, tôi đặt mật độ của chúng thành 0,1 và đối với hộp được kết nối ở cuối sợi dây tôi đã sử dụng mật độ 10.

một điều nữa bạn cần lo lắng về cách đoạn dây của bạn phản ứng với nhau. tôi chỉ muốn sợi dây của mình di chuyển tự do trong cảnh nên tôi đã đánh dấu tất cả đồ đạc dây là cảm biến. bạn có thể cần sự chấp thuận khác nhau.

điều tiếp theo bạn phải lo lắng là số lần lặp mà bạn đang theo dõi cập nhật thế giới: đối với đoạn dây thấp (nhiều nhất có thể là 8), không cần sử dụng giá trị lặp cao có thể là 10/10 mà chính box2d đã đề xuất là đủ nhưng nếu bạn tăng số lượng phân đoạn, ví dụ tôi đã thử 30 phân đoạn, với số lần lặp thấp, dây của bạn dường như tăng chiều dài hơn mức cần thiết, vì vậy bạn cần có thể lặp lại 40/40 lần để giải quyết các tình huống đó.

Sau một số thử nghiệm, có vẻ như hộp 2d được thiết kế cho các cảnh có kích thước đối tượng từ 0,1m đến 10m và kích thước tối đa được đề xuất cho các cảnh lớn là khoảng 50mx50m. Vì vậy, về cơ bản, bạn cần phải thu nhỏ đối tượng của mình xuống để khớp với các tham số này. trong trường hợp của tôi, lần đầu tiên tôi đã cố gắng chuyển trực tiếp các vị trí pixel sang box2d nhưng có vẻ như có một số giới hạn tốc độ ngăn không cho thế giới di chuyển nhanh như vậy, vì vậy tôi phải điều chỉnh cảnh của mình khoảng 64 lần để có kết quả tốt nhất. mặc dù tôi đã không tự kiểm tra nhưng có một số giới hạn trong box2d ngăn bạn sử dụng các cảnh lớn hơn. ví dụ: có một giá trị được xác định trong b2Setting.htệp, #define b2_maxTranslation 2.0fbạn có thể thay đổi cài đặt box2d nhưng có vẻ như không được khuyến nghị.


Tại sao sai với box2d để kiếm cho tôi một downvote ??
Ali1S 232

Điều này không trả lời câu hỏi. Ít nhất hãy viết cách bạn làm cho nó hoạt động bằng Box2D.
bummzack

@bummzack: ok tôi sẽ thêm câu đó vào câu trả lời của mình
Ali1S232

Nếu bạn chấp nhận đây là câu trả lời của bạn, câu hỏi của bạn nếu thiếu sót. Vật lý dây phân đoạn khác nhiều so với những gì bạn mô tả.
Tấn

@attackingHobo: quesiton đã đúng vào thời điểm đó nhưng khi tôi chuyển đổi mã của mình sang box2d, tôi đã tìm ra ở đó mà không cần nỗ lực nhiều, tôi có thể thực hiện vật lý dây được phân đoạn. và nó không khác nhau nhiều lắm, hãy nghĩ đến câu hỏi của tôi chỉ là một đoạn của một sợi dây được phân đoạn. và hầu hết tất cả các giải pháp của tôi là cách để thực hiện dây kiểu vòng tròn mà không cần box2d.
Ali1S 232

2

Bạn đã xem xét làm chậm tốc độ của chuyển động xoay dựa trên khoảng cách dây thừng từ đường thẳng (trung tâm) bao xa?


đối với cả 3 chiều dài của sợi dây là một trong những thông số tôi đã sử dụng để tính tốc độ xoay. Nhưng tôi không thể đảm bảo rằng tôi đã sử dụng nó một cách chính xác. Tôi vừa mới thực hiện một số tính toán vật lý và áp dụng phiên bản đã giải của họ vào trò chơi.
Ali1S232

Càng ở xa trung tâm, độ trễ càng dài trước khi chuyển động tiếp theo của đu dây. Bạn cũng có thể nhân giá trị ABSolute của độ trễ bằng 0,28 (bạn sẽ phải thử nghiệm điều này).
Randolf Richardson

Tôi không thể hiểu những gì bạn đang cố nói, khi tôi tính bước tiếp theo, tôi có một số giá trị không đổi cho delta_time và sử dụng tất cả các tham số tôi có (như tốc độ chiếm ưu thế, vị trí chiếm ưu thế, độ dài dây, v.v.) để tính toán vận tốc mới, và sau đó thêm vận tốc này nhân với delta_time vào vị trí cuối cùng để tạo vị trí mới. nếu bạn có ý gì khác xin vui lòng cung cấp đầy đủ chi tiết trong câu trả lời của bạn.
Ali1S232

1

Khi người chơi xa hơn chiều dài của sợi dây, người chơi sẽ ngay lập tức bị đẩy lùi với một lực bằng khoảng cách mà anh ta đã vượt qua. Điều này sẽ làm việc mà không cảm thấy hồi xuân, và sẽ cảm thấy trực quan cho người chơi. Bạn có thể phải điều chỉnh vật lý của bạn để có được kết quả tốt nhất cho trò chơi của bạn mặc dù.

Khi dây được gắn. Lưu một maxLengthgiá trị.

Mỗi bản cập nhật, kiểm tra distancegiữa playerattachPoint

Nếu distanceít hơn maxLengthbản cập nhật thông thường, không có hiệu ứng từ dây.

Nếu khoảng cách lớn hơn maxLength, hãy tìm normaltừ người attachPointđến. Nhận sự khác biệt giữa distancemaxLength. Thêm vào playerVelocity, normalnhân với sự khác biệt.

Mã giả:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

Vì vậy, mã tôi đã chỉnh sửa vào câu trả lời của bạn (xin lỗi về điều đó nhưng tôi không tìm thấy nơi nào tốt hơn để thêm nó) mã mà bạn đang đề xuất?
Ali1S 232

Tôi đã phê duyệt bản chỉnh sửa, và vâng tôi nghĩ rằng nó nên như vậy. Mặc dù tôi đã sử dụng vật lý dây trước đây và sử dụng một cách phức tạp hơn nhiều để làm điều tương tự, vì điều đó tôi không hoàn toàn chắc chắn rằng mã này sẽ hoạt động đúng, nhưng tôi nghĩ rằng nó nên, và ngay cả khi nó không, nó sẽ giúp bạn 95 % đường đến đó.
Tấn

sau một số lần thử, tôi đoán tôi sẽ thử dùng box2d cho vấn đề này và nhân tiện bạn phải thay đổi mã đó để bạn có dx = player.x - attachpoint.xdy = player.y - attachpoint.y.
Ali1S232

1

Nếu bạn nhìn vào http://www.cocos2d-iphone.org/archives/1112 thì có một sợi dây với thân cứng được gắn vào đầu sợi dây. Nó sử dụng Box2D cho động cơ vật lý. Nếu bạn nhìn vào mã nguồn, tôi chắc chắn bạn có thể triển khai nó bằng bất kỳ ngôn ngữ nào bạn muốn.

Ngoài ra, liên kết ở trên với câu hỏi Rope là của tôi và bản demo này (liên kết được cung cấp) ở trên thực sự hữu ích.

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.