Bản sao PyGame QIX, điền vào các khu vực


8

Tôi đang chơi xung quanh với PyGame.

Bây giờ tôi đang cố gắng thực hiện một bản sao QIX .

Tôi có vòng lặp trò chơi của mình và tôi có thể di chuyển trình phát (con trỏ) trên màn hình.

Trong QIX, chuyển động của người chơi để lại dấu vết (đuôi) trên màn hình, tạo ra một đa tuyến.

Nếu đa tuyến với các ranh giới màn hình tạo ra một đa giác, khu vực được lấp đầy.

Làm thế nào tôi có thể thực hiện hành vi này?

Làm thế nào để lưu trữ đuôi trong bộ nhớ?

Làm thế nào để phát hiện khi nó xây dựng một hình dạng kín cần được lấp đầy?

Tôi không cần một giải pháp làm việc chính xác, một số gợi ý, tên algo sẽ rất tuyệt.

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

Khi bắt đầu, chỉ có đường viền màu xám, nơi người chơi có thể di chuyển con trỏ xung quanh.

  • Kịch bản đầu tiên:

Người dùng di chuyển con trỏ của mình từ điểm A máng B, vẽ đa tuyến màu đỏ cho đến điểm C. Tại thời điểm này, do vượt qua biên giới, điểm A phải được kết nối với điểm C tự động, tạo ra một đa giác, cần được lấp đầy ( thứ màu cam đó trên bản vẽ của tôi). Việc điền vào đa giác rất đơn giản trong PyGame, bởi vì tôi cung cấp chuỗi các điểm và PyGame quan tâm đến phần còn lại.

  • Kịch bản thứ hai:

Người dùng di chuyển trên đường viền tới điểm D, từ đó anh ta vẽ một đường thẳng đến điểm E. Bởi vì anh ta đang vượt qua đường thẳng của đa giác trước đó, và với các đường thẳng của anh ta và đường viền khác có thể tạo ra một đa giác khác. (Cái màu xanh lá cây).

  • Kịch bản thứ ba:

Người chơi di chuyển xa hơn trên đa giác (anh ta có thể di chuyển trên các đường đa giác hiện có) và vẽ một đường từ điểm G đến điểm F. Ở đây một lần nữa, vì đường viền và các đường hiện có, nên điền vào một đa giác khác (đường màu xanh) .


Có lẽ có một số câu trả lời ở đây (câu hỏi tương tự): gamedev.stackexchange.com/questions/26377/ Lời
tigrou

Cảm ơn, nhưng liên kết cho thấy các trường hợp sử dụng nguyên thủy. Tôi đã cập nhật câu hỏi của mình, vì vậy có lẽ rõ ràng hơn những gì tôi cố gắng hoàn thành
astropanic

Câu trả lời:


5

Đây là cách tôi tiếp cận nó:

  1. Luôn có một khu vực mở duy nhất, được đại diện bởi một đa giác. Tất cả các lĩnh vực khác là không liên quan.
  2. Một dòng bắt đầu khi bạn di chuyển từ chu vi của đa giác vào bên trong đa giác.
  3. Một dòng dừng lại khi bạn di chuyển từ bên trong đa giác trở lại chu vi.
  4. Khi bạn dừng dòng, bạn đã chia đa giác thành hai đa giác.
  5. Sau đó, bạn quyết định cái nào trong hai đa giác cần điền và cái nào sẽ giữ làm vùng mở. Trong Qix, phía mà Qix (kẻ thù) vẫn ở trạng thái mở và phía bên kia đã được lấp đầy.

Làm thế nào để bạn chia nhỏ đa giác? Bạn sử dụng các điểm cuối của dòng của bạn để chia chu vi đa giác thành hai phần, sau đó sử dụng dòng mới để hoàn thành hai phần đó thành đa giác mới.

