Menyimpan kisi hex

10

Saya telah membuat kerangka kerja hex grid kecil untuk Unity3D dan telah sampai pada dilema berikut. Ini adalah sistem koordinat saya (diambil dari sini ):

masukkan deskripsi gambar di sini

Semuanya bekerja dengan sangat baik kecuali untuk fakta saya tidak tahu cara menyimpannya. Saya awalnya bermaksud menyimpan ini dalam array 2D dan menggunakan gambar untuk menghasilkan peta saya.

Satu masalah adalah bahwa ia memiliki nilai negatif (ini mudah diperbaiki dengan mengimbangi koordinat sedikit).

Namun, karena sistem koordinat ini, gambar atau bitmap seperti itu harus berbentuk berlian - dan karena struktur ini berbentuk persegi, ini akan menyebabkan banyak sakit kepala bahkan jika saya meretas sesuatu bersama-sama. Apakah ada sesuatu yang saya lewatkan yang dapat memperbaikinya? Saya ingat pernah melihat posting forum mengenai hal ini di forum persatuan tetapi saya tidak dapat lagi menemukan tautannya.

Apakah menulis satu set penerjemah koordinator merupakan solusi terbaik di sini?

Jika kalian pikir itu akan membantu, saya dapat memposting kode dan gambar dari masalah saya.

PeeC
sumber
1
Tidak bisakah Anda menyimpan gambar PNG yang transparan di sekitar segi enam?
Markus von Broady
Masalah utama saya dengan menyimpan ke pngs dan array adalah jumlah "spasi putih" yang harus mereka isi untuk menjaga sistem koordinat ini tetap utuh.
PeeC
1
Jika "spasi putih" berarti piksel transparan, lalu mengapa jumlah itu menjadi masalah?
Markus von Broady
Itu poin yang sangat bagus. Sebagian besar format gambar tidak membuang banyak memori yang menyimpan pola berulang. Tapi tetap, itu sedikit mengganggu saya bahwa untuk menyimpan peta ini saya menggunakan ini banyak memori (piksel abu-abu adalah ruang kosong, warna lain adalah koordinat hex valid).
PeeC
1
Oh, Anda menyimpan data grid, bukan mem-tile gambar! Mengapa Anda tidak akan hanya menyimpan struktur data (kisi) ke file biner, atau menyandikannya menggunakan mis. JSON dan menyimpannya ke file teks? Saya tidak tahu kemampuan Unity. Juga, Anda mungkin ingin mengkonfirmasi ini, tapi saya percaya area dengan warna yang sama dioptimalkan (dikompresi longgar) dalam format PNG.
Markus von Broady

Jawaban:

9

Koordinat jajar genjang yang Anda gunakan lebih mudah digunakan, tetapi memiliki kelemahan karena aneh untuk peta persegi panjang. Salah satu pendekatan adalah menyimpannya dengan koordinat offset tetapi sebenarnya menggunakan koordinat jajaran genjang dalam logika game Anda.

Pengamatan: di setiap baris peta, data kisi berdekatan. Semua ruang yang terbuang ada di kiri dan kanan.

Solusi: di dalam baris itu, simpan data mulai dari kolom paling kiri daripada kolom bertanda 0. Hitung kolom pertama dari peta persegi panjang di sistem koordinat Anda , kemudian kurangi dari koordinat kolom untuk menentukan di mana dalam array itu pergi. Ini berfungsi untuk koordinat kolom negatif juga.

Lakukan konversi di pengambil dan penyetel untuk peta, dengan sesuatu seperti ini:

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

Anda harus memodifikasi ini agar berfungsi dengan koordinat dan peta pilihan Anda (perhatikan satu perbedaan). Di beberapa tata letak, Anda ingin mengimbangi kolom dengan baris alih-alih sebaliknya.

Anda dapat menggunakan trik yang sama untuk membuat peta dengan bentuk lain; itu tidak terbatas pada persegi panjang.

Jika Anda menggunakan C atau C ++ Anda dapat menggunakan aritmatika pointer untuk membuatnya lebih cepat. Alih-alih menyimpan array pointer ke array, simpan array pointer yang telah disesuaikan dengan first_column_in_row. (Ini mungkin tidak portabel)

amitp
sumber
Ini bekerja sejauh yang saya tahu, tetapi matematika itu benar-benar aneh. Setelah mencoba beberapa persamaan yang masuk akal di kepala saya, saya memutuskan yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)setelah beberapa percobaan dan kesalahan. Tidak tahu cara kerjanya tangguh.
PeeC
Buat itu yIndex = y-((x%2==0)?(-x/2):(-x/2)-1). x / 2 adalah semua btw berbasis integer jadi tidak perlu lantai.
PeeC
6

Secara pribadi, saya lebih suka kesederhanaan daripada menghemat memori. Jangan optimalkan sampai dibutuhkan!

Jika Anda masih ingin menghemat beberapa byte, berikut ini cara melakukannya:

masukkan deskripsi gambar di sini

  1. Iris jajaran genjang menjadi dua untuk membentuk segitiga siku-siku
  2. Atur ulang dua segitiga untuk membentuk persegi panjang.
  3. (Catatan saya menambahkan strip penyangga hijau sehingga matematika bekerja dengan baik.)

Kode python untuk memetakan koordinat persegi panjang ke koordinat jajaran genjang dan kembali:

# 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)
Leftium
sumber
2
Anda juga bisa memindahkan piksel secara vertikal ke bawah - pada gambar yang akanoffsetY = Math.floor ( (x+1)/2 )
Markus von Broady
1

Tidak perlu mengubah peta Anda, karena konversi antara koordinat persegi panjang dan "kanonik" cepat dan mudah. Berikut ini tautan ke intro tentang cara melakukannya:

Mengubah antara koordinat hex Rectangular dan Canonical

Teknik ini menggabungkan evaluasi malas dengan caching konversi yang dihitung.

Pieter Geerkens
sumber