11 KiB
Catatan mesin (untuk yang mengerjakan fitur)
Game fighting 2D canvas, tanpa dependensi dan tanpa langkah build. Semua teks untuk pemain dalam bahasa Indonesia. Dibangun dari AETHER CLASH (Bang Tutorial).
Peta berkas
index.htmlmemuat semua script berurutan: manifest tiap karakter →announcer.js→match.js→feel.js→game.js→touch.js→menu.js→meta.js. Gaya:style.css(arena/HUD),feel.css(peringkat kombo),menu.css(menu),meta.css(toko, karakter, koleksi, toast, tombol sentuh tambahan).game.js(~2400 baris, satu IIFE): seluruh mesin. Pemain =hero, lawan =dummy(CPU atau P2). Fungsi penting:step(dt)loop logika;draw()menggambar (drawBackground,drawHero,drawDummy,drawEffects,drawCfBack/Front, dst);updateHud()/updateMatchHud()mengisi HUD DOM.- Serangan:
startAttack,cast/castMove,meleeHit,fireSkill,hitDummy(pemain memukul lawan),window.__game.receiveHit(lawan memukul pemain),startCommand/specialHit/startThrow/useShopMove/heroGuard(gerakan perintah, lempar, blok/parry, jurus toko). - Karakter data-driven:
window.FIGHTERS[id](dariassets/<id>/manifest.js) →cfKit(d)(gerakan),cfStrike(actor, def, move)(efek pukul: jenis projectile/wave/homing/dash/area/pillar/lob; ultimate volley/stampede/rain/pillars viaupdateCfUltimate). Bro Wo ditulis tangan (browo.js+updateBrowo,browoStrike). - Proyektil: array
projectiles, diperbarui diupdateProjectiles(dt); efek visual: arrayeffects(tipeslash,impact,cf-fx,cf-pillar, ...) digambar didrawEffects(); partikelspawnParticles; angka damagedamageNumbers. - Efek jurus (blok "Efek jurus (FX)" di game.js, dipakai pemain dan CPU lewat
cfStrike): proyektil CF punya umur (p.age) dan gaya gambarp.fx(rings, shout, chain, roll, spray, flame, bull, drive, wave, bolt, ant);fxPartmembuat partikel kosmetik (pengacak terpisahfxr(), bukanrandom()); jurus area punya aba-aba cincin 0,25 s (fxTeleP), gelombang kejut dan retakan; dash meninggalkan bayangan sprite (cfx.ghosts). Flag data di manifest per skill (jugamode.skills):fx,lift,trail,split,dot,bind,convoy,aftershock,pull,rebound,swarm+ramp,fire; artinya ada di komentar "Mekanik jurus" di game.js. - Rasa kena (
feel.js,window.Feel): tabel penyetelanFeel.tableper jenis serangan (ringan/sedang/berat/ultimate/guard/parry/counter: hit-stop, getaran, sentakan layar, kilat putih, ukuran angka, riak),Feel.classify(damage, {counter, shake}), K.O. slow-motion (Feel.ko, skala hanya untuk dt simulasi visual; jam ronde tetap waktu nyata), angka damage pop (maks 8) dan peringkat kombo#combo-rank. Titik pakai di game.js:feelImpact(satu pintu efek),feelHeroHit(CPU memukul pemain),hitDummy(pemain memukul lawan),startKoFx. - CPU:
updateFenrAI,cpuProfile(tingkat easy/medium/hard/excellent darimatch.js). - Aturan ronde:
match.js(MatchRules), dipakaiadvanceMatchdi game.js.
meta.js:window.Meta— koin, toko, skin (filter warna), jurus toko (tombol K), varian skill, menu Karakter/Koleksi, pencapaian, easter egg, Arcade/Survival (startRun), kolom kode cheat di Pengaturan. Simpanan:localStorage['konoha.save.v1'].menu.js: menu utama (home, pilih karakter, arena, hasil, about) di#front-menu;window.FrontEnd.touch.js: kontrol sentuh; tombol memanggil__game.input(key, down).brand.js(window.Brand) +content/loading.js(window.LOADING_QUOTES) +content/changelog.js(window.CHANGELOG): dimuat diindex.htmltepat setelah kartu#boot, sebelumprecache.js. Kutipan acak (tidak pernah sama dengan yang terakhir, kuncikonoha.loadquote;?quote=Nmemaksa) tampil di#boot .boot-quotedan#load-state .load-quote. "Yang baru":Brand.decorate(root, screen)dipanggilmenu.jsdi akhirrender(); layaraboutmendapat panel.whatsnew-paneldan tautan kredit, layarhomememicu toast.brand-toastsatu kali bila versi teratas CHANGELOG berbeda darilocalStorage['konoha.changelog.seen'](pemain tanpa simpanankonoha.save.v1tidak diberi toast). Menambah pembaruan: sisipkan objek baru di AWALcontent/changelog.jsdengan version lebih besar. Berkascontent/*.jsikuttools/build_precache.py.- Latar menu utama dan About:
menu.jscollageHtml()menyusun tujuh potretassets/menu/<id>-select.webp(lima di layar sentuh) menjadi kolase CSS (.hc-*di bagian "Merek" paling bawahmenu.css). Gerak berhenti lewat kelas.bg-stillpada#front-menu(FrontEnd.syncBackground(): Pengaturan terbuka, tab tersembunyi, saklar "Animasi latar menu",prefers-reduced-motion). Video dan gambar bergaya game asal (home-factions.webp,home-factions-loop.mp4,home-art.webp) tidak dipakai lagi tetapi berkasnya masih ada (dan ikut daftar precache). vs.js(window.VS,window.ResultView) +vs.css+content/quotes.js(window.QUOTES: intro/win/lose per karakter): layar VS dan layar hasil.startMatch({..., vs: true | {label, p2}})menampilkan layar VS 2,2 dtk (hanya mode versus; latihan tidak); selama ituvsHolddi game.js menahanadvanceMatchdan cue 'Round 1' keluar tepat sekali saat VS selesai atau dilewati (klik/Spasi/Enter/Esc setelah 0,38 dtk).startMatchtanpavsberperilaku seperti dulu.menu.jsscreenresultmemakaiResultView.view/mount(layar lama jadi cadangan);Meta.awardmenyimpan rincian diMeta.lastAward;Meta.nextFight/finishRunmemakai VS dan layar hasil yang sama. Pemilih kutipanVS.quote(id, 'intro'|'win'|'lose')memakai pengacak kosmetik terpisah. API uji:__game.vsActive(),__game.vsSkip(). Menu depan yang tersembunyi dijamin hilang oleh#front-menu[hidden]{display:none!important}(menu.css); aturandisplayperdata-screentidak boleh menimpanya. Layar hasil memfokuskan wadah.rs(tabindex=-1), bukan tombol, agar Spasi/Enter dari pertarungan tidak langsung memicu MAIN LAGI (Tab tetap menjangkau tombol).Meta.toastmenahan toast selamaVS.activedan memunculkannya sesudah VS selesai.- Dialog pasangan dan easter egg berpasangan (Tahap 3.1 dan 3.4):
content/dialogs.js(dimuat sebelumvs.js) mengisiwindow.DIALOGS['<idA>|<idB>'] = {a, b}untuk 21 pasangan (kunci urut alfabet; a = ucapan idA) danwindow.DIALOGS.rahasia(empat pasangan tersembunyi, bentuk sama, bukan bagian dari 21 kunci).VS.dialog(idPemain, idLawan)->{key, secret, l, r, reply}memetakan ucapan ke sisi kiri (pemain) dan kanan (lawan), ataunullbila pasangan tidak punya dialog (karakter sama) sehingga kutipan umumQUOTESjadi cadangan. Pasangan ber-dialog menampilkan dua balon.vs-quote.vs-bubble(pembuka = ucapanamuncul dulu, pembalas = ucapanbmenyusul lewat kelas.re, apa pun sisi pemainnya) dan layar VS berlangsungVS.durationDialog(3,3 dtk;VS.duration2,2 dtk dipakai tanpa dialog); gaya di bagian "Dialog pasangan"vs.css. Dialog rahasia menggantikan dialog biasa setiap pasangan itu bertemu (balon keemasan.secret, label.vs-secretDIALOG RAHASIA) dan memanggilMeta.pairEgg(kunci): +75 koin dan satu toast hanya sekali per pasangan (Meta.save.eggs['dialog:<kunci>']), pencapaianreuni(tampil ??? sampai terbuka, deskripsi umum tanpa menyebut pasangan) setelah semua kunciDIALOGS.rahasiaditemukan. Toast ikut tertahan selama VS (aturanMeta.toast). Berlaku di versus, 2 pemain, Arcade, Survival; latihan tidak punya layar VS. Pedoman isi sama denganquotes.js; Belum ada skenario otomatis khusus dialog (diuji manual; cek cepat:__game.startMatch({player:'soloman',enemy:'sonofsolo',stage:'harbor',level:'easy',mode:'versus',vs:true}), laluMeta.save.eggsdanVS.dialog(idPemain, idLawan)). Pengujian yang menunggu layar VS selesai harus menunggu!__game.vsActive()(bukan tidur 2,2 dtk) karena waktunya kini bergantung pada ada-tidaknya dialog. - HUD (game.js): meter ultimate
#ult-player/#ult-enemy(updateUltMeters; mengisi/SIAP/waktu mode darimodeOf,bwx.rage, bentuk FENR; DOM hanya ditulis saat tampilan berubah). Menu jeda#pause-paneldua panel;buildMoveList()membangun ulang Daftar gerakan tiapsetPaused(true), pilihan lipat diingat dilocalStorage['konoha.moveList']. assets/<id>/atlas sprite (15 state),manifest.js(data + metrik),ui/;work/(di repo induk, luar folder ini) berisi pipeline pembuat karakter.precache.js/files.json: dibuat otomatis olehtools/build_precache.py— jangan diedit atau di-commit oleh cabang fitur; perintahkan integrator membangun ulang.
API uji: window.__game
startMatch({player,enemy,stage,level,mode}) (mode versus|training), advance(detik) (memajukan simulasi tanpa menunggu waktu nyata), press(key)/release(key) (a d w s spasi i o p k l j; P2: arrowleft arrowright arrowup n m , .), setAI(bool), setP2(bool), snapshot(), hero, dummy, projectiles, effects, draw(), receiveHit(dmg), command(id). Layar tidak diperbarui saat advance; panggil draw() sebelum screenshot.
__game.hitDummy, __game.feel dan __game.feelState() membuka tabel rasa kena, status K.O./angka untuk tests/t1-feel.mjs. __game.fx.snapshot() melaporkan keadaan efek (bayangan, genangan api, DoT, aba-aba, proyektil beserta gaya/umur) untuk skenario uji. Untuk uji deterministik set __game.manual = true dulu; kalau tidak, loop waktu nyata ikut memajukan simulasi saat screenshot.
Alat uji headless
node tests/harness.mjs smoke — 7 karakter × easy/hard melawan CPU, gagal bila ada galat halaman. node tests/harness.mjs tests/foo.mjs — menjalankan skenario: export default async ({ page, game, errors, characters }) => hasil (game(fn, arg) = page.evaluate). Screenshot: await page.screenshot({path}) lalu Read gambar. tests/t1-fx.mjs melepas semua jurus enam karakter berbasis data dari kedua sisi (env FX_SHOTS = folder screenshot, FX_ONLY = regex nama jurus). Node dan Playwright sudah terpasang; tidak perlu npm install. tests/t2-hud.mjs (env HUD_ONLY=meter|enemy|cpu|pause|layout) menguji meter ultimate dan menu jeda; tests/t2-vsresult.mjs (env VSR_SHOTS, VSR_ONLY=quotes|vs|skip|abort|result|run|ui|focus|phone) menguji layar VS, layar hasil, dan kutipan. Skenario tests/t2-vsresult.mjs menunggu !__game.vsActive() (bukan tidur 2,2 dtk) karena layar VS ber-dialog 3,3 dtk. tests/t2-brand.mjs (env BRAND_SHOTS, BRAND_ONLY=text|quote|log|menu|flow|docs) menguji sisa nama game asal di seluruh layar, kutipan loading, Yang baru dan toast, serta latar kolase.
Aturan kerja
- Jangan memakai
Math.random/Date.nowuntuk logika yang memengaruhi hasil pertandingan bila ada pengacakrandom()bawaan (benih tetap). - Tampilan harus tetap muat di jendela setinggi 520 px; jangan memotong menu.
- Tidak ada pustaka eksternal baru. Tidak ada gambar baru (tidak boleh memanggil generator gambar).
- Commit atas nama
rizkyaz0 <rizkyadizaelani@gmail.com>, tanpa baris Co-Authored-By atau atribusi apa pun. Jangan pernahgit pushdan jangan mengubah remote. - Teks HUD di
index.html(nama, kelas, jurus) hanya placeholder netral;game.jsmenimpanya lewatfighterInfo. Cabang lama difighterInfodan manifestassets/mecha,assets/fenradalah sisa game asal yang tidak terjangkau dari roster; jangan menampilkannya ke pemain. - Jaga gaya kode yang ada (ringkas, satu baris per pernyataan kecil, komentar hanya bila perlu).