Ví dụ: giả sử khu vực mở của bạn là một đa giác có điểm [p0, p1, p2, p3, p4, p5]. Điểm bắt đầu của bạn Axảy ra giữa p1p2, và điểm cuối của bạn Bxảy ra giữa p3p4. Các dòng mới đã được rút ra là [A, s, t, u, v, B]. Đầu tiên chúng ta chia đa giác thành hai phân đoạn [A, p2, p3, B][B, p4, p5, p0, p1, A]. Hai phân đoạn này cùng nhau tạo thành đa giác ban đầu. Sau đó, chúng tôi dán dòng mới vào từng dòng (một lần tiến, một lần lùi), tạo thành [A, p2, p3, B, v, u, t, s][B, p4, p5, p0, p1, A, s, t, u, v]. Bạn điền vào một trong những đa giác này và giữ cái kia là vùng mở mới của bạn.

Tôi đã không thực hiện điều này và không biết chắc chắn nó có hoạt động không, nhưng đó là cách tiếp cận tôi sẽ sử dụng: phân chia đa giác thay vì điền vào đa giác.


1

Đây là một vấn đề liên quan đến nhiều bước phụ rời rạc. Dưới đây là một phác thảo về những gì tôi đề nghị:

  • Đợi cho đến khi người chơi tạo thành một giao điểm của nhiều dòng
  • Nhận một pixel từ mỗi bên của giao lộ
  • Tìm đường để xem họ có thể kết nối với nhau không
  • Các pixel không thể kết nối với nhau là các khu vực riêng biệt
  • Thực hiện lấp đầy để có được tất cả các pixel trong khu vực

Tôi sẽ lưu trữ trạng thái của các pixel của trò chơi trong một mảng Numpy (numpy dot scipy dot org). Màu sắc có thể là ba mảng riêng biệt cho RGB, nhưng mảng tôi sẽ tập trung vào là mảng dòng / không có dòng. Chỉ cần khởi tạo nó bằng số không và đặt kích thước của trường trò chơi của bạn và mỗi khi người chơi đi qua một pixel, đặt mục tương ứng trong mảng thành 1. Bạn sẽ muốn hiển thị các mục này trên màn hình dưới dạng màu khác , như họ là dòng của bạn!

Mỗi khi pixel của người chơi di chuyển, tôi sẽ kiểm tra xem liệu nó có vượt qua (và vẽ một dòng bên cạnh) một dòng hiện có không. Nếu vậy, tôi sẽ nhận được một pixel từ mỗi bộ phận có thể:

. . . | . 
. . . | . 
. . . | x 
. . x < -

Dấu chấm là các pixel trống, các dòng là (rõ ràng) các dòng và X là các pixel trống mà chúng ta muốn chọn. Chúng ta có thể làm như vậy theo cách sau:

  • Thêm tất cả các pixel trống liền kề với trình phát / giao cắt vào danh sách.
  • Lặp lại danh sách loại bỏ pixel nếu mục tiếp theo trong danh sách liền kề (trong trường trò chơi) với mục bạn đang bật.

Khi bạn có pixel từ tất cả các phía có thể của giao lộ, hãy chạy A * trên mỗi cặp có thể. (Xem http://www-cs-students.stanford.edu/~amitp/gameprog.html#paths hoặc Google a-star để biết thêm thông tin.) Nếu có thể tìm thấy đường dẫn giữa một cặp, hãy xóa một trong các pixel được kết nối từ danh sách.

Sau khi lặp và đường dẫn cho tất cả các cặp, các pixel còn lại phải ở trong một khu vực kín, riêng biệt! Để có được tất cả các pixel trong từng khu vực, hãy thực hiện lấp đầy từ pixel của khu vực đó. Xem http://en.wikipedia.org/wiki/Flood_fill .

Chúc may mắn!


0

Khu vực của bạn chỉ là một loạt các điểm. Công việc khó khăn đi kèm với việc lấy một loạt các điểm hình thành (thường là) một đa giác lõm và tam giác chúng để bạn có thể kết xuất và có thể chiếu kết cấu lên chúng. Xem http://en.wikipedia.org/wiki/Polygon_triangulation để biết thêm chi tiết


1
Đó không phải là vấn đề với tam giác, PyGame đảm nhận việc đó. Tôi đã cập nhật câu hỏi của mình bằng một hình ảnh, và một số trường hợp sử dụng, hãy xem để bạn có được điểm. Dù sao cũng cảm ơn
astropanic
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.