Construire un jeu web pour téléphone à partir du kit
Le modèle web-game est un jeu terminé (Coin Dash) sur Vite + React + TypeScript. Votre travail consiste à remplacer ses règles, sa vue, son texte et ses graphismes par le jeu de l'utilisateur. Priorité au mobile : un téléphone en portrait de 390 x 844, une seule pouce. Le bureau doit également fonctionner.
Règles fixes
- Lancez l'aperçu en direct avant toute autre chose (étape 1 de l'ordre de construction). Ensuite, écrivez le code : planifiez en 10 lignes maximum, puis éditez. Un fichier ou une fonctionnalité par tour, puis
bun run typecheck. - Ne reconstruisez jamais ce que le kit possède déjà (liste ci-dessous). N'ajoutez pas de moteur de jeu, de bibliothèque d'interface utilisateur ou
@react-three/fiber. - Les règles du jeu sont des fonctions pures dans
src/games/<game>/logic.ts: pas de React, DOM, dessin,Date.now()ouMath.random(). Utilisezseeded(seed). La même graine doit donner le même jeu : les tours quotidiens et de défi en dépendent. - Pas de serveur, pas de connexion. La progression reste dans
localStorage(le kit le fait). - Chaque affirmation dans le texte doit correspondre à ce que fait le jeu.
- Vérifié signifie vu fonctionner :
bun run check:playréussi et vous avez regardé ses captures d'écran en taille téléphone. Un HTTP 200 du lien en direct n'est pas un test.check:playest sans tête et n'a besoin ni de bureau ni de fenêtre de navigateur.
Ce que le kit fait déjà (ne pas reconstruire)
- Boucle à pas fixe, entrée clavier et tactile (glisser n'importe où, joystick, croix directionnelle, volant, boutons d'action, multi-touch, deux joueurs, glisser souris sur un ordinateur), caméra, collision, pause lors du masquage de l'onglet.
- Une interface utilisateur de jeu pour la 2D et la 3D dans
src/ui/: menu, bandeau HUD (badge de score, cœurs, minuterie, pause), pause, résultats, déverrouillages, Comment jouer et FAQ, Tournez votre téléphone, toasts, routeur, profil enregistré. - Thèmes dans
src/ui/theme.ts:softCandy(par défaut),glassNeon,cleanMinimal.?theme=glassNeonprévisualise un autre. - Meilleur score et déverrouillages ; défi quotidien (graine de date, numéro du jour de lancement, série) ; liens de défi
?c=<seed>&s=<score>&n=<name>avec paramètres nettoyés et "Vous avez gagné / Vous avez perdu" plus "Envoyer en retour" ; partage avecnavigator.shareou copie dans le presse-papiers ; son Web Audio après le premier tap avec mise en sourdine mémorisée ; vibration qui échoue silencieusement. track(name, data)avecgame_open,game_start,game_over,play_engaged(45 s),share,challenge_open,daily_complete. Il enregistre dans la console et envoie aux analyses omg sur une page publiée.useRundans play.tsx les envoie ; ne les renvoyez pas.- 100dvh, zones de sécurité, pas de défilement ni de zoom, cibles tactiles de 48 px, mouvement réduit.
- SEO construit à partir de
src/app/about.ts: titre, description, Open Graph, image de partage, données VideoGame et FAQPage. Le manifeste d'installation provient du plugin Vite omg avecpublic/icons/.
Choisir 2D ou 3D
2D par défaut (environ 100 Ko gzip de script). 3D uniquement lorsque l'idée a besoin de profondeur ; cela ajoute three.js (environ 137 Ko gzip), chargé pendant que le menu s'affiche et jamais dans une construction 2D. Basculez avec l'UNIQUE ligne dans src/app/view.ts, puis supprimez le fichier de vue inutilisé.
Choisir la commande
Définissez-la une fois dans src/app/about.ts, GAME.controls : kind, touchHint (menu sur un téléphone) et keysHint (menu sur un ordinateur). play.tsx passe GAME.controls.kind à <TouchControls>. Les deux astuces et howToPlay doivent décrire cette même commande. N'écrivez jamais "glisser" pour un jeu avec des boutons, ou "taper sur les flèches" pour un jeu de glissement. check:ui et check:play échouent sur une astuce qui nomme une autre commande.
| Jeu | kind | Le joueur fait | Les règles lisent |
|---|---|---|---|
| Pagaie, attraper, coureur, esquiveur de voie, lance-pierre | drag | glisse n'importe où sur le terrain | axisX/axisY ; avec mode="absolute", dragTarget pour que la pagaie se place sous le doigt |
| Vue du dessus, mouvement libre, double stick | stick | utilise le joystick avec le pouce, en bas à gauche | axisX/axisY |
| Mouvements sur grille : labyrinthe, serpent, sokoban | dpad | tape sur quatre flèches | axisX/axisY ou wasTapped |
| Course, changement de voie avec deux touches | steer | maintient gauche ou droite | axisX |
| Un tap : flappy, saut, timing | buttons | tape sur le bouton d'action | wasTapped(input, "p1", "a") |
Ajoutez des boutons d'action avec buttons={[...]} sur n'importe quel type. axes="x" limite un glissement à gauche et à droite. Le clavier fonctionne toujours : flèches ou WASD, Espace.
Ordre de construction
- Aperçu d'abord, avant d'éditer un fichier : dans le répertoire du projet, exécutez
bun installsinode_modulesest manquant. Lancezbun run deven arrière-plan (port 5174). Appelezomg_expose_portavec le port 5174, sansexpoGo. Dites à l'utilisateur : "L'aperçu est prêt dans la carte ci-dessous. Il se met à jour pendant que je construis." Vite recharge l'aperçu à chaque sauvegarde à partir de maintenant. Lorsque les étapes de première exécution ont déjà fait cela, ou que le port 5174 est déjà utilisé par le serveur de développement de ce projet, passez à l'étape 2. - Planification : boucle centrale en une ligne, type de commande (tableau ci-dessus), victoire, défaite, score, et comment un tour se termine (une horloge, des vies, ou des objets qui tombent). Mettez-le dans
README.md. - Règles : copiez
coin-dash/logic.tsverssrc/games/<game>/logic.ts. ConservezcreateGame(players, seed),stepGame(game, input, dt),finalScore,events(pour le son),UNLOCKS,shareLine. Lisez l'entrée avecaxisX/axisY/wasTapped. - Vue : copiez
view-2d.ts(canvas :drawWorld,drawShadow,loadImage) ouview-3d.ts(three.js :createStage,chaseCamera,billboard,checkerTexture; géométrie partagée, matériaux Lambert, ombres blob, pas de shadow maps). Dessinez l'image de l'emplacement d'art lorsqu'elle est définie, une forme de placeholder lorsqu'elle ne l'est pas. - Câblage : dans
src/app/play.tsx, changez les imports, les nombres HUD,FEEDBACK(son par événement), les boutons et la lignerun.finish({...}). Gardez<TouchControls kind={GAME.controls.kind}>,<HudScore icon={ART.scoreIcon}>,run.stepetrun.finish. - Texte : remplissez
src/app/about.ts(nom, titre avec mots de recherche, description, slogan, commandes, jour de lancement, orientation, comment jouer en 3 à 5 étapes, astuces, 4 à 6 FAQ). - Graphismes (obligatoire) : le kit fournit les graphismes d'exemple Coin Dash, et ils ne doivent pas atteindre le jeu de l'utilisateur. Choisissez le préréglage dans
theme.ts, ou étalez-en un et définissez les couleurs du client. Créez des images avecomg_generate_imagedans un style unique (une feuille, découpée en PNG transparents, le jeu sous 3 Mo) et remplacez chaque élément :ART.hero(l'art du menu sous le logo) etART.scoreIcon(l'icône de score HUD) danssrc/app/art.ts. Supprimezpublic/art/hero.svgetpublic/art/score.svg.ART.items(un par déverrouillage) etART.sprites.public/icons/(pwa-192x192.png,pwa-512x512.png,pwa-512x512-maskable.png,apple-touch-icon.pngà 180) etpublic/og.png(1200 x 630). Ensuite, regardez les captures d'écran du menu, du jeu et des résultats : pas de coureur rouge, pas de pièces, pas de badge de pièces à moins que le jeu ne parle de pièces.
- Vérification :
bun run typecheck,bun test,bun run check:ui, puisbun run check:play.check:playjoue un tour à 390 x 844 avec le tactile : menu, Jouer, votre commande, pause, reprendre, résultats, erreurs console, graphismes d'exemple. Ouvrez chaque PNG dans.omg/ui-check/et.omg/play-check/. Corrigez chaque ÉCHEC et AVERTISSEMENT, puis relancez-les. Ne publiez pas tant quecheck:playn'est pas réussi. - Publier :
omg_deploy. La première publication nécessitepublic/omg-store/1.pngà3.png(menu, jeu, résultats à 390 x 844). Attendez une minute, puis exécutezbun run check:play -- --url <lien en direct>et regardez ses captures d'écran. Signalez uniquement ce qui y a réussi.
Éditez src/ui/, src/game/ et src/render/ uniquement lorsqu'un bogue du kit vous bloque. Ajoutez des aides dans votre dossier de jeu.
Règles pour le téléphone
- Gardez la balise viewport,
styles.css,page.ts. Placez les éléments HUD à l'intérieur de<Hud>. Les commandes importantes restent dans la moitié inférieure. - Pas de
setInterval,setTimeoutouDate.now()pour le temps de jeu : comptezdt. - Pas de
alert,confirm,prompt, polices ou scripts externes. - 3D : quelques centaines de maillages au maximum, réutilisez la géométrie et les matériaux, pas de post-traitement, pas de grandes textures.
- Sur les téléphones, la barre d'installation omg se trouve en dessous du jeu, et le jeu devient une carte au-dessus. Ne la cachez pas et ne la déplacez pas.
Rapport final
- Lien en direct. 2. Le jeu en une phrase. 3. Ce qui a été testé et à quelles tailles, avec le résultat
check:playsur le lien en direct. 4. Captures d'écran du menu, du jeu et des résultats. 5. Problèmes connus ou idées suivantes (au maximum 5). Dites si la 3D a été vérifiée sur un vrai téléphone.
Leçons déjà apprises
- Un bouton à la fin d'une rangée qui défile latéralement est sorti de l'écran et les joueurs sont restés bloqués.
check:uiéchoue pour un tel bouton ; gardez les boutons clés à l'écran à 360 px. - "Vérifié" a été affirmé juste après un déploiement alors que le site en direct servait encore l'ancienne construction. Revérifiez après une courte attente.
- Des copies d'un jeu se sont éloignées de la source. Construisez à partir d'un seul dossier ; ne patchez jamais une copie.
- Fruit Catcher (22 oct.) disait "Glissez à gauche ou à droite pour déplacer le panier" au-dessus d'une paire de boutons fléchés ; glisser ne faisait rien. Définissez
GAME.controlset laissezcheck:playle piloter. - Le même jeu a été expédié avec le coureur rouge du kit, les pièces, le badge de score de pièces et l'icône d'application de pièces. L'étape 7 les remplace tous ;
check:playéchoue sur tout fichier d'exemple. - L'utilisateur n'a vu aucun aperçu pendant 5 minutes car le port n'a jamais été exposé. L'étape 1 vient avant toute édition.
- L'agent a écrit "le navigateur de bureau ne fonctionnait pas" et a vérifié le lien en direct avec HTTP uniquement.
check:playest sans tête ; exécutez-le sur le lien en direct. - Les annonces optimisées pour un nouvel événement personnalisé (
play_engaged) ont été abandonnées. Commencez les annonces sur un objectif standard, passez une fois que l'événement se déclenche environ 50 fois par semaine.