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 ↗Gratis mini games voor tussendoor, gemaakt door Gloop. Gebouwd met Next.js (App Router). Alle pagina's worden vooraf als statische HTML gebouwd, en elke game wordt pas geladen als iemand hem opent.
npm install
npm run dev # http://localhost:3000
Productiebuild testen:
npm run build
npm start
git init, git add ., git commit, git push).lib/site.js het veld url in (bijv. https://gloop.nl) en push. Dit wordt gebruikt
voor deellinks, de sitemap en Google. Laat je het leeg, dan gebruikt de site op Vercel
automatisch het productiedomein van het project.Spelers kunnen een account maken met alleen een spelersnaam en een pincode van 4 of 6 cijfers (geen e-mail). Records gaan dan automatisch mee naar elk apparaat. Accounts staan in Supabase; alleen de server praat met de database.
supabase/schema.sql en klik Run.select cron.schedule('gloop-cleanup', '17 3 * * *', 'select public.gloop_cleanup()');
Zo worden accounts die 400 dagen niet zijn gebruikt automatisch verwijderd (dat belooft de privacyverklaring).SUPABASE_URL – Project Settings → API → Project URLSUPABASE_SERVICE_ROLE_KEY – Project Settings → API → service_role key (geheim, nooit NEXT_PUBLIC_ ervoor zetten)Zonder deze instellingen werkt de site gewoon; op de inlogpagina staat dan dat inloggen nog niet beschikbaar is.
Lokaal (npm run dev) wordt zonder instellingen een tijdelijke database in het geheugen gebruikt.
| Bestand | Wat |
|---|---|
lib/accountRules.js | Regels voor namen en pincodes (o.a. blokkade van makkelijke codes) |
lib/account.js | Inloggen/uitloggen in de browser en records automatisch bewaren |
lib/merge.js | Records van apparaat en account samenvoegen (beste score wint) |
lib/server/* | Database, pincode-hashing (scrypt), sessies, beperking van inlogpogingen |
app/api/account/* | De account-API |
lib/server/admin.js, app/api/beheer/*, app/beheer | Beheer (zie hieronder) |
Op /beheer kan een beheerder spelers zoeken, verbergen op de ranglijst, hernoemen, hun scores wissen of het account verwijderen,
en per spel/niveau losse scores van de ranglijst halen (bijv. bij valsspelen). Een weggehaalde score komt niet terug via een ander apparaat
(staat in de kolom players.cleared). Elke beheeractie staat in de Vercel-logs ([gloop beheer]).
Er zijn twee sloten, omdat een pincode van een kinderaccount makkelijk te raden is:
supabase/schema.sql opnieuw (voegt is_admin en cleared toe).is_admin op true.ADMIN_PASSWORD toe (minstens 12 tekens, niet je pincode), en deploy opnieuw.Lokaal zonder Supabase: GLOOP_DEV_ADMIN=JouwNaam ADMIN_PASSWORD=... npm run dev.
Gloop is te installeren als app op telefoon, tablet en computer, zonder app store.
| Bestand | Wat |
|---|---|
app/manifest.ts | Naam, kleuren, icoontjes en snelkoppelingen van de app |
public/icons/ | App-icoontjes (icon-* gewoon, maskable-* met extra rand voor Android) |
app/apple-icon.png | Icoontje voor iPhone/iPad |
app/sw.js/route.ts | Service worker: bewaart pagina's en games, zodat ze ook offline werken |
components/InstallApp.tsx | Knop/banner "Installeren" (met uitleg voor iPhone/iPad en Mac) |
Leuke vernieuwingen voor spelers staan in lib/updates.js en op de pagina /nieuw.
Zet een nieuw nieuwtje bovenaan de lijst. Met popup: true krijgen spelers één keer een pop-up
"Nieuw in Gloop!" (nooit tijdens het spelen; nieuwe bezoekers krijgen geen oude nieuwtjes).
Technische of kleine verbeteringen horen er niet in.
| Map / bestand | Wat staat erin |
|---|---|
lib/site.js | Sitegegevens: eigenaar, e-mail, plaats, KvK, hosting, live-URL |
lib/games.js | Lijst met alle games (titel, categorie, kleuren, speelbaar of "Binnenkort") |
lib/engine/*.js | Eén bestand per game (canvas/DOM-code) |
lib/engine/index.js | Koppeling game-id → game-bestand (code-splitting) |
lib/engine/common.js | Gedeeld resultaatscherm, delen en dagelijkse uitdaging |
lib/store.js | Lokale opslag (records, gespeelde potjes, naam), dagelijkse uitdaging, recordteksten |
lib/content.js | Teksten van info- en juridische pagina's (privacy, cookies, voorwaarden, FAQ…) |
lib/blob.js | Gloopie-tekening (SVG) en iconen |
app/ | Pagina's (home, games, ranglijst, profiel, info-pagina's, sitemap, robots) |
components/ | React-onderdelen (header, footer, gamekaarten, uitdaging…) |
app/globals.css | Alle vormgeving (Gloop-huisstijl) |
Alles staat in lib/stickers.js:
THEMES (id, name, emoji, color).
Seizoensthema? Geef from/to ('MM-DD') en season (tekst). Het komt dan elk jaar terug; buiten die periode zijn de stickers niet te verdienen.reward = id van een spulletje. Zet dat in ACCESSORIES met theme:'<id>' en teken het in lib/blob.js (ACC),
en voeg het id toe aan ACC_IDS in lib/accountRules.js.HALLOWEEN, met test(e). e is het potje dat net klaar is: {game, level, r, challenge}
(r is het resultaat van de game, bijv. r.score, r.planets). secret:true verbergt de hint tot je hem hebt.
Aantal potjes in een seizoen: seasonPlays('<thema-id>').STICKERS met theme:'<id>'. Een id nooit meer veranderen (dan raken spelers hun sticker kwijt).lib/shop.js: alles wat te koop is (SHOP: gezicht, spulletje of achtergrond met een prijs; alleen exclusieve dingen, kleuren zijn gratis) en hoeveel munten een potje oplevert (coinsFor).coins = totaal ooit verdiend, owned = gekochte ids. Saldo = coins min de prijzen; de server bewaart nooit meer aankopen dan je kunt betalen,
en een Gloop mag alleen dingen dragen die echt gekocht zijn (allowedAvatar in lib/server/auth.js).lib/blob.js (FACES/MOUTH/ACC/BG). Een id nooit meer veranderen.lib/farm.js: gewassen (CROPS), dieren (ANIMALS), producten, recepten voor de werkplaats, versiering en landprijzen.
Iets toevoegen = een regel erbij (id nooit veranderen). lvl bepaalt vanaf welk level het te koop is.farm (ook bij je account). cleanFarm schoont op; bij twee apparaten wint de boerderij met de meeste ervaringspunten.lib/engine/<id>.js met:
import {data,save} from '../store';
import {finishCommon} from './common';
export default function start(stage, g, restart){
// bouw je game in `stage` (een div)
// aan het eind: stage.innerHTML = finishCommon(g, {score}, isRecord, [regels], 'grin');
// document.getElementById('again').addEventListener('click', restart);
return () => { /* opruimen: animaties stoppen, listeners weghalen */ };
}
lib/engine/index.js.lib/games.js bij de game playable:true en een desc.fmtRec() (lib/store.js) en een deeltekst in shareText() (lib/engine/common.js).Zet bij een nieuwe game in lib/games.js ook added:'JJJJ-MM-DD' (de datum van vandaag). Dan krijgt hij 30 dagen lang een "Nieuw!"-sticker, maar alleen voor spelers die hem nog niet hebben gespeeld.
Links uit de vorige versie (zoals /#/game/memo) worden automatisch doorgestuurd naar /games/memo.