Apa yang Perlu Anda Ketahui Saat Mengonversi Flash Game Menjadi HTML5?
Diterbitkan: 2022-03-10Dengan meningkatnya penggunaan HTML5, banyak perusahaan mulai mengulang judul terpopuler mereka untuk menyingkirkan Flash yang sudah ketinggalan zaman dan mencocokkan produk mereka dengan standar industri terbaru. Perubahan ini terutama terlihat di industri Perjudian/Kasino & Hiburan dan telah terjadi selama beberapa tahun sekarang, jadi pilihan judul yang layak telah dikonversi.
Sayangnya, saat menjelajah Internet, Anda cukup sering menemukan contoh pekerjaan yang tampaknya tergesa-gesa, yang menghasilkan kualitas produk akhir yang disukai. Itulah mengapa merupakan ide bagus bagi pengembang game untuk mendedikasikan sebagian waktu mereka untuk mengenal subjek konversi Flash ke HTML5 dan mempelajari kesalahan mana yang harus dihindari sebelum mulai bekerja.
Di antara alasan untuk memilih JavaScript daripada Flash, selain dari masalah teknis yang jelas, juga fakta bahwa mengubah desain game Anda dari SWF ke JavaScript dapat menghasilkan pengalaman pengguna yang lebih baik, yang pada gilirannya memberikan tampilan modern. Tapi bagaimana melakukannya? Apakah Anda memerlukan pengonversi permainan JavaScript khusus untuk menyingkirkan teknologi usang ini? Nah, konversi Flash ke HTML5 bisa menjadi hal yang mudah — berikut cara menanganinya.
Bacaan yang disarankan : Prinsip Desain Game HTML5
Cara Meningkatkan Pengalaman Game HTML5
Mengonversi game ke platform lain adalah peluang bagus untuk meningkatkannya, memperbaiki masalahnya, dan meningkatkan audiens. Di bawah ini adalah beberapa hal yang dapat dilakukan dengan mudah dan patut dipertimbangkan:
Mendukung perangkat seluler
Konversi dari Flash ke JavaScript memungkinkan menjangkau audiens yang lebih luas (pengguna perangkat seluler); dukungan untuk kontrol layar sentuh biasanya perlu diimplementasikan ke dalam game juga. Untungnya, perangkat Android dan iOS sekarang juga mendukung WebGL, jadi rendering 30 atau 60 FPS biasanya dapat dengan mudah dicapai. Dalam banyak kasus, 60 FPS tidak akan menyebabkan masalah, yang hanya akan meningkat seiring waktu, karena perangkat seluler menjadi semakin berkinerja.- Meningkatkan kinerja
Ketika membandingkan ActionScript dan JavaScript, yang terakhir lebih cepat daripada yang pertama. Selain itu, mengonversi game adalah kesempatan yang baik untuk meninjau kembali algoritme yang digunakan dalam kode game. Dengan pengembangan game JavaScript, Anda dapat mengoptimalkannya atau menghapus sepenuhnya kode yang tidak digunakan yang ditinggalkan oleh pengembang asli. - Memperbaiki bug dan meningkatkan gameplay
Memiliki pengembang baru yang mencari kode sumber game dapat membantu memperbaiki bug yang diketahui atau menemukan yang baru dan sangat langka. Ini akan membuat bermain game tidak terlalu mengganggu para pemain, yang akan membuat mereka menghabiskan lebih banyak waktu di situs Anda dan mendorong untuk mencoba game Anda yang lain. - Menambahkan analisis web
Selain melacak lalu lintas, analisis web juga dapat digunakan untuk mengumpulkan pengetahuan tentang bagaimana pemain berperilaku dalam game dan di mana mereka terjebak selama bermain game. - Menambahkan lokalisasi
Ini akan meningkatkan penonton dan penting untuk anak-anak dari negara lain yang memainkan permainan Anda. Atau mungkin game Anda tidak dalam bahasa Inggris dan Anda ingin mendukung bahasa tersebut?
Mengapa Melewatkan HTML Dan CSS Untuk UI Dalam Game Akan Meningkatkan Performa Game
Ketika datang ke pengembangan game JavaScript, mungkin tergoda untuk memanfaatkan HTML dan CSS untuk tombol dalam game, widget, dan elemen GUI lainnya. Saran saya, berhati-hatilah di sini. Ini berlawanan dengan intuisi, tetapi sebenarnya memanfaatkan elemen DOM kurang berperforma pada game yang kompleks dan ini menjadi lebih penting di seluler. Jika Anda ingin mencapai 60 FPS konstan di semua platform, maka Anda mungkin perlu mengundurkan diri dari HTML dan CSS.
Elemen GUI non-interaktif, seperti bar kesehatan, bar amunisi, atau penghitung skor dapat dengan mudah diimplementasikan di Phaser dengan menggunakan gambar biasa (kelas Phaser.Image
), memanfaatkan properti .crop
untuk pemangkasan dan kelas Phaser.Text
untuk sederhana label teks.
Elemen interaktif seperti tombol dan kotak centang dapat diimplementasikan dengan menggunakan kelas Phaser.Button
. Elemen lain yang lebih kompleks dapat terdiri dari tipe sederhana yang berbeda, seperti grup, gambar, tombol, dan label teks.
Catatan: Setiap kali Anda membuat instance objek Phaser.Text atau PIXI.Text, tekstur baru dibuat untuk merender teks. Tekstur tambahan ini merusak kumpulan simpul, jadi berhati-hatilah agar tidak terlalu banyak .
Cara Memastikan Font Kustom Telah Dimuat
Jika Anda ingin merender teks dengan font vektor kustom (misalnya TTF atau OTF), maka Anda perlu memastikan bahwa font telah dimuat oleh browser sebelum merender teks apa pun. Phaser v2 tidak memberikan solusi untuk tujuan ini, tetapi perpustakaan lain dapat digunakan: Web Font Loader.
Dengan asumsi bahwa Anda memiliki file font dan menyertakan Web Font Loader di halaman Anda, maka di bawah ini adalah contoh sederhana tentang cara memuat font:
Buat file CSS sederhana yang akan dimuat oleh Web Font Loader (Anda tidak perlu memasukkannya ke dalam HTML Anda):
@font-face { // This name you will use in JS font-family: 'Gunplay'; // URL to the font file, can be relative or absolute src: url('../fonts/gunplay.ttf') format('truetype'); font-weight: 400; }
Sekarang tentukan variabel global bernama WebFontConfig
. Sesuatu yang sederhana seperti ini biasanya sudah cukup:
var WebFontConfig = { 'classes': false, 'timeout': 0, 'active': function() { // The font has successfully loaded... }, 'custom': { 'families': ['Gunplay'], // URL to the previously mentioned CSS 'urls': ['styles/fonts.css'] } };
Itu akhirnya, ingatlah untuk memasukkan kode Anda ke dalam panggilan balik 'aktif' yang ditunjukkan di atas. Dan itu saja!
Cara Memudahkan Pengguna Untuk Menyimpan Game
Untuk menyimpan data lokal secara terus-menerus di ActionScript, Anda akan menggunakan kelas SharedObject. Dalam JavaScript, pengganti sederhananya adalah localStorage API, yang memungkinkan penyimpanan string untuk pengambilan nanti, bertahan saat memuat ulang halaman.
Menyimpan data sangat sederhana:
var progress = 15; localStorage.setItem('myGame.progress', progress);
Perhatikan bahwa dalam contoh di atas, variabel progress
, yang berupa angka, akan diubah menjadi string.
Memuat juga sederhana, tetapi ingat bahwa nilai yang diambil akan berupa string atau null
jika tidak ada.
var progress = parseInt(localStorage.getItem('myGame.progress')) || 0;
Di sini kami memastikan bahwa nilai yang dikembalikan adalah angka. Jika tidak ada, maka 0 akan ditetapkan ke variabel progress
.
Anda juga dapat menyimpan dan mengambil struktur yang lebih kompleks, misalnya, JSON:
var stats = {'goals': 13, 'wins': 7, 'losses': 3, 'draws': 1}; localStorage.setItem('myGame.stats', JSON.stringify(stats)); … var stats = JSON.parse(localStorage.getItem('myGame.stats')) || {};
Ada beberapa kasus ketika objek localStorage tidak tersedia. Misalnya, saat menggunakan protokol file://
atau saat halaman dimuat di jendela pribadi. Anda dapat menggunakan pernyataan try and catch untuk memastikan kode Anda akan terus bekerja dan menggunakan nilai default, seperti yang ditunjukkan pada contoh di bawah ini:
try { var progress = localStorage.getItem('myGame.progress'); } catch (exception) { // localStorage not available, use default values }
Hal lain yang perlu diingat adalah bahwa data yang disimpan disimpan per domain, bukan per URL. Jadi jika ada risiko banyak game yang dihosting di satu domain, maka lebih baik menggunakan awalan (namespace) saat menyimpan. Dalam contoh di atas 'myGame.'
adalah awalan seperti itu dan Anda biasanya ingin menggantinya dengan nama gim.
Catatan : Jika game Anda disematkan dalam iframe, penyimpanan lokal tidak akan bertahan di iOS. Dalam hal ini, Anda perlu menyimpan data di iframe induk sebagai gantinya .
Cara Memanfaatkan Mengganti Shader Fragmen Default
Saat Phaser dan PixiJS merender sprite Anda, mereka menggunakan shader fragmen internal sederhana. Tidak memiliki banyak fitur karena disesuaikan untuk kecepatan. Namun, Anda dapat mengganti shader itu untuk keperluan Anda. Misalnya, Anda dapat memanfaatkannya untuk memeriksa overdraw atau mendukung lebih banyak fitur untuk rendering.
Di bawah ini adalah contoh cara memasok shader fragmen default Anda sendiri ke Phaser v2:
function preload() { this.load.shader('filename.frag', 'shaders/filename.frag'); } function create() { var renderer = this.renderer; var batch = renderer.spriteBatch; batch.defaultShader = new PIXI.AbstractFilter(this.cache.getShader('filename.frag')); batch.setContext(renderer.gl); }
Catatan: Penting untuk diingat bahwa shader default digunakan untuk SEMUA sprite serta saat merender ke tekstur. Juga, perlu diingat bahwa menggunakan shader kompleks untuk semua sprite dalam game akan sangat mengurangi kinerja rendering .
Cara Mengubah Metode Pewarnaan Dengan Shader Default
Shader default kustom dapat digunakan untuk menggantikan metode pewarnaan default di Phaser dan PixiJS.
Pewarnaan di Phaser dan PixiJS bekerja dengan mengalikan piksel tekstur dengan warna tertentu. Perkalian selalu menggelapkan warna, yang jelas bukan masalah; itu hanya berbeda dari pewarnaan Flash. Untuk salah satu game kami, kami perlu menerapkan pewarnaan yang mirip dengan Flash dan memutuskan bahwa shader default khusus dapat digunakan. Di bawah ini adalah contoh dari shader fragmen tersebut:
// Specific tint variant, similar to the Flash tinting that adds // to the color and does not multiply. A negative of a color // must be supplied for this shader to work properly, ie set // sprite.tint to 0 to turn whole sprite to white. precision lowp float; varying vec2 vTextureCoord; varying vec4 vColor; uniform sampler2D uSampler; void main(void) { vec4 f = texture2D(uSampler, vTextureCoord); float a = clamp(vColor.a, 0.00001, 1.0); gl_FragColor.rgb = f.rgb * vColor.a + clamp(1.0 - vColor.rgb/a, 0.0, 1.0) * vColor.a * fa; gl_FragColor.a = fa * vColor.a; }
Shader ini mencerahkan piksel dengan menambahkan warna dasar ke warna. Agar ini berfungsi, Anda perlu memberikan warna negatif yang Anda inginkan. Karena itu, untuk menjadi putih, Anda perlu mengatur:
sprite.tint = 0x000000; // This colors the sprite to white Sprite.tint = 0x00ffff; // This gives red
Hasil dalam permainan kami terlihat seperti ini (perhatikan bagaimana tank berkedip putih saat dipukul):
Cara Memeriksa Overdraw Untuk Mendeteksi Masalah Tingkat Pengisian
Mengganti shader default juga dapat dimanfaatkan untuk membantu debugging. Di bawah ini saya telah menjelaskan bagaimana overdraw dapat dideteksi dengan shader seperti itu.
Overdrawing terjadi ketika banyak atau semua piksel di layar dirender beberapa kali. Misalnya, banyak objek mengambil tempat yang sama dan dirender satu sama lain. Berapa banyak piksel yang dapat dirender GPU per detik digambarkan sebagai rasio pengisian. GPU desktop modern memiliki rasio pengisian yang berlebihan untuk tujuan 2D biasa, tetapi GPU seluler jauh lebih lambat.
Ada metode sederhana untuk mengetahui berapa kali setiap piksel pada layar ditulis dengan mengganti shader fragmen global default di PixiJS dan Phaser dengan yang ini:
void main(void) { gl_FragColor.rgb += 1.0 / 7.0; }
Shader ini mencerahkan piksel yang sedang diproses. Angka 7.0 menunjukkan berapa banyak penulisan yang diperlukan untuk mengubah piksel menjadi putih; Anda dapat menyetel nomor ini sesuai keinginan Anda. Dengan kata lain, piksel yang lebih terang di layar ditulis beberapa kali, dan piksel putih ditulis setidaknya 7 kali.
Shader ini juga membantu menemukan objek "tak terlihat" yang karena alasan tertentu masih dirender dan sprite yang memiliki area transparan berlebihan di sekitarnya yang perlu dilucuti (GPU masih perlu memproses piksel transparan dalam tekstur Anda).
Gambar di sebelah kiri menunjukkan bagaimana seorang pemain melihat permainan, sedangkan gambar di sebelah kanan menampilkan efek penerapan shader overdraw ke adegan yang sama.
Mengapa Mesin Fisika Adalah Teman Anda
Mesin fisika adalah middleware yang bertanggung jawab untuk mensimulasikan benda fisika (biasanya dinamika benda tegar) dan tumbukannya. Mesin fisika mensimulasikan ruang 2D atau 3D, tetapi tidak keduanya. Sebuah mesin fisika khas akan memberikan:
- gerakan benda dengan mengatur kecepatan, percepatan, sambungan, dan motor;
- mendeteksi tabrakan antara berbagai jenis bentuk;
- menghitung tanggapan tumbukan, yaitu bagaimana dua benda harus bereaksi ketika mereka bertabrakan.
Di Merixstudio, kami adalah penggemar berat mesin fisika Box2D dan menggunakannya beberapa kali. Ada plugin Phaser yang bekerja dengan baik untuk tujuan ini. Box2D juga digunakan di mesin game Unity dan GameMaker Studio 2.
Sementara mesin fisika akan mempercepat pengembangan Anda, ada harga yang harus Anda bayar: kinerja runtime berkurang. Mendeteksi tabrakan dan menghitung respons adalah tugas intensif CPU. Anda mungkin terbatas pada beberapa lusin objek dinamis dalam pemandangan di ponsel atau menghadapi kinerja yang menurun, serta kecepatan bingkai yang berkurang jauh di bawah 60 FPS.
Bagian kiri gambar adalah adegan dari game, sedangkan sisi kanan menunjukkan adegan yang sama dengan overlay debug fisika Phaser yang ditampilkan di atas.
Cara Mengekspor Suara Dari File .fla
Jika Anda memiliki efek suara permainan Flash di dalam file .fla , maka mengekspornya dari GUI tidak dimungkinkan (setidaknya tidak di Adobe Animate CC 2017) karena kurangnya opsi menu yang melayani tujuan ini. Tetapi ada solusi lain — skrip khusus yang melakukan hal itu:
function normalizeFilename(name) { // Converts a camelCase name to snake_case name return name.replace(/([AZ])/g, '_$1').replace(/^_/, '').toLowerCase(); } function displayPath(path) { // Makes the file path more readable return unescape(path).replace('file:///', '').replace('|', ':'); } fl.outputPanel.clear(); if (fl.getDocumentDOM().library.getSelectedItems().length > 0) // Get only selected items var library = fl.getDocumentDOM().library.getSelectedItems(); else // Get all items var library = fl.getDocumentDOM().library.items; // Ask user for the export destination directory var root = fl.browseForFolderURL('Select a folder.'); var errors = 0; for (var i = 0; i < library.length; i++) { var item = library[i]; if (item.itemType !== 'sound') continue; var path = root + '/'; if (item.originalCompressionType === 'RAW') path += normalizeFilename(item.name.split('.')[0]) + '.wav'; else path += normalizeFilename(item.name); var success = item.exportToFile(path); if (!success) errors += 1; fl.trace(displayPath(path) + ': ' + (success ? 'OK' : 'Error')); } fl.trace(errors + ' error(s)');
Cara menggunakan skrip untuk mengekspor file suara:
- Simpan kode di atas sebagai file .jsfl di komputer Anda;
- Buka file .fla dengan Adobe Animate;
- Pilih 'Perintah' → 'Jalankan Perintah' dari menu atas dan pilih skrip dalam dialog yang terbuka;
- Sekarang file dialog lain muncul untuk memilih direktori tujuan ekspor.
Dan selesai! Anda sekarang harus memiliki file WAV di direktori yang ditentukan. Yang tersisa untuk dilakukan adalah mengonversinya ke, misalnya, MP3, OGG, atau AAC.
Cara Menggunakan MP3 Dalam Konversi Flash Ke HTML5
Format MP3 lama yang bagus kembali, karena beberapa paten telah kedaluwarsa dan sekarang setiap browser dapat memecahkan kode dan memutar MP3. Ini membuat pengembangan sedikit lebih mudah karena akhirnya tidak perlu menyiapkan dua format audio terpisah. Sebelumnya Anda membutuhkan, misalnya, file OGG dan AAC, sementara sekarang MP3 sudah cukup.
Meskipun demikian, ada dua hal penting yang perlu Anda ingat tentang MP3:
- Kebutuhan MP3 untuk memecahkan kode setelah memuat, yang dapat memakan waktu, terutama pada perangkat seluler. Jika Anda melihat jeda setelah semua aset Anda dimuat, itu mungkin berarti MP3 sedang diterjemahkan;
- memutar MP3 tanpa celah sedikit bermasalah. Solusinya adalah dengan menggunakan mp3loop, yang dapat Anda baca di artikel yang diposting oleh Compu Phase.
Jadi, Mengapa Anda Harus Mengonversi Flash ke JavaScript?
Seperti yang Anda lihat, konversi Flash ke JavaScript bukanlah hal yang mustahil jika Anda tahu apa yang harus dilakukan. Dengan pengetahuan dan keterampilan, Anda dapat berhenti berkutat dengan Flash dan menikmati permainan halus dan menghibur yang dibuat dalam JavaScript. Jangan mencoba memperbaiki Flash — singkirkan sebelum semua orang terpaksa melakukannya!
Ingin Pelajari Lebih Lanjut?
Dalam artikel ini, saya berfokus terutama pada Phaser v2. Namun, versi Phaser yang lebih baru sekarang tersedia, dan saya sangat menganjurkan Anda untuk memeriksanya, karena ini memperkenalkan sejumlah besar fitur keren dan segar, seperti beberapa kamera, pemandangan, peta ubin, atau mesin fisika Matter.js.
Jika Anda cukup berani dan ingin membuat hal yang benar-benar luar biasa di browser, maka WebGL adalah hal yang tepat untuk dipelajari dari awal. Ini adalah tingkat abstraksi yang lebih rendah daripada berbagai kerangka kerja atau alat pembuatan game, tetapi memungkinkan untuk mencapai kinerja dan kualitas yang lebih baik bahkan jika Anda bekerja pada game atau demo 2D. Di antara banyak situs web yang mungkin berguna bagi Anda saat mempelajari dasar-dasar WebGL adalah WebGL Fundamentals (menggunakan demo interaktif). Selain itu, untuk mengetahui lebih lanjut tentang tingkat adopsi fitur WebGL, periksa Statistik WebGL.
Selalu ingat bahwa tidak ada yang namanya terlalu banyak pengetahuan — terutama dalam hal pengembangan game!