Solusi teknologi yang bagus untuk membangun peta ascii dan memindahkan karakter dalam browser (seperti benteng kerdil)? [Tutup]

10

Saya ingin membuat aplikasi web untuk situs web permainan saya yang melibatkan penggunaan karakter teks untuk mewakili hewan dan manusia, dan membuatnya bergerak di kotak peta dengan AI (server-driven) yang independen.

Jadi pada dasarnya, peta kerdil-benteng di browser: kerdil-benteng-contoh Dengan makhluk bergerak, gerombolan, npcs, dan pcs. Meskipun bukan berarti saya tidak ingin mencapai skala ini, saya mungkin akan mulai menunjukkan seperempat dari konten ini kapan saja.

Mungkin beberapa ubin latar belakang / tidak bergerak dapat dimuat secara statis. Tetapi untuk makhluk / hewan dan hal-hal yang dapat bergerak, saya tidak yakin solusi teknologi apa yang paling efektif.

Saya sadar <canvas>meskipun saya tidak tahu apakah kemampuannya cocok dengan use case ini. Tentu saja sejumlah javascript akan diperlukan.

Apakah ada pustaka javascript atau pustaka kanvas di luar sana yang sesuai dengan use case ini? Teknologi lain yang tidak saya sadari? Adakah yang tahu contoh situs web yang telah melakukan hal serupa dengan ini, sehingga saya dapat menampung ide dari mereka?

Kzqai
sumber
1
Lihatlah rot.js ondras.github.com/rot.js/hp
Alayric
Yah, rot.js mungkin persis seperti yang saya cari, tetapi tidak mengetahuinya.
Kzqai

Jawaban:

5

Saya sebenarnya telah membuat pustaka tampilan karakter untuk web, Unicodetiles.js , yang saya tidak hanya menghabiskan waktu untuk mengoptimalkan, tetapi juga mengeksplorasi berbagai cara penyajian teks; memiliki tiga penyaji:

  1. DOM, yang menggunakan matriks <div>elemen untuk membuat setiap mesin terbang dengan warna latar depan dan latar belakang yang dapat disesuaikan.
  2. Kanvas, yang menggambar karakter menggunakan <canvas>elemen. Ini jauh lebih cepat, dan ada tes kinerja untuk mendukungnya: http://tapiov.net/unicodetiles.js/tests/
  3. WebGL, yang menggunakan elemen kanvas untuk membuat tekstur font dan kemudian merender menggunakan WebGL, yang bahkan lebih cepat dan sangat terukur untuk ukuran viewport yang besar, tetapi tidak didukung dengan baik di browser.

Perhatikan bahwa tes kinerja tertaut bisa sangat ekstrem, mengubah setiap karakter setiap bingkai. Dalam praktiknya, bahkan renderer DOM cukup cepat untuk sebagian besar tujuan.

Jika Anda memutuskan untuk membuat perpustakaan Anda sendiri, saya masih merekomendasikan menggunakan kanvas karena tampaknya berkinerja lebih baik, memungkinkan adegan yang lebih besar. Hanya menggunakan WebGL akan membatasi basis pengguna dan kompleks untuk diterapkan (Unicodetiles memiliki mekanisme fallback otomatis).


Perpustakaan lain, yang saya dengar menyarankan banyak baru-baru ini rot.js . Itu secara khusus diarahkan pada roguelikes karena dilengkapi dengan misalnya sistem FOV dan generator penjara bawah tanah. Jika Anda ingin paket lengkap, ini mungkin cara yang tepat.

Tapio
sumber
Bagus. Saya bisa menggunakannya. Atau setidaknya belajar dari cara orang lain melakukannya untuk memberi tahu pendekatan saya sendiri, karena saya ingin membuat roguelike, tetapi tidak seperti roguelike. : D
Kzqai
@ Tapio Saya mencoba menerapkan pacman dengan unicodetiles, masalahnya adalah pemain selalu terpusat di peta, itu tidak diinginkan untuk pacman, dapatkah saya menonaktifkannya entah bagaimana, atau dapatkah saya berkeliling tanpa menentukan pemain.
user3995789
6

