Pada bagian
pertama saya berbicara tentang masalah yang saya temui dalam proses pembuatan game 3D untuk browser menggunakan Three.js. Sekarang saya ingin membahas secara terperinci penyelesaian beberapa masalah penting saat menulis gim, seperti membangun level, mendeteksi tabrakan, dan mengadaptasi gambar ke proporsi jendela peramban apa pun.
Diagram level
Sebenarnya, level itu sendiri dibuat dalam editor 3D, yaitu geometri, pemetaan tekstur, pembuatan bayangan, dll. Saya menggambarkan semua ini di bagian pertama. Mengapa ada skema lain? Faktanya adalah bahwa Three.js tidak menawarkan segala jenis mesin fisik, dan saya menggunakan skema level untuk mengidentifikasi kendala.
Three.js untuk menyelesaikan masalah tabrakan hanya menawarkan raytracing - cara paling sederhana untuk menentukan persimpangan geometri objek. Pada prinsipnya, ini dapat digunakan, dan saya bahkan melakukannya di salah satu proyek saya yang lain. Itu adalah kota virtual tepat di situs, di browser. Anda bisa bergerak keliling kota dan tidak melewati tembok.
Dalam kasus ketika persimpangan geometri pemain dan bangunan terjadi selama gerakan, saya menerapkan tolakan pemain dengan jarak tertentu ke arah yang berlawanan dengan dinding. Tetapi untuk ini, objek harus paralelepiped. Di sekitar beberapa objek yang kompleks, saya membuat colliders (kami akan memanggil objek tak kasat mata yang memainkan peran sebagai penghalang dan mencegah pemain melewati diri mereka sendiri), yang melaluinya persimpangan dibuat. Dan bagian bawah dari beberapa bangunan, yang hanya "kotak", kadang-kadang digunakan sebagai colliders sendiri.
Pada objek yang secara geometris kompleks, penelusuran sinar mungkin tidak berfungsi atau berperilaku tidak tepat. Dan, seperti solusi alternatif, Anda dapat menanamkan objek bukan hanya satu, tetapi beberapa colliders kecil yang tak terlihat dalam bentuk paralelepiped dengan transparansi 100%, yang disusun bersebelahan dan di atas satu sama lain, secara kasar mengulangi bentuk objek.
Dalam game tentang ruang bawah tanah, level adalah objek panjang tunggal dengan gerakan potong untuk memindahkan pemain. Sebenarnya, untuk menyelesaikan masalah tabrakan, seseorang dapat menempel colliders yang tidak terlihat di mana diperlukan dan menggunakan raytracing. Namun, saya memutuskan untuk pergi ke arah lain.

- Pertama, saya ingin mengotomatisasi proses menciptakan berbagai colliders.
- Kedua, Anda hanya dapat menggunakan informasi tentang colliders, yaitu koordinatnya di ruang angkasa, dan tidak memuat adegan 3D itu sendiri dengan beberapa objek kosong tambahan.
- Ketiga, karena permainan hanya menggunakan tampilan sisi dan salah satu koordinat tidak pernah berubah saat bergerak, Anda dapat menggunakan perhitungan persimpangan hanya dalam dua koordinat.
- Dan keempat, setelah semua, pada kenyataannya, akan ada skema level. Selain itu, datang dengan level baru hanya nyaman dimulai dengan skema seperti itu. Anda cukup menyeret blok di sekitar layar dalam editor grafis apa pun, membangun koridor dan hambatan baru, dan kemudian menjalankan skrip dan mendapatkan informasi tentang colliders. Artinya, masalah editor level sebagian diselesaikan.
Saya menulis sebuah skrip yang mengambil parameter input seperti nama file skema level (png) dan warnanya, yang isinya ditafsirkan sebagai hambatan. Warna ruang kosong standar adalah hitam. Untuk diproses oleh skrip, skema setiap level harus disimpan dalam file png terpisah. Misalnya, untuk level terendah, tampilannya seperti ini:
Saya setuju bahwa satu blok harus memiliki lebar 80 piksel dan tinggi 48 piksel. Ini sesuai dengan 4 x 2,4 meter di dunia 3D. Dimungkinkan untuk membuat 40 x 24 piksel, yaitu, sepuluh kali, tetapi dalam gambar terlihat kecil.
Hasil skrip di tingkat pertama (gambar dipotong ke kanan):

