拆解迷因大亂鬥的打擊感
從原始碼看迷因大亂鬥的打擊感:命中停頓、畫面震動、浮空衰減、連段緩衝、敵人輪流出手與頭目硬直值。
《迷因大亂鬥》是一款像素風清版動作遊戲,可以單人玩,也能兩人同機合作。它沒有設計文件,所以這篇我們直接讀原始碼,看看「打下去很爽」是由哪些數字堆出來的。遊戲每秒固定更新 60 次,下文的「幀」都是 1/60 秒。
一次命中裡發生的事
每一下打中都會呼叫同一個 hitFx 函式。它在命中點噴火花(輕擊 5 顆、其他 8 顆),畫一個 6 幀的十字閃光,由白轉黃,播放音效,並設定命中停頓(hit-stop);被打的一方則整個剪影白閃 10 幀。
停頓長度跟著招式份量走:預設輕擊 2 幀、較重的攻擊 4 幀,連段收尾技自己指定 8 或 9 幀,猛男的大招落地則是 10 幀。停頓是全域的,整個世界一起凍住:
if (this.cutin) {
if (++this.cutin.t >= this.cutin.dur) this.cutin = null;
return;
}
if (this.hitstop > 0) {
this.hitstop--;
return;
}
if (this.slow > 0 && --this.slow % 3) return;
畫面震動的衰減寫在這段上面、return 之前,所以凍住的那幾幀畫面仍在抖,不會變成一張靜止截圖。只有非輕擊才會震:擊倒、挑起類 4 像素,其他重擊 2 像素,刺拳完全不震。聲音也分兩層:揮拳時先播風切聲,打中才疊上打擊聲,全部用 WebAudio 即時合成。
細節裡藏著幾個取捨。停頓取最大值而不累加,打中三個人跟打中一個人停得一樣久,我們推測是為了不讓清群的節奏被拖慢。投射物命中完全不停頓,畢竟珍奶機槍每 6 幀就一發。另外,攻擊鍵只在按下的那一幀被讀取,而停頓期間玩家的更新也停了,所以剛好按在停頓裡的那一下不會被讀到。
這款遊戲不跳傷害數字,改用字卡:收尾技冒出 YEET、YES、POP,其他重擊有 22% 機率跳出 BAM、BRUH 這類字,連擊數到 6、12、20、30、50 下各有一個稱號。
連段:按鍵要在對的時間進來
柴犬的連段有 4 段(刺拳、刺拳、勾拳、旋風踢),猛男 3 段(刺拳、直拳、上勾拳),啵啵貓 5 段。以刺拳為例,全長 14 幀,第 3 到 5 幀有判定(active frames),第 6 幀起可以取消。
判定開始之後按攻擊,按鍵會先存進緩衝,到了可取消的那一幀就直接接下一段;判定開始前的按鍵不算數。錯過的話,招式結束後還有 24 幀可以接。收尾技沒有取消點,打完一定從頭來。
結果是:用緩衝接刺拳,大約每 6 幀打中一次,而敵人吃輕擊的硬直是 16 幀,節奏對了就不會留空檔給對方反擊。勾拳、直拳和旋風踢還會帶著角色每幀前進 1 到 1.4 像素,看起來是用來抵銷擊退拉開的距離。揮空一樣會往下一段走。
衝刺是在 15 幀內連按兩次同方向。空手衝刺時按攻擊會出衝刺技,判定很長(柴犬的頭槌是第 2 到 14 幀),期間角色每幀前進 3 到 3.8 像素,等於一個會移動的打擊框。跳躍攻擊每跳只能出一次,判定一路持續到落地,打中一般敵人一律擊倒。
擊退與浮空:讓敵人變成武器
輕擊和重擊只造成硬直,擊倒和挑起才會把敵人打飛。猛男上勾拳的上升初速是 6.2,敵人大約要 41 幀才落地。浮空中的敵人仍然打得到,但每多打一下,彈起來的力道就少一點:
if (this.state === 'fall') {
this.vz = Math.max(this.vz, 2.4 - this.juggle * 0.3);
this.vx = dir * 1.2;
this.juggle++;
break;
}
挑起本身就算一次,所以第一下追擊補 2.1,接著 1.8、1.5,到第 8 下就補不上去了。浮空計數超過 4 之後,任何再把它打飛的攻擊,向上的力道只剩 45%。沒有硬上限,浮空會自然收尾。落地夠快會反彈一次,多給一次追打機會;但真正倒地後就打不到,爬起來還有 18 幀無敵時間。
柴犬的旋風踢屬於獨立的 yeet 種類:被踢飛的敵人在最多 40 幀內,只要橫向速度還有每幀 2 像素,撞到別的敵人就造成基礎 10 點傷害並把對方撞倒,每次碰撞都算進玩家的連擊數和能量。
輪流出手與無敵時間
為了不讓一群人同時圍上來,敵人要先拿到「出手配額」才能上前出拳:
takeToken() {
if (this.token) return true;
if (world.tokens.size >= Game.diff.atk + (world.players.length > 1 ? 1 : 0)) return false;
world.tokens.add(this);
this.token = true;
return true;
}
同時能出手的敵人,簡單 2 個、普通 3 個、地獄 4 個,雙人再加 1。沒拿到的會在 52 到 82 像素外徘徊,用六成速度移動。配額在出完招、被打中或死亡時歸還,所以打斷一個正在蓄力的敵人,效果上等於把回合讓給下一個。配額只管近身攻擊,鍵盤俠丟字、Dat Boi 衝撞都不用排隊,壓力還在,只是不會全擠在你身邊。
出手前敵人會蓄力,頭上閃紅色驚嘆號:NPC 22 幀,酸民只有 14 幀,難度越高越短(NPC 在地獄只剩 19 幀)。
玩家這邊,連續吃到第 4 下(每下間隔不到 70 幀)會直接被打倒,不會一直被硬直鎖住,代價是武器脫手。爬起來有 50 幀無敵,敵人只有 18 幀。玩家的輕擊硬直 14 幀、重擊 20 幀,都比敵人少 2 幀。復活有 160 幀無敵,放大招的整段期間也打不到。
頭目:不會被打斷,但硬直會累積
頭目不會因為單一下攻擊而退縮,傷害會累積成硬直值,擊倒、挑起類攻擊算 1.5 倍;累積到最大血量的 15%,頭目才會失去平衡,正在出的招也會中斷。硬直值每幀消退 0.05,所以輸出要集中。單人普通難度的酸民大王有 620 血,門檻就是 93。
血量降到固定比例會觸發特定招式,例如召喚小兵或進入第二階段(酸民大王會走得更快、蓄力更短、衝刺連來兩次)。預警也比小兵明顯:驚嘆號字級從 9 放大到 16,跳起砸地時地上有閃爍的圈,股票線、掉金幣、火柱落下前至少有 40 幀預告。擊敗頭目後的 120 幀裡,世界每 3 幀才前進 1 幀,等於 2 秒的慢動作,場上其他敵人也一併清空。
大招與武器:兩種會用完的資源
迷因能量上限 200,大招花 100,最多存兩發。打中一般敵人加 3.6、頭目 2.4,解決一個敵人加 5、頭目 60,被打則是每點傷害加 0.6。能量不夠但血量高於 15% 時,改扣 10% 最大血量施放,算下來不可能把自己扣死。施放時世界凍結 34 幀播放角色特寫,扣血版只有 16 幀。
近戰武器是「揮一次有打中才扣 1 耐久」,打中一個還是三個都一樣,我們把它解讀成鼓勵往人多的地方揮。武器的三段連擊最後一段傷害 1.4 倍、停頓 8 幀。被打倒時武器會掉在地上、保留剩餘耐久 10 秒;把武器丟出去則固定是基礎 14 點傷害,跟剩幾次耐久無關。
兩個人和一支手機
2P 隨時按逗號鍵就能加入,從天上掉下來,有 120 幀無敵。玩家之間沒有友軍傷害,頭目血量乘 1.45,出手配額加 1,鏡頭也不會往前捲到把落後的人擠出畫面。
手機上的搖桿其實是數位的:推過半徑的 30% 就算一個方向,推多推少速度都一樣。從程式看,衝刺用的是同一套連按兩次偵測,在搖桿上就是快速推兩下。觸控只控制 1P,切到別的 App 時遊戲會自動暫停。這些都可以到遊戲頁親手試試。