Saya pikir cara yang paling efektif adalah dengan memalsukannya. Merender ke beberapa elemen target menggunakan font sprite bawaan Anda sendiri seolah-olah Anda sedang merender layar 2D normal. Pendekatan ini memastikan tidak ada hal aneh terjadi ketika orang kehilangan font, atau menggunakan bahasa yang sangat berbeda (Cina, Rusia).

Font dan teks adalah salah satu hal yang paling sulit untuk mendapatkan pixel sempurna di semua lokal di semua browser. Bahkan ketika menanamkan font dan menggunakan beberapa peramban ajaib CSS dan pengaturan kegunaan masih bisa menimpa dan mengubahnya. Untuk situs web normal, teks pixel-perfect bukan merupakan masalah, tetapi dalam game seperti Dwarf Fortress, beberapa piksel dapat menyebabkan tampilan yang sangat tidak koheren. Bahkan ketika tidak menggunakan browser tetapi aplikasi normal ada masalah dengan rendering teks. Jadi, bahkan Dwarf Fortress sendiri menggunakan pendekatan yang saya jelaskan.

http://en.wikipedia.org/wiki/Dwarf_Fortress

Tampilan di layar menggunakan halaman kode yang sedikit dimodifikasi, 437 karakter dalam 16 warna berbeda diimplementasikan sebagai bitmap, disajikan dengan OpenGL

Sunting: karena saya mendapat beberapa komentar, saya sedikit memperluas jawabannya

Roy T.
sumber
Apakah bahasa lain bukan ekstensi daripada pengganti ASCII? Mengapa situs web berisi teks yang biasa "tidak memalsukannya"?
Anko
1
Sebagian besar masalah pengkodean karakter dapat dicegah dengan menggunakan pengkodean UTF-8.
Philipp
Bahasa Rusia memiliki font yang berbeda dari ASCII, dan bahasa Mandarin bahkan lebih berbeda. Peduli situs web biasa tentang estetika, yang mencakup hal-hal seperti mesin terbang berukuran variabel, kerning, "aliran" teks yang bagus, dll. Sebuah permainan seperti DF akan peduli tentang penempatan huruf yang teratur, yang tidak dapat dilakukan dengan andal di peramban web.
Liosan
1
@Liosan yakin itu bisa. Cukup gunakan deklarasi CSS font-family:monospace;dan browser web akan menggunakan font monospace default.
Philipp
Saya tidak benar-benar yakin bagaimana ini akan menguntungkan vs font web monospace css tertanam? Maksud saya, ini akan membutuhkan lebih banyak rendering, mungkin akan memungkinkan masalah jarak diselesaikan dengan lebih andal, tetapi dengan font css yang disematkan tidak masalah jika orang kehilangan font atau menggunakan bahasa yang berbeda? Meskipun saya kira itu akan membatasi operasi hanya pada set karakter font web tertanam, hmmm.
Kzqai
3

Untuk mengetahui jumlah garis dan kolom yang Anda perlu hasilkan, Anda harus memeriksa lebar dan tinggi jendela dan mengubahnya sesuai. Ingatlah untuk mendengarkan acara onResize dan memodifikasi lebar dan tinggi sesuai dengan itu.

Saat Anda ingin melakukan ini dengan cara tekstual , Anda bisa melakukan ini menggunakan teks dengan font monospace dan tabel di mana setiap sel berisi satu karakter.

Untuk mengatasi masing-masing karakter, Anda dapat membuat a <table>dengan jumlah baris dan kolom yang benar, di mana masing-masing <td>memiliki ID yang terdiri dari koordinat x dan y. Dengan cara itu Anda dapat mengatasi sel-sel individual dengan ID dan mengubah innerHTML mereka untuk mengubah huruf dan mengubah kelas css mereka untuk mengubah warna mereka.

