Pengalaman menulis game dalam TypeScript dan WebGL atau kisah tentang bagaimana backend-shch dicelupkan ke tampilan modern

Hari baik untuk semua habrozhitel. Saya ingin memberi tahu Anda tentang bagaimana saya kembali ke pengembang game amatir setelah 3+ tahun, secara radikal mengubah alat (dan sepanjang jalan - pandangan dunia saya), dan apa yang terjadi. Di bawah luka Anda:


  1. Disposisi singkat dari semua fakta di awal perjalanan. Seperti gambar "SEBELUM" dalam iklan online murah "SEBELUM" dan "SETELAH".
  2. Penyelaman sukarela di garis depan modern dengan gaya "Di mana uangnya, Lebowski?!"
  3. Sedikit gatal pada titik intim, berubah menjadi keinginan yang membara untuk mempelajari sesuatu yang baru dengan melakukan sesuatu yang lama.
  4. Kesadaran akan ketidakberdayaan seseorang
  5. Mengatasi
  6. Akhir yang menyenangkan, seperti di film-film Anda ini.

Penafian


Artikel ini dalam bentuk konsep di github selama dua tahun, versi yang hampir lengkap ditulis pada akhir 2017 dalam pengejaran peristiwa.


Warga negara, perkenalkan diri Anda!


