Làm thế nào tôi có thể quạt đều một tay bài?


20

Đưa ra một bộ thẻ chơi (hình ảnh hình chữ nhật có chiều rộng và chiều cao) làm thế nào tôi có thể xoay và định vị từng thẻ sao cho chúng xuất hiện theo mô hình 'quạt', giống như bạn sẽ cầm một lá bài trong đời thực. Toán học nào là cần thiết để làm điều này?

CẬP NHẬT

Đây là bản cuối cùng, trong triển khai trình duyệt bằng JavaScript: https://cosmicrealms.com/blog/2013/03/16/hand-of-cards/http://jsfiddle.net/tyyvk/108/


9
Thưa bạn, dường như bạn có quá nhiều con át chủ bài trong tay. Hãy bước ra khỏi bàn.
Tomas Andrle

Fiddle cần được cập nhật để sử dụng phiên bản mới hơn của MooTools.
tomdemuyt

Câu trả lời:


30

Học thuyết

Vì bạn không chỉ định nền tảng nào bạn đang thực hiện điều này, tôi sẽ đưa ra mô tả về thuật toán theo cách không thể biết ngôn ngữ:

  1. Đầu tiên xếp chồng từng thẻ lên nhau bằng cách cho chúng cùng một vị trí ban đầu.
  2. Sau đó, đối với mỗi thẻ áp dụng một vòng quay (thường tập trung quanh một trong các góc dưới cùng , nhưng việc di chuyển nguồn gốc này xung quanh sẽ rất cần thiết cho phép bạn điều chỉnh giao diện của quạt).
  3. Tăng góc xoay giữa mỗi cuộc gọi , tùy thuộc vào số lượng thẻ và mức độ bạn muốn chúng được trải đều.

Việc xoay được tập trung xung quanh một trong các góc dưới cùng của thẻ (hoặc gần góc) nên rõ ràng khi nhìn vào nó:

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


Thực hiện

Đối với cách thực hiện điều này, nó phụ thuộc vào nền tảng của bạn. Trên XNA, bạn chỉ cần sử dụng tham số Origin SpriteBatch.Drawđể thay đổi tâm xoay của mình.

Đây là những gì tôi nhận được với đoạn mã sau (với một vài điều chỉnh về điểm gốc để làm cho nó trông đẹp hơn - về cơ bản nguồn gốc bắt đầu ở gần góc phải và kết thúc ở gần góc bên trái):

int cards = 20;
float range = MathHelper.ToRadians(90);
float initialAngle = MathHelper.ToRadians(-45);
float increment = range / cards;
Vector2 leftCorner = new Vector2(0, texture.Height * 0.9f);
Vector2 rightCorner = new Vector2(texture.Width, texture.Height * 0.9f);
Vector2 fanPosition = new Vector2(400, 300);
spriteBatch.Begin();
for (float angle = 0; angle < range; angle+=increment)
{
    float cardAngle = initialAngle + angle;
    Vector2 cardOrigin = Vector2.Lerp(rightCorner, leftCorner, angle / range);
    spriteBatch.Draw(texture, fanPosition, null, Color.White, cardAngle, cardOrigin, 1f, SpriteEffects.None, 0f);
}
spriteBatch.End();

Và kết quả:

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


7
Tôi muốn nói thêm rằng giao diện có thể được điều chỉnh bằng cách sử dụng một tâm xoay khác, nếu bạn muốn kéo dài một vòng cung nhỏ hơn, bạn nên sử dụng một điểm xoay nằm bên dưới thẻ.
aaaaaaaaaaaa

@eBusiness Bạn nói đúng, tôi sẽ thêm nó vào.
David Gouveia

Cảm ơn David rất nhiều! Tôi đã triển khai mã bạn đã hiển thị trong JavaScript tại đây: jsfiddle.net/tyyvk/7
Sembiance
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.