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를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 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.