Dalam artikel saya sebelumnya ( https://habrahabr.ru/post/244417/ ) saya menulis sedikit tentang diri saya, dan lebih khusus tentang bagaimana saya dan gamedev terhubung. De jure - tidak mungkin, de facto - Saya menulis game dan mesin untuk kesenangan dan partisipasi dalam kompetisi lampu dan hangat. Sejak itu, sedikit yang berubah.


Untuk narasi lebih lanjut dan memaksa atmosfer yang diperlukan, penting bahwa pada awal kisah ini saya adalah seorang pengembang web .net profesional yang dapat menggunakan html5, css3 dan ... jquery. Untuk memperkuat yang tak terduga "ini giliran", kami menambahkan bahwa ada rasa tidak percaya dan jijik untuk JavaScript, dibumbui dengan:


  • kesalahpahaman terus terang dari semua hype ini di sekitar bahasa;
  • serangkaian lelucon tentang pengetikan, keusangan kerangka yang dipercepat, angka + kejutan-kejutan, dan banyak lagi. Anda tahu, set yang benar-benar standar, serangkaian pengembang sopan menggunakan bahasa yang lebih tua dan lebih mapan (hei, saya tahu bahwa platform .net lebih muda dari js, tetapi bukan "dewasa" dalam arti literal).

Ayo ikut!


September 2017. Saya memulai pekerjaan hangat dan lampu baru dengan tumpukan teknologi baru (.net core web api + angular 4) dan tugas saya hanyalah backend. Kata Angular terdengar kasar bagi saya, npm dan nodejs sangat terkait dengan smoothie dan skuter gyro. Timlid, melihat ini dan memahami, mengajari saya kursus singkat tentang cara meluncurkan semua syaitan ini. Sama seperti dalam lelucon tentang Chukchi dan anjing di luar angkasa. Saya ingat julukan kelelawar yang harus saya mulai (mengingat mulai npm mulai saya merasa sangat tidak perlu untuk sifat lembut saya), dan membenamkan diri dalam hangat dan tabung Inti bersih .net


Oktober 2017. Bel pertama. Timlid mengatakan bahwa pekerja garis depan kami segera menyelesaikan 4 proyek dan menawarkan untuk memotong beberapa bagian di area admin kepada saya. Memotivasi itu, kata mereka, mudah di sana, cukup ulangi bagaimana hal itu dilakukan untuk entitas N, hanya sekarang untuk M. Kepada rekan-rekan yang melarikan diri untuk skuter gyro dan vape untuk saya, buru-buru membaca beberapa program pendidikan singkat tentang Angular, dengan copy-paste dan keberuntungan, saya Saya melahirkan beberapa bagian yang, dengan reservasi, berfungsi. Timlid puas, saya kaget, dan sepertinya tugas di backend muncul di papan ...


Tapi tidak. Ada banyak back-endors, sudah ada beberapa tugas untuk mereka, dan bidang yang belum dibajak ada di depan. Tugas baru, sudah langsung di portal, membuat saya menanggapi masalah ini dengan serius. Kolega berusaha keras untuk menyelipkan celanaku dan membawaku ke salon, dan selama seminggu aku menyelami bahan bacaan tentang Angular, TypeScript, npm, webpack, dan lainnya. Omong-omong, artikel tentang Javascript modern untuk dinosaurus banyak membantu - https://habrahabr.ru/company/mailru/blog/340922/ .


Setelah beberapa waktu, saya dapat menutup tugas-tugas front-end yang sederhana, merasa seperti penjaga gerbang tanpa kehadiran seorang pelayan. Masih tergelak pada lelucon tentang front-end, saya sarankan agar rekan-rekan seperjuangan saya berkumpul dan mendengarkan pengalaman pisang-strawberry saya. Semua orang tertawa, tetapi secara diam-diam semua orang ingin memahami jenis gelembung yang terjadi di front-end yang cepat ini (pada kenyataannya, tidak).


Tanpa basa-basi lagi, saya menceritakan kembali artikel di atas dari Habr, membumbui dengan pengetahuan dasar saya tentang Angular. Mitap datang dengan ledakan, dan, kemudian, saya menghabiskan serangkaian yang seperti itu - tentang ujung depan untuk backend, yang, bagaimanapun, tidak begitu penting untuk cerita kita. Satu-satunya hal yang penting adalah implementasi mereka membawa saya ke studi yang lebih mendalam tentang tumpukan modern teknologi front-end.


Gatal


Di tempat kerja, semuanya berubah, waktu yang agak tenang datang dalam kehidupan keluarga, dan gatal muncul. Seperti, Anda tahu, kecil, masih cukup rapuh dan tinggal di suatu tempat di perbatasan alam bawah sadar. Pikiran melintas di kepala saya, kata mereka, tiga tahun yang lalu, saya hampir sepenuhnya berhenti melakukan hobi-pemrograman game. Tapi bagaimana jika Anda menggabungkan pengetahuan segar dan ...


Saya melihat WebGL untuk waktu yang lama, tetapi sebelumnya saya takut dengan kurangnya bantuan (mengetik, penyelesaian otomatis) saat menggunakannya. Dan di sini, tolong - peluru perak yang tidak ada dalam daging, Palu yang sama, ketika diambil, semuanya menjadi paku. TypeScript


Bagi saya, sebagai orang yang tahu sakitnya dengan panggilan balik neraka, var self = ini, ikat (ini), tidak terdefinisi bukan fungsi ... Jadi, bagi saya Scriptrip bahkan bukan embusan angin segar, tetapi sejenis penyihir di kapal luar angkasa biru, yang, turun dari surga, dengan malas melemparkan saya - nak, lupakan semua yang Anda ketahui tentang js sebelumnya, dan saya akan menunjukkan kepada Anda seberapa dalam lubang kelinci. Apakah analogi ini terlihat kacau dan pada umumnya semacam campur aduk dari analogi lain? Benar, seperti TypeScript itu sendiri sekilas.


Kelas, antarmuka, pengetikan, async, kesalahan kompilasi, dan kesalahan ketik, penyelesaian kode, bekerja tanpa rebana, perilaku yang dapat dimengerti, bukannya mencegah var fuck-the-scope. Tentu saja, setelah beberapa saat, saya menyadari bahwa sponsor dari sebagian besar kebahagiaan ini bukanlah TypeScript sama sekali, tetapi JavaScript itu sendiri, dalam versi modernnya (ES6 ke atas). Tetapi pada saat itu, sepertinya saya telah menemukan seorang nabi yang akan memimpin garis depan ke yang cerah, komunis masa depan Tambahkan ke ini kemajuan yang cukup serius dari berbagai IDE di bidang Intellisense dan bantuan kepada pengembang, dan mungkin Anda akan mengerti kesenangan anak anjing saya.


Ketidakberdayaan


Pukulan serius pertama yang saya sadari adalah TypeScript itu sendiri. Upaya untuk mengaitkannya dengan proyek kosong membuat saya mengerti - saya tidak bisa mengerti apa pun di luar sudut dan sudut-cli, yang melakukan banyak pekerjaan kotor bagi saya. Apakah saya memerlukan kompiler? Ok, masukkan ke package.json, lakukan npm install, jalankan tsc dan ... tidak ada. Ah, apakah Anda harus menginstalnya secara global? Mengabaikan detail membosankan dari perang saya dengan semua hal ini, saya akan mengatakan bahwa beberapa waktu kemudian saya belajar untuk mengubah main.ts menjadi main.js. Tapi di depan saya sibuk dengan webpack.


Ya, sekarang saya menyadari bahwa itu mungkin dilakukan tanpa dia. Tapi ketika di tangan-tangan kikuk Typecript, segala sesuatu di sekitarnya tampak seperti sudut-cli. Sudah setelah implementasi webpack saya belajar bahwa kompiler TypeScript itu sendiri dapat "memonitor" perubahan dalam file, bahwa masalah dengan impor / ekspor dapat diselesaikan tanpa webpack.


Mengatasi


Setelah sekitar satu minggu, saya dapat membuat proyek di mana saya menulis kode TypeScript, mengklik "Simpan" dan semuanya berubah sebagaimana mestinya - webpack secara otomatis mengkompilasi ulang semua file saya ke dalam satu bundel, pertama menjalankan compiler TypeScript pada mereka, dan kemudian menjatuhkan build ke folder terpisah di mana saya menyalin hal-hal statis lainnya, dan di browser pada saat itu lite-server memuat ulang halaman. Saya mengatakan bahwa semuanya terjadi secara otomatis? Tidak, semuanya terjadi secara otomatis . Joy tidak mengenal batas, dan saya duduk untuk menulis arena tembak sederhana.


Di mana itu dimulai tanah air apakah game untuk saya? Tentu saja, dengan hal-hal dasar seperti vektor dan matriks matematika. Saya berhasil mengatasi sindrom Not Invented Here di tempat kerja, tetapi dalam hobi itu tidak hilang. Saya tidak ingin perpustakaan yang sudah jadi, jadi saya duduk untuk menulis matematika saya. Tidak, itu kata yang terlalu keras. Saya membuka kerangka FreePascal saya sebelumnya ( https://github.com/perfectdaemon/tiny-glr/ ) dan mulai mengkonversi matematika dari sana.


Ke depan, saya akan mengatakan bahwa, secara umum, kerangka kerja saya yang baru adalah konversi yang lama dari Free Pascal ke TypeScript. Diberikan lebih dari tiga tahun absen di game dev, saya tidak bisa membuat arsitektur yang lebih baik, atau bahkan mengingat apa kekurangan di masa lalu.


Setelah beberapa waktu, saya mulai kehabisan nafas: motivasi menurun secara alami, beban kerja meningkat. Dan kemudian pada igdc mengumumkan kontes lain. Dan percayalah, kompetisi adalah motivator eksternal yang luar biasa yang menetapkan batas tematis, teknis, dan waktu.


Persaingan


Saya sudah mengatakan di artikel terakhir saya apa itu kegilaan igdc , tapi saya akan mengulangi secara singkat di sini - komunitas yang hangat dan hangat yang mengadakan kontes pendek atau menengah untuk mengembangkan game pada topik tertentu. Tanpa hadiah uang tunai, sponsor terkenal dan jaminan keamanan kerja. Oh ya, bahkan tanpa iklan, antusiasme dan dengan keterlibatan sumbangan sukarela untuk hosting dan domain. Dan selama hampir 15 tahun.


Tema Persaingan - Game Sampah . Diberikan paket sumber daya grafis yang luas dan beragam. Tugas para peserta adalah membuat game hanya menggunakannya. Genre dan tema tidak terbatas, penggunaan suara dan musik apa pun diperbolehkan, karena hanya gambar yang ada dalam paket. Ada batasan teknis historis terkait dengan peluncuran yang benar-benar offline, tanpa installer, pengunduhan, dan banyak lagi.


Yang terakhir adalah masalah kecil, karena Chrome dan perusahaan melarang banyak hal ketika pengguna membuka file html secara lokal. WebGL mungkin tidak hidup, skrip tidak ingin ditarik, belum lagi sumber daya grafis. Ada jalan keluar - kami membuat server web super kecil lokal dan skrip startup untuk pengguna yang akan mengambilnya dan membuka browser favorit pengguna di alamat yang diinginkan.


Tugasnya sederhana, saya masuk ke exe 6-kilobyte di C # dan nama panggilan kelelawar di dekatnya, yang mendefinisikan folder root untuk server dan port.


Tapi, cukup tentang halangan kecil ini untuk tujuan yang besar dan bersih - menulis permainan untuk kompetisi.


Game kompetisi


Melihat sumber daya, saya menyadari bahwa penembak arena dengan penggunaannya akan berubah menjadi cukup solid.


Setelah menyelesaikan hal-hal dasar, saya melanjutkan ke pemilihan sumber daya yang saya butuhkan. Pengiris terakhir dalam bentuk atlas tekstur terlihat seperti ini:



Ngomong-ngomong, beberapa hal yang dipanggang di atlas tidak pernah digunakan dalam permainan. Setelah memuat sumber daya, saya mulai fungsional baru untuk saya sendiri - animasi sprite. Saya senang ketika kecil ketika semuanya berubah:



Fisika sendiri


Menghubungkan fisika orang lain dengan keinginan yang tak terkendali untuk menciptakan semua milik saya sendiri tampaknya setidaknya menghujat, dan, menurut saya, bahkan tidak dianggap oleh organisme yang antusias (saya baru saja mengalahkan animasi sprite, ingat?). Juga, apa yang bisa sulit dalam pemrosesan tabrakan sederhana berdasarkan pada persegi panjang (Axis-aligned bounding box, AABB) dan lingkaran? Banyak hal. Mulai dari membuat karakter terjebak di sudut-sudut yang tidak terlihat dan berakhir dengan fakta bahwa Anda membawa semua objek dunia Anda ke persegi panjang dan lingkaran.


Itu tidak mungkin untuk menyelesaikan semua masalah, tetapi beberapa fisika tetap muncul:



Kedengarannya


Diam-diam berharap itu sulit. Bahkan, ternyata entah bagaimana curiga sederhana dan efisien. Kami menciptakan konteks audio, membuat buffer audio, menempatkan musik / suara di sana dalam format apa pun yang dapat diterima untuk browser (saya menggunakan wav), membuat node dan mengatakan dari mana buffer untuk bermain.


Suara yang saya hasilkan menggunakan bfxr ( https://www.bfxr.net/ ).


Khaki


Kruk, keputusan ad hoc, podhachivaniya - sulit untuk menemukan orang yang tahu kata-kata ini hanya dengan desas-desus. Pada akhir kontes, saya memasukkan beberapa cadangan penting.


Tidak ada output teks - html yang digunakan


Pada akhir kompetisi, menjadi jelas bahwa saya tidak akan punya waktu untuk mentransfer teks ke mesin. Bahkan tanpa generator. Ada banyak opsi, di sini ada empat opsi utama:


  1. Rendering teks pada kanvas 2D transparan yang berada di atas kanvas dengan WebGL.
  2. Buat game tanpa teks
  3. Panggang kata-kata yang diperlukan dan gunakan sebagai sprite
  4. Output HUD dalam html

Menurut ketentuan kompetisi, dimungkinkan untuk hanya menggunakan font piksel khusus yang disediakan, sehingga opsi pertama (rendering teks pada kanvas 2D) dijatuhkan. Kanvas dapat dirender hanya menggunakan font sistem. Font yang dimuat ke css melalui fontface berfungsi dengan sangat tidak stabil.


Bermain tanpa teks adalah pilihan yang bagus dan kreatif. Sangat disayangkan bahwa dengan kreativitas pada saat itu saya sudah merasa tidak enak.


Kosakata minimum yang disyaratkan adalah besar dan meningkatkan ukuran aset. Selain itu, tampilan angka masih membutuhkan logika tertentu.


Dan akhirnya, kami sampai pada kruk asli, yang saya gunakan - Saya baru saja mengimplementasikan HUD sebagai markup html di bawah kanvas, menghubungkan @fontface ke css, dan mengatur pembaruan melalui API DOM standar (getElementById).


Game restart - document.location.reload ()


Ketika seorang pemain meninggal, dia ingin menutup permainan atau memulainya lagi. Sayangnya, jika Anda tidak menyediakan mekanisme restart dari awal dan menodai seluruh kondisi permainan pada sekelompok kelas yang tidak terorganisir dengan baik, Anda tidak akan mendapatkan restart yang baik. Akan selalu ada tempat ajaib yang belum diatur ulang ke nol.


Penopang yang sangat baik dalam hal ini adalah halaman dangkal memuat kembali melalui header document.location.reload () yang disebutkan dalam header. Mengingat ukuran kecil dari bangunan final (kurang dari 300 kb, termasuk semua sumber daya) dan fakta bahwa permainan bekerja secara lokal, kecepatan memulai kembali dapat diabaikan.


Apa yang terjadi



Anda dapat mencobanya online di sini: https://perfectdaemon.imtqy.com/151/index.html
Tautan ke repositori: https://github.com/perfectdaemon/ts-game
Versi repositori dengan kode sumber permainan ini: https://github.com/perfectdaemon/ts-game/releases/tag/0.1.0


Kesimpulannya adalah akhir yang menyenangkan.


Sebagai kesimpulan, saya ingin menguraikan secara singkat pro dan kontra subjektif dari penulisan game di WebGL + TypeScript.


Pro


  • Menulis sekali, mainkan / debug di mana-mana. Sangat keren bahwa saya bisa meletakkan gitub.io di imtqy.com, dan siapa saja bisa memainkannya dari perangkat apa pun dengan browser. Wajar dengan sejumlah pemesanan.
  • Setelah pengaturan tertentu dan menambahkan TypeScript, bekerja dengan JS modern tidak terlalu buruk.
  • Nyaman untuk membuat konteks (dibandingkan dengan Win API dan OpenGL)
  • Ada alat yang mudah digunakan (Visual Studio Code), yang dilengkapi dengan plugins dan sangat membantu dalam menulis kode melalui tips, cuplikan, dan catatan tentang area masalah.

Cons


  • Javascript berjalan dalam satu utas. Dan masalahnya bukan bahwa Anda ingin mempertimbangkan fisika atau logika dalam aliran terpisah. Profiling menunjukkan bahwa panggilan WebGL sedang diblokir, mis. mereka menunggu kontrol untuk kembali dari driver kartu video sebelum melanjutkan dengan eksekusi kode lebih lanjut. Meskipun sebagian besar panggilan WebGL tidak menghasilkan apa-apa selain batal. Implementasi Desktop OpenGL (pada beberapa driver) untuk banyak fungsi mengembalikan kontrol secara instan, yang secara signifikan meningkatkan kecepatan rendering.
  • Langkah kecil ke kiri / kanan - dan Anda benar-benar sendirian. Memiliki masalah dengan Angular dan Typcript? Dua tautan pertama ke stack overflow akan membantu Anda. Ada keinginan untuk berteman dengan Typescript secara terpisah dan muncul bug / pertanyaan aneh? Bersiaplah untuk kenyataan bahwa Anda mungkin sendirian. Tentu saja, sebagai orang yang sebelumnya menulis di tumpukan FreePascal + OpenGL yang sangat populer (tidak ada), saya sudah terbiasa. Tetapi dalam kasus bahasa dewasa seperti C ++, akan selalu ada orang India yang telah memecahkan masalah seperti itu. Dan kemudian orang Cina, yang menyelesaikannya menggunakan controller dari Guitar Hero dan Arduino.

Source: https://habr.com/ru/post/id479918/


All Articles