Pola umum untuk skala "unit nyata" ke piksel?

10

Ini adalah pertanyaan lanjutan untuk pertanyaan ini .

Saya ingin tahu apakah ada pola umum / tipikal / terbaik untuk skala representasi saya di dunia (saat ini 160Kmx160Km) agar sesuai dengan area gambar (saat ini 800x600 piksel).

Saya dapat memikirkan setidaknya empat pendekatan yang berbeda:

Naif satu (cara saya melakukannya sejauh ini). Saya mengimplementasikan fungsi global sc(vector)yang hanya akan mengembalikan salinan vektor yang diperkecil. Ini tentu saja berfungsi, tetapi mengharuskan saya untuk menulis kode seperti:

drawCircle(sc(radius), sc(position))

Fungsi pembungkus . Saya dapat mendefinisikan beberapa fungsi, masing-masing membungkus satu middleware asli. Sebagai contoh saya bisa mendefinisikan myDrawCirclebahwa pertama-tama akan skala argumen yang perlu scaling, dan kemudian memanggil drawCircledengan yang terakhir. Ini akan membuat kode saya mungkin lebih mudah dibaca dan lebih mudah dirawat, tetapi saya harus menulis banyak fungsi pembungkus, yang kedengarannya konyol.

Penghias fungsi . Saya hanya bisa menghiasi fungsi middleware yang ada, menyediakan penskalaan otomatis untuk semua parameter yang merupakan instance dari kelas Vector3D, tetapi masalahnya adalah fungsi tersebut juga berfungsi dengan parameter yang sama listatau Vector2Dterlalu, dan dekorator tidak memiliki cara untuk mengetahui daftar mana yang perlu diskalakan (jari-jari misalnya) dan yang tidak (nilai RGB).

Inisialisasi permukaan . Ketika mendefinisikan permukaan yang akan saya gambar, saya bisa mendefinisikan faktor penskalaan (sehingga saya akan menggunakan meter dan bukan piksel sebagai parameter). Ini akan bekerja secara transparan untuk saya dan akan menjadi solusi pilihan saya, tetapi tentu saja itu harus diterapkan di middleware, jadi itu bukan pilihan nyata.

... bagaimanapun juga: karena ini adalah masalah yang sangat umum, saya bertanya-tanya apakah ada pola yang mapan yang dengan elegan menyelesaikan masalah ini yang gagal saya temukan.

PS: Untuk proyek ini saya menggunakan python (dengan pygame ), tetapi - meskipun jawaban khusus python / pygame sangat dihargai, saya lebih tertarik pada deskripsi umum / tingkat tinggi dari pola daripada implementasi konkretnya.

Terima kasih sebelumnya atas waktu dan keahlian Anda.

Mac
sumber

Jawaban:

6

Cara standar untuk melakukan itu adalah mengatur matriks transformasi untuk melakukan konversi selama rendering. Untuk rendering 3D, ini adalah view transform matrix untuk kamera yang melakukannya.

Sebagian besar API 2D memiliki cara untuk menentukan transformasi tampilan juga, baik sebagai matriks 2x3 atau sebagai skala terpisah, terjemahan dan rotasi.

Pandangan cepat pada dokumentasi pygame menyarankan Anda harus mengimplementasikan sendiri view transform matrix. Apakah itu memungkinkan Anda menurunkan kelas Anda sendiri dari kelas permukaannya untuk memungkinkan Anda menambahkan fungsionalitas itu?

Adam
sumber
Jawaban Anda sangat berguna (+1). Saya dapat mensubklasifikasikan kelas permukaan saya, tetapi saya perlu lebih banyak waktu untuk mengeksplorasi jika saya dapat mencapai apa yang ditunjukkan dalam pos Anda. Saya sangat baru dalam pemrograman game dan grafik secara umum, apakah Anda memiliki beberapa tautan untuk merekomendasikan yang menjelaskan pendekatan matriks ini (atau bahkan hanya matematika yang terlibat menggunakan matriks untuk skala permukaan?). Terima kasih!
mac
1
Karena ini 2D dan tidak ada rotasi yang terlibat @mac pada dasarnya mengatakan untuk membungkus fungsi dan Anda dapat menggunakan pembagian skala sederhana Anda dalam pembungkus tersebut. Alasan matriks penuh biasanya digunakan adalah karena sebagian besar API memiliki matriks yang mengontrol viewport, tetapi tampaknya pygame tidak jadi Anda harus melakukannya sendiri satu lapis ke atas.
Patrick Hughes
2

