Lưu trữ lưới hex


10

Tôi đã tạo một khung lưới hex nhỏ cho Unity3D và đã đi đến tình huống khó xử sau đây. Đây là hệ tọa độ của tôi (lấy từ đây ):

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

Tất cả đều hoạt động khá độc đáo ngoại trừ thực tế tôi không biết làm thế nào để lưu trữ nó. Ban đầu tôi dự định lưu trữ cái này trong một mảng 2D và sử dụng hình ảnh để tạo bản đồ của mình.

Một vấn đề là nó có các giá trị âm (điều này dễ dàng được khắc phục bằng cách bù đắp tọa độ một chút).

Tuy nhiên, do hệ tọa độ này, một hình ảnh hoặc bitmap như vậy sẽ phải có hình kim cương - và vì các cấu trúc này có dạng hình vuông, điều này sẽ gây ra nhiều đau đầu ngay cả khi tôi hack một cái gì đó cùng nhau. Có bất cứ điều gì tôi thiếu có thể khắc phục điều này? Tôi nhớ rằng đã thấy một bài đăng diễn đàn liên quan đến điều này trong các diễn đàn thống nhất nhưng tôi không thể tìm thấy liên kết nữa.

Viết một bộ các dịch giả tọa độ là giải pháp tốt nhất ở đây?

Nếu các bạn nghĩ rằng nó sẽ hữu ích, tôi có thể đăng mã và hình ảnh về vấn đề của mình.


1
Bạn có thể chỉ lưu hình ảnh PNG trong suốt xung quanh hình lục giác không?
Markus von Broady

Vấn đề chính của tôi khi lưu vào pngs và mảng là số lượng "khoảng trắng" mà chúng sẽ phải chứa để giữ cho hệ thống tọa độ này nguyên vẹn.
PeeC

1
Nếu "khoảng trắng" có nghĩa là các pixel trong suốt, thì tại sao số lượng của nó lại là một vấn đề?
Markus von Broady

Đó là một điểm rất tốt. Hầu hết các định dạng hình ảnh không lãng phí nhiều bộ nhớ lưu trữ các mẫu lặp đi lặp lại. Nhưng vẫn còn, nó hơi phiền với tôi rằng để lưu trữ bản đồ này tôi đang sử dụng này bộ nhớ nhiều (pixel màu xám là không gian trống rỗng, màu sắc khác là tọa độ hex hợp lệ).
PeeC

1
Oh, bạn đang lưu trữ dữ liệu lưới, không phải hình ảnh gạch! Tại sao bạn không lưu cấu trúc dữ liệu (lưới) vào tệp nhị phân hoặc mã hóa nó bằng cách sử dụng ví dụ JSON và lưu vào tệp văn bản? Tuy nhiên, tôi không biết khả năng của Unity. Ngoài ra, bạn có thể muốn xác nhận điều này, nhưng tôi tin rằng một khu vực có cùng màu được tối ưu hóa (được nén lỏng) ở định dạng PNG.
Markus von Broady

Câu trả lời:


9

Các tọa độ hình bình hành bạn đang sử dụng dễ làm việc hơn, nhưng chúng có nhược điểm là lạ đối với bản đồ hình chữ nhật. Một cách tiếp cận là lưu trữ nó với tọa độ bù nhưng thực sự sử dụng tọa độ hình bình hành trong logic trò chơi của bạn.

Quan sát: trong mỗi hàng của bản đồ, dữ liệu lưới tiếp giáp nhau. Tất cả các không gian lãng phí là ở bên trái và bên phải.

Giải pháp: trong hàng đó, lưu trữ dữ liệu bắt đầu từ cột ngoài cùng bên trái thay vì cột được đánh dấu 0. Tính cột đầu tiên của bản đồ hình chữ nhật trong hệ tọa độ của bạn , sau đó trừ đi từ tọa độ cột để xác định vị trí trong mảng. Điều này làm việc cho tọa độ cột âm quá.

Thực hiện chuyển đổi trong getter và setter cho bản đồ, với nội dung như sau:

inline function get(q, r) {
    first_column_in_this_row = -floor(q/2);
    return array[r][q - first_column_in_this_row];
}

Bạn sẽ phải sửa đổi điều này để làm việc với sự lựa chọn tọa độ và bản đồ của bạn (chú ý tắt bởi một sự khác biệt). Trong một số bố cục, bạn sẽ muốn bù các cột theo hàng thay vì ngược lại.

Bạn có thể sử dụng cùng một mẹo để tạo bản đồ có hình dạng khác; nó không giới hạn ở hình chữ nhật.

Nếu bạn đang sử dụng C hoặc C ++, bạn có thể sử dụng số học con trỏ để thực hiện việc này nhanh hơn. Thay vì lưu trữ một mảng các con trỏ vào các mảng, hãy lưu trữ một mảng các con trỏ đã được điều chỉnh bởi first_column_in_row. (Điều này có thể không di động)


Điều này hoạt động như tôi có thể nói, tuy nhiên toán học thực sự kỳ lạ. Sau khi thử một vài phương trình có ý nghĩa trong đầu, tôi đã giải quyết yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)sau một vài thử nghiệm và sai sót. Không biết làm thế nào nó hoạt động khó khăn.
PeeC

Hãy chắc rằng yIndex = y-((x%2==0)?(-x/2):(-x/2)-1). x / 2 là tất cả btw dựa trên số nguyên nên không cần sàn.
PeeC

6

Cá nhân, tôi thích sự đơn giản hơn là tiết kiệm bộ nhớ. Đừng tối ưu hóa cho đến khi cần!

Nếu bạn vẫn cố gắng tiết kiệm một vài byte, đây là cách bạn có thể làm điều đó:

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

  1. Cắt hình bình hành làm đôi để tạo thành hai hình tam giác vuông
  2. Sắp xếp lại hai hình tam giác để tạo thành một hình chữ nhật.
  3. (Lưu ý tôi đã thêm dải đệm màu xanh lá cây để toán học hoạt động tốt.)

Mã Python để ánh xạ tọa độ hình chữ nhật thành tọa độ hình bình hành và ngược lại:

# Height of rectangle
H = 15

def r2p(x, y):
"rectangle to parallelogram"
if y < -x/2 + H:
    y = y + H
return (x - 1, y)

def p2r(x,y):
"parallelogram to rectangle"
if y >= H:
    y = y - H
return (x + 1, y)

2
bạn cũng có thể di chuyển các pixel theo chiều dọc xuống - trên hình ảnh sẽ cóoffsetY = Math.floor ( (x+1)/2 )
Markus von Broady

1

Không cần thiết phải làm biến dạng bản đồ của bạn, vì chuyển đổi giữa tọa độ hình chữ nhật và "chính tắc" là nhanh chóng và dễ dàng. Đây là đường dẫn đến phần giới thiệu về cách thực hiện:

Chuyển đổi giữa tọa độ hex hình chữ nhật và Canonical

Kỹ thuật này kết hợp việc đánh giá lười biếng với bộ nhớ đệm của các chuyển đổi được tính toán.

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.