Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗俯瞰式(top-down)子彈時間射擊遊戲原型,用 Three.js 製作。靈感來自 My Friend Pedro: 慢鏡、雙槍分離瞄準、旋轉閃避、反彈子彈、踢擊,以及鼓勵「打得好看」的 Style 計分。
敵人一波一波湧上來,每一波比上一波更多、更兇。開始畫面選模式和起點場景:
街機和無盡的場景依次是霓虹天台 → 脈衝夜店 → 七號碼頭 → 議事亭前地 → 福隆新街 → 東望洋跑道 → 大三巴,然後循環。每個模式各自記錄最高分。 除了預設的雙槍,還可以撿到 6 種武器。
遊戲是純靜態網頁,沒有建置步驟;Three.js 已放在 vendor/ 內,不需要網路。
因為使用 ES modules,必須經由 HTTP 開啟(直接雙擊 index.html 不行):
npm install # 第一次:安裝測試和工具用的套件
npm run serve # http://127.0.0.1:8123/
需要滑鼠 + 鍵盤(暫不支援手機觸控)。
推送到 main 時,.github/workflows/pages.yml 會把整個 repo 部署到 GitHub Pages
(repo 的 Pages 設定需選擇 GitHub Actions 作為來源)。每次推送 .github/workflows/ci.yml 都會跑 lint 和測試。
| 指令 | 作用 |
|---|---|
npm run lint | ESLint 檢查 src/、scripts/、test/ |
npm test | 議事亭單元測試、冒煙測試、地圖驗證、資產管線、每張地圖一段機器人對戰(約 2 分鐘) |
npm run test:game | 較慢:每種武器開火、E 交換、長時間撿武器跨場景(約 10 分鐘) |
npm run build | 打包成單一 HTML 檔 dist/bullet-ballet.html,方便分享 |
npm run assets | 把 assets/source/ 的模型母版處理成網頁版 |
npm run assets:docs | 重新生成 assets/PROMPTS.md、asset-list.*、maps/*.json |
給 Claude 的工作說明在 CLAUDE.md;規劃書、任務清單和決策紀錄在 docs/。
| 按鍵 | 動作 |
|---|---|
| WASD / 方向鍵 | 移動 |
| 滑鼠 | 瞄準 |
| 左鍵(可長按) | 射擊(雙槍會左右手交替) |
| Shift 或 Q | 子彈時間(切換),會消耗 Focus 量表 |
| Space | 旋轉閃避:旋轉期間子彈穿身而過;旋轉中按住開槍會向四周掃射;彈匣空時旋轉,轉完就裝好 |
| C | 滑鏟(跑動中):低身滑行半秒多,敵人子彈從頭頂飛過,可邊滑邊開槍 |
| 右鍵(按住) | 分離瞄準(雙持武器):左手槍鎖定游標附近的敵人,右手槍繼續跟游標;拿狙擊槍時是瞄準鏡,視野往前推 |
| F | 踢:踢飛敵人、油桶、平底鍋 |
| G | 拿起 1.6 米內的平底鑊或油桶舉過頭,再按 G 或左鍵擲向游標;特殊武器打空後按 G 擲出空槍擊暈敵人 |
| E | 站在另一把武器上時交換 |
| 1 / 2 / 滾輪 | 切換雙槍與特殊武器 |
| R | 換彈(雙槍) |
| V | 切換鏡頭:俯視 / 45° 俯視 / 45° 側俯視 |
| M | 音樂開關 |
| Esc / P | 暫停(暫停選單:繼續、R 重新開始、T 返回主畫面換地圖) |
| N | 記下這一刻:暫停、寫一句回饋,自動附上當時狀態和之前十件事;暫停選單可匯出 |
| ` | 數據面板:fps、時間倍率、焦點、手感數字即時調整 |
手機(橫放):左手拇指按下的地方是移動搖桿;右手拇指按下的地方是瞄準搖桿,推着就自動開火(會吸附附近的敵人);按住右上的「子彈時間」就是子彈時間,放手就停;頂部「❚❚」暫停。手機自動用低畫質(數據面板可以改)。網址加 ?touch=1 可以在電腦上試觸控層。
Claude 看不到手感,只看得到數字。試玩時覺得哪裡不對,就按 N:遊戲暫停,寫一句(例如「旋轉閃避的無敵時間太短,第 3 波被散彈打中兩次」),Enter 繼續。每條回饋會自動附上地圖、波次、HP、慢鏡狀態和之前十件事。玩完在暫停選單按「匯出回饋」,把下載的 Markdown 貼進對話就可以。
按 ` 打開數據面板:fps、世界與玩家的時間倍率、焦點、停格、邏輯步數,還可以即時調手感數字(慢鏡速度、旋轉閃避時長、焦點消耗…)。調過的值會記住,畫面右下角會標示「手感數字已調整」,面板裡「重設為預設」還原;匯出的回饋會列出調過的數字。
網址加 ?seed=123(任何數字或文字都可以)會固定隨機數:同一個種子、同樣的操作,就是同一局:波次組成、出生點、武器台、敵人的決定都一樣,重新開始也一樣。操作不同,之後的局面也會跟著不同。不加種子就每局不同。
遊戲的畫風是「霓虹人偶」:平塗卡通色階、黑描邊、動作殘影、人物姿勢每秒 12 格的頓格、漫畫比例。這全是渲染層的事,不影響玩法。數據面板()的「風格」區塊可以逐項開關(卡通色階要重新整理才生效),網址加 ?style=off` 可以整套關掉作對比。
每局會記錄影格時間,匯出的回饋開頭有平均 fps、低於 50 fps 的秒數、最差一格、顯示卡名稱和畫質;連續一秒低於 45 fps 會在事件裡記一條「掉幀」。數據面板可以勾「常駐 FPS 角標」(或網址加 ?fps=1)。機器弱就選「畫質:低」或網址加 ?quality=low:關掉泛光和陰影、像素比降到 1,重新整理生效。每張地圖的渲染預算在 src/maps.js,超出時 npm test 會失敗。
| 場景 | 特色 |
|---|---|
| 霓虹天台 NEON ROOFTOP | 下雨的天台、直升機坪、玻璃溫室、樓梯間和從天台邊爬上來的敵人 |
| 脈衝夜店 CLUB PULSE | 跟著音樂節拍變換圖案的舞池(子彈時間時會跟著音樂一起變慢)、鏡面球、吧枱後整排會碎的酒瓶、二氧化碳氣罐 |
| 七號碼頭 HARBOR 7 | 貨櫃迷宮、叉車、爆炸範圍更大的氣罐,敵人會從倉庫捲閘、圍欄閘口,甚至從海裡爬上來 |
| 議事亭前地 LARGO DO SENADO | 按實景比例重建的澳門議事亭前地(白天)。由新馬路經噴水池廣場、約 10 米闊的窄段一直到板樟堂前地,長 148 米;敵人從新馬路兩端和各條橫巷湧入。掩體是熟食檔、石花槽、街燈、巴士站和停泊的的士,熟食檔旁的石油氣罐會爆炸 |
| 福隆新街 RUA DA FELICIDADE | 晚上的福隆新街:6 米闊、60 米長的直街,兩旁是紅窗木門、灰磚牆的兩層舊舖(店名全是虛構的)。六間舖可以入:木門一腳踢開,巷口那間是鐵閘,近橫巷的兩間有後門通出巷。街上有吊招牌、街燈、石油氣罐、平底鑊和擺出來的麻雀枱;敵人從街的兩頭和橫巷的兩頭殺到 |
| 東望洋跑道 GUIA CIRCUIT | 晚上的格蘭披治跑道,一個髮夾彎(約 56 × 40 米,按 ROADMAP 的尺寸手建)。賽道由北面入、繞過西邊的彎、由南面出;彎內是草地場內和計時塔,四周藍白輪胎牆,外面是護欄、北面的看台和彎外的沙石緩衝區。輪胎牆擋得住子彈但只夠蹲低:看台前排的人望得過它,場內的人要踏出賽道才還擊得到。每隔一陣有一隊賽車高速掠過(燈轉紅、路上亮起紅線就是預告):撞中誰都倒,旋轉、滑鏟、飛撲都躲不過,只能離開賽道——把敵人引上賽道等車來。車隊、贊助和圈速全是虛構的 |
| 大三巴 RUINS OF ST. PAUL'S | 晚上的大三巴,風格化(世遺核心,不求還原石材):前地之上六十八級石階分三段、兩個平台,頂上是牌坊立面。高低差決定視線:站在石階上的人越過比腳下低的掩體看得到你、射得到你,你站上去也一樣,所以平台是要搶的高位。牌坊只剩立面:三個門洞走得過、子彈穿得過,後面是舊教堂的地基,可以繞到牆後再由另一個門出來。石階上的油桶一射或一踢就打側滾落去,撞倒路上的人(ROLLING)。前地有花槽,兩邊是餅家和肉乾舖(店名虛構) |
預設是 45° 側俯視。按 V 輪流切換三種鏡頭,選擇會記住:
鏡頭壓低後,擋在鏡頭和主角之間的牆、掩體和樓宇會被挖空。
模型來自同一個 repo 的議事亭前地量體研究(claude/practical-archimedes-ay1ycf 分支的 senado/,1 單位 = 1 米)。
遊戲只取廣場一帶:
更新模型後重新抽取:
node scripts/senado-extract.mjs <senado 資料夾的路徑>
會覆寫 src/senado/model.js(原封不動複製)、src/senado/data.js(裁切後的資料)和
src/senado/assets.js(地磚和窗戶貼圖)。範圍和旋轉角度在 src/senado/transform.js。
人物改成真人比例,與議事亭前地模型的比例人一致:約 1.78 米高、肩寬約 0.46 米,碰撞半徑 0.3 米。
所有尺寸集中在 src/characters.js 的 BODY,改這裡就會套用到主角和全部敵人。
每張地圖有兩個金色武器台,每一波開始時會刷出一把武器。
主角、敵人、武器、道具、環境物和議事亭前地的地標都可以換成高質量 3D 模型。沒有模型的繼續用方塊版,所以可以逐件替換。
assets/SPEC.md:比例尺寸與交付規格,以及轉用 Unity、Unreal、Godot 的須知。assets/PROMPTS.md:71 件物件的參考圖和 3D 模型提示詞。assets/asset-list.json、assets/maps/*.json:引擎中立的物件清單和地圖佈局。assets/source/<id>/,執行 npm run assets 就會生成網頁版並用在遊戲裡。?models=off 可看回方塊版,加 ?use=hero-b 可切換同一物件的不同版本。雙槍彈藥無限(30 發彈匣,要換彈)。其他武器都是撿來的,彈藥用完就自動切回雙槍; 同時只能帶一把特殊武器,走過同款武器會補彈藥。
| 武器 | 來源 | 特性 |
|---|---|---|
| 雙槍 DUAL PISTOLS | 預設 | 可以分離瞄準 |
| 雙衝鋒槍 DUAL SMG | 武器台、THUG 偶爾掉落 | 射速極高、散布大,可以分離瞄準 |
| 散彈槍 SHOTGUN | 武器台、SHOTGUNNER 掉落 | 8 顆彈丸,近距離一槍把人轟飛,有後座力 |
| 突擊步槍 ASSAULT RIFLE | 武器台、RIFLEMAN 掉落 | 準、快、每發傷害較高 |
| 狙擊槍 SNIPER RIFLE | 武器台 | 一槍斃命,子彈穿透最多 5 個目標(COLLATERAL 加分);右鍵瞄準鏡 |
| 榴彈發射器 GRENADE LAUNCHER | 武器台 | 拋物線榴彈,落地或撞到敵人就爆炸;自己被炸到傷害減少 |
| 機槍 MINIGUN | BRUTE 必定掉落 | 240 發彈幕,但拿著時走得比較慢 |
| 類型 | 特性 |
|---|---|
| THUG | 手槍,最常見 |
| SHOTGUNNER | 散彈,喜歡貼近 |
| RIFLEMAN | 三連發,遠距離、預判較準 |
| BLADE | 沒有槍,衝過來砍你 —— 用旋轉閃避或踢回去 |
| BRUTE | 第 4 波起出現,又大又硬,機槍會追著你掃射 |
index.html HUD / 選單 DOM,importmap 指向 vendor/three
style.css 介面樣式
src/
main.js Game:主迴圈(遊戲邏輯固定每秒 120 步,與螢幕更新率無關)、時間縮放(子彈時間、hit-stop、kill-cam)、攝影機、事件
config.js 所有手感參數(速度、子彈時間倍率、射速、鏡頭)
player.js 玩家:移動、武器槽與射擊、旋轉、踢、分離瞄準、受傷/死亡
weapons.js 玩家武器數值、掉落表、榴彈
pickups.js 地上的武器、武器台刷新、拾取與交換
enemies.js 敵人種類、武器與 AI 狀態機(移動 → 瞄準 → 射擊 → 恢復)、掉落武器
bullets.js 子彈:逐段碰撞、反彈、擦身判定、互相抵消
level.js 載入地圖:掩體、玻璃、油桶/氣罐、平底鍋、武器台、出生點、燈光、雨
maps.js 七張地圖的資料(掩體座標、道具、出生點)和各自的佈景與動畫
senado/ 議事亭前地:轉換參數、抽取出來的模型程式、資料和貼圖
ambient.js 環境生物(白鴿群)
cutaway.js 把鏡頭和主角之間的物件挖空的 shader 補丁
nav.js 網格 A* 尋路
rng.js 有種子的隨機數:遊戲邏輯用 game.rng(每局重設,`?seed=` 固定),特效另用一套
input.js 鍵盤滑鼠;每個邏輯步取一份快照(按鍵、瞄準點、鏡頭方向),遊戲邏輯只讀這份
replay.js 每局的輸入記錄(只存變化,十分鐘約 70 KB);加上種子就能重現一局
fx.js 粒子(InstancedMesh)、地面血跡、閃光燈、衝擊波、激光
postfx.js Bloom + 子彈時間調色 shader(去飽和、色差、暗角、漣漪)
audio.js WebAudio 合成音效與背景音樂,會隨時間縮放降調
hud.js HUD、Style 分數欄、橫幅、準星、畫面外敵人箭頭
waves.js 波次編排與出生預告;街機、無盡、每日挑戰和澳門一夜的規則(MODES)
night.js 澳門一夜:按時間排地圖、本機進度
score.js 分數、連擊、最高分(localStorage)
characters.js 方塊風人物模型、可替換的武器模型與動畫
asset-manifest.js 3D 模型清單:人物、武器、道具、環境、地標、材質的尺寸、面數、提示詞
models.js 載入 assets/models/ 的模型,按碰撞盒縮放擺放道具
skin.js 讓有骨架的人物模型跟隨方塊骨架:播動作、轉身、雙手 IK 握槍
models-index.js 由 scripts/assets.mjs 生成:已處理好的模型列表
textures.js 程序生成的貼圖(地板、木箱、貨櫃、圍欄、窗戶、霓虹招牌)
vendor/three/ Three.js r186(MIT)及所需的 addons(postprocessing、GLTFLoader、SkeletonUtils、meshopt)
assets/ 3D 模型:source/ 放高質量母版,models/ 是處理後的網頁版;規格、提示詞、清單、地圖佈局
scripts/assets.mjs 把母版減面、縮貼圖、壓縮成網頁版,並合併分開存放的動作
scripts/asset-docs.mjs 生成 PROMPTS.md、asset-list.json/.csv、maps/*.json
想調手感,先看 src/config.js;玩家武器在 src/weapons.js;敵人數值在 src/enemies.js
的 TYPES / WEAPONS;波次節奏在 src/waves.js。
新增地圖:在 src/maps.js 加一個物件放進 MAPS 陣列即可。座標以地圖中心為原點,
x 向右、z 向鏡頭(南);掩體寫成 [x, z, 寬, 深, 高, 材質]。
Three.js 以 MIT 授權隨附於 vendor/three/(見 vendor/three/LICENSE)。
議事亭前地的建築輪廓、高度和街道來自 © OpenStreetMap contributors,以 ODbL 授權;遊戲中選擇這張地圖時會顯示出處。
其餘音效、音樂、貼圖都在執行時以程式生成,沒有外部素材。