karena ini adalah masalah yang sangat umum, saya bertanya-tanya apakah ada pola yang mapan yang dengan elegan menyelesaikan masalah ini yang gagal saya temukan.

Biasanya orang tidak mencoba melakukan penskalaan run-time dalam game 2D. Saya tidak setuju bahwa itu masalah umum. Jika orang menginginkan peta mini atau beberapa penyalinan tetap lainnya, seringkali ada satu set grafis baru yang dilakukan untuk tujuan ini. Jarang bahwa Anda membutuhkan rutinitas tunggal untuk dijalankan pada 2 level zoom berbeda dalam game 2D.

Jika Anda menggunakan API 3D, Anda bisa mendapatkan fungsionalitas ini secara gratis - cukup ubah parameter kamera / viewport.

PyGame adalah API yang sangat lama dan sayangnya hanya cocok untuk 2D. Bahkan jika Anda dapat mengerjakan sistem penskalaan yang memadai untuk tingkat zoom yang berbeda, kinerjanya tidak akan cukup baik dan penampilannya mungkin sangat buruk.

Saya akan menyarankan bahwa jika Anda ingin memperbesar dan memperkecil, Anda pindah ke API 3D modern sesegera mungkin. Saya akan merekomendasikan pyglet tetapi ada juga yang lain.

Kylotan
sumber
Terima kasih atas jawaban Anda (+1). Saya sudah pernah menggunakan pygletsuntuk simulasi 3D. Tentunya lebih mampu daripada pygame, tetapi dukungan untuk 2D adalah tingkat yang cukup rendah daripada yang ada di pygame. Dokumentasi / contoh yang tersedia juga kurang terperinci, yang sangat mengecewakan bagi saya karena saya pemula dalam pengembangan game, dan saya benar-benar perlu memahami dasar dari operasi yang paling umum dilakukan. :) Adapun "usia" pygame: Anda benar. Namun modernisasi sedang berlangsung! :)
mac
Adapun: "Jarang sekali Anda membutuhkan rutinitas tunggal untuk berjalan pada 2 level zoom berbeda" ... Saya pikir itulah yang akan digunakan ketika mengubah ukuran jendela / resolusi permainan layar penuh. Dari komentar Anda, saya mengerti bukan: ada pointer ke apa yang "umum"?
mac
Operasi 2D manakah yang Anda lakukan di mana pyglet lebih rendah daripada pygame? Keduanya memungkinkan Anda menggambar sprite dengan 1 baris kode. Saat Anda mengubah ukuran jendela gim 2D, rasio piksel-ke-dunia-unit hampir selalu tetap konstan. Jadi, Anda akhirnya menggambar lebih banyak sprite: Anda tidak menggambarnya secara berbeda.
Kylotan
Di sisi level rendah: Saya tidak benar-benar ahli dalam salah satu dari kedua lib, tetapi dalam pyglet saya tidak bisa meniru di luar kotak perilaku rendering grup yang ditawarkan oleh pygame (seperti pada pygame.sprite.LayeredUpdatesmisalnya). Adapun rasio yang tidak berubah: Saya mengerti maksud Anda. Perilaku yang Anda gambarkan bukan yang ingin saya tiru, tetapi saya mengerti apa yang Anda maksudkan, terima kasih atas klarifikasi! :)
mac
pyglet memiliki objek OrderedGroup - dokumen ada di sini jika Anda atau orang lain tertarik: pyglet.org/doc/programming_guide/displaying_images.html#sprites
Kylotan