Namun, menggunakan kanvas mungkin lebih cepat karena Anda tidak harus memanipulasi pohon DOM besar untuk setiap karakter yang harus Anda ganti. Omong kosong, Benteng melakukan hal yang serupa. Karakter yang digunakan untuk mewakili objek sebenarnya adalah bitmap, bukan output teks asli, dan mereka digambar menggunakan API grafis 2d. Kanvas HTML5 dilengkapi dengan baik untuk ini. Ini memiliki metode context.fillText yang memungkinkan Anda untuk menggambar teks di kanvas. Ini dapat digunakan untuk menggambar karakter individu. Anda dapat mengubah ukuran dan wajah font dengan memanipulasi variabel context.font dan warna setiap huruf dengan memanggil context.fillStyle .

Perhatikan bahwa memanggil fillText ratusan kali per frame bisa lambat, karena font rasterisasi mahal dan tidak ada browser yang saya tahu menggunakan cache. Itu berarti bahwa ketika Anda merender surat yang sama dengan pengaturan yang sama seratus kali, itu akan diraster ulang seratus kali. Untuk meningkatkan kinerja Anda bisa men-cache penampilan raster dari setiap huruf dengan setiap warna pada kanvas tersembunyi dan kemudian menggambar kanvas tersembunyi ini menggunakan context.drawImage . Menyalin dari satu kanvas ke kanvas lain biasanya jauh lebih cepat daripada rasterisasi font.

Saat ini saya sedang mengembangkan game 2d menggunakan kanvas, dan memperhatikan bahwa pemakan FPS terbesar adalah menggambar font. Ketika saya menambahkan cache untuk teks raster, itu banyak meningkatkan kinerja.

Philipp
sumber
Font bitmap juga merupakan output teks yang benar! Saya menggunakannya di terminal sepanjang waktu. Juga, jika kanvas lebih cepat, mengapa StackExchange tidak membuat teks berbasis kanvas?
Anko
sial, sekarang saya ingin menulis perpustakaan untuk itu.
Philipp
@Anko terminal! = Browser web. Render teks apa yang Anda maksud?
Philipp
1
Pepatah Anko mengatakan bahwa bitmap yang dipetakan adalah teks-benar, ia dapat menggunakannya di terminalnya - dan itu adalah bukti bahwa font-bitmap yang dipetakan adalah teks-benar.
Polar
0

OK ini hanya tikaman dalam gelap dan saya tidak tahu bagaimana itu membuat.

Pada dasarnya Anda menggunakan trik trik yang sama (alias terminal) lakukan di masa lalu. Pertama Anda mulai dengan font monospace. Anda memiliki garis M dengan karakter N. Jadi Anda cukup membuang teks ke dalam div yang cukup lebar (lebar: N em?) Dan menempatkan setiap N karakter satu baris; dalam hal ini <br/>bukan a \n.

Caranya adalah dengan mengganti buffer, baik char by char atau seluruh konten sekaligus dengan java script.

Jika Anda ingin benar-benar spesifik, Anda dapat menggunakan font-@ untuk memastikan Anda memiliki font monospace yang sama di mana-mana.

rioki
sumber
Saya juga berpikir untuk melakukan itu, tetapi kemudian saya menyadari bahwa itu tidak akan menjadi arsitektur yang baik ketika Anda ingin mengontrol warna dan warna latar belakang masing-masing karakter individu.
Philipp
0

Pikirkan istilah mesin terbang. Pisahkan tampilan teks dari makna di baliknya. Sebagai contoh:

(kode semu)

if (display.hitGlyph)
    glyph = Glyph.Asterisk;

display(glyph);

Dan kemudian dalam kode dasar Anda untuk mendefinisikan atlas mesin terbang, lakukan sesuatu seperti:

Glyph.Asterisk = "*";

Atlas glyph sebenarnya bisa menjadi tabel ascii dengan berbagai pengkodean. Maksudnya di sini adalah hanya untuk memisahkan kapan harus ditampilkan, dengan apa yang akan ditampilkan. Saya akan merekomendasikan membuat kerangka kerja dari awal. Itu akan memberi Anda lebih banyak kebebasan.

Jason Coombes
sumber