Script dieksekusi di browser. Saya pikir tidak ada gunanya markup html, itu dasar: bidang entri data dan tombol mulai. Selanjutnya, gambar baca ditampilkan di kanvas. Dan sebagai hasil dari skrip, sebuah array ditampilkan di bawah gambar dalam skala dunia 3D, yang berisi koordinat kiri dan kanan atas setiap blok, dan dengan offset yang ditentukan dalam skrip untuk setiap level. Array ini dapat disalin dan ditempelkan ke dalam daftar collider untuk digunakan dalam game (lebih lanjut tentang itu di bawah), itu akan disimpan dalam semacam konstan. Koordinat juga muncul pada gambar itu sendiri, tetapi dalam kerangka referensi gambar 2D. Angka-angka ini ditampilkan di tengah setiap blok dan memungkinkan Anda untuk memeriksa apakah semua blok termasuk dalam perhitungan. Sendiri, angka-angka ini tidak diperlukan untuk apa pun kecuali untuk inspeksi visual. Beberapa blok, seperti kolom yang dilewati pemain, tidak boleh dihitung. Tentang objek mana yang dikecualikan dari perhitungan - di bawah ini.
Selain itu, misalnya, di tingkat kedua ada pelat horizontal tipis tempat pemain berjalan. Mereka harus dipertimbangkan. Oleh karena itu, Anda perlu memastikan bahwa angka-angka juga muncul pada mereka. Dalam diagram, buat tingginya 2 piksel.
Sekarang, tentang bagaimana skrip memperhitungkan blok:
- Skema ini diproses oleh blok 80x48, di mana masing-masing area diambil dari piksel ke-2 hingga ke-79 secara horizontal dan dari piksel ke-ke-47 secara vertikal. Pixel pertama dan terakhir tidak digunakan sehingga di sekitar blok Anda dapat membuat bingkai hitam dengan lebar 1 piksel, ini meningkatkan persepsi visual dari rangkaian dan memfasilitasi pembuatannya.
- Semua piksel dari baris atas blok dilihat. Jika ada yang berwarna di antara mereka, maka koordinat blok bergerak dari pixel berwarna pertama ke terakhir secara horizontal dan ke ketinggian penuh blok secara vertikal dalam array terakhir. Ini akan menjadi blok kosong pada lebar penuh atau sebagian.
- Semua piksel garis bawah blok dilihat. Jika ada yang berwarna di antara mereka, tetapi tidak ada satu berwarna di baris atas, maka koordinat blok bergerak dari pixel berwarna pertama ke terakhir secara horizontal dan 3 piksel secara vertikal dari bawah ke array terakhir. Ini akan menjadi platform untuk berjalan. Di dalam satu blok ada beberapa platform horisontal. Platform dikenali hanya di bagian bawah blok. Koordinat platform "tenggelam" ke dalam blok, yang terletak di bawah, sehingga permukaan platform berada pada level yang sama dengan blok tetangga - bukan platform.
- Kolom dan dekorasi lainnya di dalam blok kosong tidak diproses, karena hanya baris piksel atas dan bawah yang dipertimbangkan. Oleh karena itu, di dalam blok, Anda dapat menempatkan dekorasi, penjelasan untuk diagram, petunjuk, kolom, dll., Tanpa takut bahwa ini entah bagaimana akan mempengaruhi hasil skrip.
Kemudian semua koordinat yang diperoleh dari array diterjemahkan ke dalam skala dunia 3D, dikalikan dengan koefisien skalanya (yang dipilih dalam editor 3D saat dibuat). Array siap digunakan dalam gim. Kode skrip ditulis dengan tergesa-gesa, sehingga tidak berpura-pura anggun, tetapi melakukan tugasnya.
Sekarang - tentang cara permainan bekerja dengan berbagai blok. Gim ini menggunakan koridor berpotongan (level). Ketika seorang pemain berubah menjadi koridor, array blok baru terhubung: dan untuk setiap koridor, sesuai, array sendiri diperoleh, diperoleh dari skema levelnya. Selama pergerakan pemain, koordinatnya diperiksa untuk berada di dalam setiap blok. Dan jika dia ada di dalam blok apa pun, maka kita mendapatkan tabrakan. Tetapi dengan setiap gerakan pemain kita tidak perlu mencari persimpangan dengan semua blok level, karena bisa ada banyak dari mereka. Buat array hanya blok yang paling dekat dengan pemain.
collisionsUpdate: function(x, y, dw, dh) { var coll = []; var o; for (var i = 0; i < ap.v.lv.d.length; i++) { o = ap.v.lv.d[i]; if ((o[0] >= x - ap.v.dw) & (o[2] <= x + ap.v.dw)) { if ((o[1] >= y - ap.v.dh) & (o[3] <= y + ap.v.dh)) { coll.push(o); }; }; }; ap.v.coll = coll; },
Di sini, pada input x, y adalah koordinat pemain saat ini, dw, dh adalah jarak di mana Anda ingin mencari blok secara horizontal dan vertikal, misalnya 12 dan 8 meter. Dengan kata lain, ambil semua blok di sekitar pemain dalam kotak 24x16 meter persegi. Mereka akan berpartisipasi dalam pencarian bentrokan. ap.v.lv.d [i] adalah elemen dari array blok dari level saat ini, pada kenyataannya, dia sendiri juga merupakan array dari 4 angka yang mendefinisikan batas-batas satu blok - [x1, y1, x2, y2], oleh karena itu, untuk memeriksa kuadrat secara horizontal kita mengambil elemen dengan indeks 0 dan 2, dan secara vertikal - 1 dan 3. Jika ada kecocokan, lalu tambahkan blok ini ke daftar untuk collision ap.v.coll.
Ketika pemain bergerak, kami akan memperbarui daftar tabrakan ini, tetapi, untuk menghemat kinerja, kami akan melakukan ini tidak pada setiap langkah (atau lebih tepatnya, merender frame), tetapi ketika pemain meninggalkan kotak tertentu, sedikit lebih kecil, ditentukan dalam ap.v.collwStep dan ap.v.collhStep, mis. 8 dan 4 meter. Artinya, kita akan memasang kembali susunan tabrakan lagi ketika pemain melewati jalur tertentu secara horizontal atau vertikal dari posisi aslinya. Pada saat yang sama, mari kita ingat posisinya di mana kita memasang kembali array untuk menggunakannya untuk iterasi berikutnya. pers [kapak] - di sini dengan kapak yang kami maksud adalah sumbu koordinat (kapak), bisa x atau z, tergantung pada arah koridor di mana pemain berjalan.
Mengapa kesulitan seperti itu? Mengapa tidak menggunakan seluruh susunan tabrakan di tingkat dan tidak mandi uap. Faktanya adalah bahwa deteksi tabrakan dilakukan sesuai dengan algoritma yang jauh lebih kompleks, dan tidak menguntungkan untuk memeriksa tabrakan dengan benar-benar semua blok level, dan bukan yang paling dekat, di setiap frame rendering. (Meskipun, ini tidak akurat.)
Definisi tabrakan pada setiap rendering frame menggunakan array collision yang disiapkan di atas:
Kode collisionsDetect: function(x, y, xOld, yOld, up) {
Di sini x, y, xOld, yOld adalah koordinat baru dan saat ini dari pemain. Yang baru dihitung dengan satu sentuhan tombol, berdasarkan kecepatan yang diberikan, yaitu, ini adalah koordinat yang memungkinkan. Mereka diperiksa untuk melihat apakah mereka berada di dalam blok mana pun dari daftar tabrakan. Jika mereka jatuh, maka mereka kembali ke yang lama, dan pemain tidak melewati rintangan. Dan jika mereka tidak jatuh, maka mereka menjadi lancar. pw2 dan ph2 adalah setengah lebar dan tinggi collider imajiner pemain (lebar pemain / 2, tinggi pemain / 2). Output dikeluarkan jika ada tabrakan horizontal dan vertikal (collw, collh), apakah ada blok dukungan di bawah pemain (supportf) - ini memperjelas apakah akan memulai animasi musim gugur lebih lanjut atau jika pemain hanya beralih ke blok tetangga, dan seterusnya. Hanya saja, jangan bertanya mengapa saya menambahkan 0,001 di sana dan mengurangi 0,11. Ini adalah kruk mengerikan yang mencegah jatuh melalui blok dan efek jitter ketika bertabrakan dengan penghalang horizontal ... Fungsi ini berfungsi, tetapi perlu ditulis ulang dengan cara normal. Optimalisasi fungsi ini juga belum hilang.
Saya pikir dengan tabrakan itu ada baiknya untuk mengakhiri di sini.
Sulit untuk mengatakan seberapa cepat metode saya atau mungkin lebih lambat daripada penelusuran ray, tetapi dalam kasus yang terakhir, Three.js juga menyimpan berbagai objek yang berpartisipasi dalam sistem tumbukan. Hanya saja tabrakan di sana ditentukan oleh metode memancarkan sinar dan persimpangan dengan bidang sisi-sisi objek, dan dengan saya, dengan menentukan apakah koordinat satu objek berada di dalam yang lain di sepanjang masing-masing kedua sumbu.
Gim ini juga memiliki objek bergerak (hiu) dan objek penanda yang memicu beberapa jenis animasi (misalnya, kontak dengan air memicu pergerakan hiu). Semua objek ini juga berpartisipasi dalam tabrakan, dan beberapa dengan koordinat waktu yang bervariasi. Di sana, anehnya, semuanya lebih sederhana: selama pergerakan objek koordinatnya dibandingkan dengan koordinat pemain.
Gamepad
Secara umum, memelihara gamepad javascript di browser bukanlah tugas yang sepele. Tidak ada tombol tekan dan lepaskan acara. Hanya ada peristiwa yang menghubungkan dan melepaskan perangkat dan keadaan yang dapat diperoleh dengan pemungutan suara berkala, dan kemudian membandingkannya dengan yang sebelumnya.
Sebuah video yang mendemonstrasikan pengoperasian gamepad di browser pada tablet pada Windows 8.1 dan PC pada Windows 10. Tablet ini, bagaimanapun, adalah yang lama, dirilis pada tahun 2014, sehingga pencahayaan dinamis dimatikan dalam game di atasnya.
Untuk polling gamepad, fungsi yang dipanggil sekali setiap 100 milidetik digunakan. Sudah diatur menggunakan fungsi perpustakaan saya m3d.lib.globalTimer.addEvent.
m3d.lib.globalTimer.addEvent({ name: 'gamepad', ti: 100, f: function() { var st = m3d.gamepad.state(); if (st == false) { if (contr.gpDownFlag == true) { m3d.gamepad.resetH(); }; }; } });
Di sini globalTimer adalah sistem manajemen acara javascript setInterval timer yang saya tulis. Di sana, sederhananya serangkaian acara ditambahkan ke array tertentu yang perlu dipanggil pada interval yang berbeda. Kemudian, satu set timer Interval diatur dengan frekuensi yang sesuai dengan acara dengan frekuensi tertinggi dari semua. Pengatur waktu polling fungsi m3d.lib.globalTimer.update (), yang berjalan melalui daftar semua peristiwa dan menjalankan fungsi-fungsi yang telah dijalankan. Saat menambahkan atau menghapus acara, frekuensi interval juga dapat berubah (misalnya, jika Anda menghapus acara tercepat).
Gim ini juga mendefinisikan penangan untuk setiap kunci gamepad: 'a' adalah untuk sumbu (kapak), 'b' adalah untuk tombol (tombol), dan 11 adalah penyimpangan kiri sepanjang sumbu horizontal dari salib (seolah-olah tombolnya 1), 12 - penyimpangan kanan sepanjang sumbu horizontal dari salib (seolah-olah tombolnya 2), 21 dan 22 - untuk sumbu vertikal. Sebagai contoh:
['a', 11],
['b', 3]
berarti bahwa fungsi selanjutnya akan diatur pada waktu yang sama untuk deviasi sepanjang sumbu horizontal ke kiri dan untuk tombol 3 (kiri). Nah, kemudian fungsi diatur yang akan dieksekusi ketika tombol ditekan, dan kemudian ketika dirilis.
m3d.gamepad.setHandler( [ ['a', 11], ['b', 3] ], function(v) { if (contr.btState.lt == false) { contr.keyDownFlag = true; contr.btState.lt = true; contr.gpDownFlag = true; apcontrolsRenderStart(); }; }, function(v) { contr.btState.lt = false; m3d.contr.controlsCheckBt(); apcontrolsRenderStart(); } );
Di sini apcontrolsRenderStart () adalah fungsi yang meluncurkan render jika belum berjalan. Secara umum, dukungan untuk gamepad terikat erat dengan perpustakaan m3d saya, jadi jika saya melanjutkan untuk menggambarkan semua fitur-fiturnya, itu akan membentang untuk waktu yang sangat lama ...
Saya hanya akan memberi Anda bagian darinya - gamepad, di mana saya menerapkan inisialisasi gamepad, pemasangan penangan, dan pemungutan suara negara dengan cara paling sederhana.
Kode gamepad: { connected: false, gamepad: {}, gamepadKey: '', axesCount: 0, buttonsCount: 0, f: [],
Secara umum, dukungan gamepad dalam game masih belum lengkap: hanya dukungan untuk gamepad yang paling sederhana yang diterapkan, tetapi bukan yang, misalnya, digunakan di XBox, karena saya tidak memilikinya. Jika saya mendapatkannya, saya akan memprogramnya dan bekerja dengannya. Akan ada kemungkinan untuk menyesuaikan kecepatan karakter, yaitu, dimungkinkan untuk bergerak pada kecepatan apa pun dalam rentang dari langkah untuk menjalankan. Ini dicapai dengan mengambil parameter fraksional dari sumbu. Gamepad saya hanya mengembalikan bilangan bulat -1 dan 1. Selain itu, gamepad saya memiliki salib yang menjijikkan, dan ketika ditekan kiri atau kanan, secara bersamaan menekan ke bawah atau ke atas. Oleh karena itu, saya tidak menggunakan bagian atas dan bawah pada salib dan menduplikasinya dengan tombol di sebelah kanan gamepad ... Dengan merilis permainan saya berencana untuk membuat beberapa profil gamepad. Selain itu, dalam hal menghubungkan beberapa gamepad, hanya yang terakhir yang akan digunakan sejauh ini.
Layar responsif
Gim ini dirancang untuk rasio aspek 16: 9. Tapi saya menambahkan penyesuaian horizontal otomatis ± 10% sehingga di jendela browser yang diperluas tidak ada bilah hitam di samping:
Dan akan seperti ini:

Dalam mode layar penuh, akan ada nyata 16: 9. Dimungkinkan untuk mengadaptasi gambar secara umum dengan rasio aspek apa pun dari jendela browser, tapi saya tidak melakukannya, karena jendela lebar rendah akan mengarah ke sudut tampilan terlalu besar, yang tidak baik dari sudut pandang gameplay: jalan buntu yang jauh, benda, musuh akan segera terlihat dan segala sesuatu yang pemain belum perlu melihatnya. Karena itu, saya membatasi diri untuk menyesuaikan dalam ± 10% dari 16: 9. Namun, untuk monitor sempit (4: 3), saya menyadari kemampuan untuk beralih dari 16: 9 ke mode adaptasi dari 4: 3 ke 16: 9 dengan menekan tombol Y. Tapi tidak lebih luas - jadi, sekali lagi, jangan sampai merusak gameplay. Artinya, Anda dapat bermain dalam rasio 16: 9 klasik, atau Anda dapat memperbesar gambar dengan ketinggian jendela dengan memotongnya secara horizontal. Meskipun, ini juga tidak terlalu baik, misalnya, dalam situasi arcade, ketika sesuatu terbang ke arah pemain dari samping. Hanya sedikit waktu yang tersisa untuk reaksi. Tetapi Anda selalu dapat dengan cepat kembali ke mode klasik.

Adaptasi layar, serta semua tombol pintas yang digunakan dalam game ditampilkan dalam video berikut:
Sebenarnya, rasio aspek diatur dalam pengaturan game.
aspect1:{w:1280, h:720, p:10},
Dan di dalam gim, saat Anda menekan Y, itu akan berganti:
contr.btCodesDn[89] = function() {
Perpustakaan saya memiliki acara yang menggantung di jendela ukuran. Ini adalah bagiannya:
Kode m3dcache.v.vw = window.innerWidth; m3dcache.v.vh = window.innerHeight; m3dcache.v.vclipw = 0; m3dcache.v.vcliph = 0; if (typeof m3dcache.setup.aspect !== "undefined") { if ((m3dcache.setup.aspect.w == 0) || (m3dcache.setup.aspect.h == 0)) {} else { var o = m3d.lib.inBlock(0, 0, m3dcache.setup.aspect.w, m3dcache.setup.aspect.h, 0, 0, m3dcache.v.vw, m3dcache.v.vh, 'center', 'center', 'resize'); if (typeof m3dcache.setup.aspect.p !== "undefined") { if (o.clipx > 0) { ow = ow * (m3dcache.setup.aspect.p / 100 + 1); if (ow > m3dcache.v.vw) { ow = m3dcache.v.vw; }; o = m3d.lib.inBlock(0, 0, ow, oh, 0, 0, m3dcache.v.vw, m3dcache.v.vh, 'center', 'center', 'resize'); }; }; m3dcache.v.vclipw = o.clipx; m3dcache.v.vcliph = o.clipy; var margx = o.clipx + 'px', margy = o.clipy + 'px'; document.getElementById('m3dcontainer').style.marginLeft = margx; document.getElementById('m3dcontainer').style.marginTop = margy; if (document.getElementById('renderer') !== null) { document.getElementById('renderer').style.marginLeft = margx; document.getElementById('renderer').style.marginTop = margy; }; m3dcache.v.vw = ow; m3dcache.v.vh = oh; }; };
m3d.lib.inBlock juga merupakan fungsi dari perpustakaan saya, yang menuliskan persegi panjang ke dalam persegi panjang lain dengan parameter seperti pemusatan, penskalaan atau pemangkasan, dan menampilkan dimensi baru dari persegi panjang bertulis, serta ukuran bidang yang dibentuk dalam proses ini. Berdasarkan informasi ini, wadah div jendela diposisikan. 'renderer' adalah elemen konteks blok dari adegan 3D. Kemudian kanvas diskalakan di sana sesuai dengan parameter yang diperoleh.
UI ditampilkan dalam wadah pada elemen kanvas yang terpisah. Secara umum, pohon dokumen terdiri dari tiga blok DIV transparan dengan posisi absolut (lebih atau kurang mungkin, tergantung pada kebutuhan permainan): di bagian bawah adalah kanvas adegan 3D, di atas adalah kanvas untuk IU dan bagian atas digunakan untuk menghidupkan elemen antarmuka dan efek visual lainnya. . Artinya, UI tidak dirender dalam 3D, tetapi pada knavass-nya, atau lapisan. Tugas menggabungkan lapisan menjadi satu gambar diserahkan ke browser. Untuk bekerja dengan UI, saya memiliki objek khusus di perpustakaan. Secara singkat - intinya adalah sebagai berikut. Daftar sprite dengan elemen UI dalam format png dengan transparansi dimuat. Dari sana, elemen yang diperlukan diambil - latar belakang, tombol. Dan mereka digambar di kanvas tengah menggunakan fungsi js drawImage (img, ix, iy, iw, ih, x, y, w, h). Artinya, fragmen yang diperlukan dari gambar ditampilkan di posisi yang diperlukan di layar. Tombol ditampilkan di atas latar belakang yang melekat padanya - semua posisi dan ukurannya diatur dalam konfigurasi UI. Saat mengubah ukuran jendela, posisi elemen pada kanvas target (tempat mereka ditampilkan) dihitung ulang, tergantung pada apakah elemen ini atau itu dipusatkan secara horizontal dan vertikal atau dijepret ke sudut atau wajah layar mana saja. Ini menciptakan UI adaptif yang tidak bergantung pada rasio aspek layar. Hanya perlu untuk mengatur resolusi minimum yang mungkin secara horizontal dan vertikal dan tidak jatuh di bawahnya sehingga elemen tidak tumpang tindih satu sama lain. Saya akan berbicara tentang UI lain kali, karena artikelnya ternyata sangat banyak, dan saya masih bekerja di UI, karena masih ada banyak kekurangan fungsi yang saya butuhkan. Misalnya, pada monitor resolusi tinggi, antarmuka akan terlihat kecil. Anda dapat mengalikan ukuran elemen dengan koefisien tertentu, tergantung pada resolusi layar. Di sisi lain, mungkin tombol besar di layar tidak diperlukan? Jika resolusi layar sangat besar, maka layar itu sendiri cukup besar.

Dan Anda dapat memberi programmer pilihan - apakah akan skala IU secara dinamis dengan ukuran jendela atau untuk mendistribusikan elemen di sudut-sudut. Dalam hal ukuran dinamis, ada juga pertanyaan mereka sendiri - misalnya, "sabun" antarmuka saat ditampilkan pada skala yang terlalu besar. Jika Anda membuat sprite elemen antarmuka dalam resolusi besar yang sengaja, maka mereka akan memakan banyak ruang dan juga, mungkin, itu tidak akan berguna untuk perangkat kecil - mereka masih tidak membutuhkan sprite besar, tetapi mereka akan menghabiskan memori.
Saya pikir itu cukup untuk hari ini. Masih ada sesuatu untuk dipikirkan, bagaimana menerapkan ini atau itu. Sementara itu, saya ngelantur untuk beberapa waktu dari pemrograman dan melakukan promosi. Saya berencana untuk berpartisipasi dalam sepasang pameran indie dan secara aktif terlibat dalam promosi permainan di jejaring sosial, karena pada bulan November saya berencana untuk pergi ke platform crowdfunding: Saya akan membutuhkan spesialis di bidang grafik 3D dan animasi kerangka untuk menyelesaikan permainan.
Dalam artikel berikut, saya akan berbicara tentang kontrol sentuh di browser untuk perangkat seluler - tidak semua orang menghubungkan gamepad atau keyboard ke tablet, tentang mengoptimalkan grafik 3D untuk perangkat berdaya rendah, dan banyak lagi.