424 lines
19 KiB
Text
424 lines
19 KiB
Text
[#_lesson_13_a_game_folder]
|
||
== Leçon 13 : Un dossier de jeu
|
||
|
||
image::learn/13-game-folder.png[La leçon terminée, 480]
|
||
|
||
Votre jeu est un script dans un dossier dont vous vous rappelez le nom, et vous
|
||
le lancez en tapant son nom dans un terminal. C'est très bien pour vous et
|
||
inutile pour n'importe qui d'autre. Un joueur devrait pouvoir copier un dossier
|
||
à côté de Singe, lancer le menu, voir votre jeu dans la liste avec son titre et
|
||
ses illustrations, et appuyer sur un bouton. L'image ci-dessus, c'est ce menu,
|
||
avec votre jeu dedans.
|
||
|
||
Il faut pour cela un nouveau fichier, d'environ six lignes, et deux images que
|
||
vous pouvez prendre avec une seule touche. Votre script ne change pas du tout.
|
||
|
||
[#_give_the_game_a_name]
|
||
=== Donnez un nom au jeu
|
||
|
||
Un jeu a deux noms, un pour l'ordinateur et un pour les gens.
|
||
|
||
Celui de l'ordinateur, c'est le dossier, et vous l'avez choisi à la leçon neuf :
|
||
`rocks`, avec `rocks.singe` dedans. Le dossier et le script portent le même nom,
|
||
comme dans chaque leçon depuis la leçon un, et c'est pourquoi `Singe rocks`
|
||
trouve le script à partir du dossier seul. Gardez ce nom simple. Pas d'espaces,
|
||
qu'un terminal lit comme l'écart entre deux noms. Et les mêmes majuscules
|
||
partout où vous le tapez : sur la plupart des ordinateurs qui ne sont pas sous
|
||
Windows, `rocks` et `Rocks` sont deux dossiers différents, et un jeu qui ne
|
||
tourne que sur votre machine n'est pas un jeu que quelqu'un d'autre peut avoir.
|
||
|
||
Le nom pour les gens peut être tout ce que vous voulez, majuscules, espaces et
|
||
tout le reste, et il ne vit pas dans le nom du dossier. Il vit dans le fichier
|
||
dont parle cette leçon, pour que renommer le jeu dans le menu ne veuille jamais
|
||
dire renommer un dossier.
|
||
|
||
[#_what_goes_in_the_folder]
|
||
=== Ce qui va dans le dossier
|
||
|
||
Tout ce dont votre jeu a besoin, et rien d'autre. À la fin de cette leçon, il
|
||
ressemble à ceci :
|
||
|
||
----
|
||
rocks/
|
||
games.dat Ce que lit le menu
|
||
rocks.singe Le jeu
|
||
art/ Le kit graphique de la leçon neuf
|
||
spaceship.png
|
||
asteroid.png
|
||
bullet.png
|
||
star.png
|
||
shoot.wav
|
||
boom.wav
|
||
...
|
||
cabinet.png Une image que le menu montre à côté de la liste
|
||
marquee.png Une image que le menu montre au-dessus
|
||
----
|
||
|
||
Tout ce qui a pu atterrir là pendant que vous appreniez -- `walk.singe` de la
|
||
leçon neuf, le petit test du son de la leçon dix -- ne fait pas partie du jeu.
|
||
Déplacez-les dans un dossier à eux, à côté de `rocks`. Le kit graphique contient
|
||
aussi quelques fichiers que ce jeu ne charge jamais, et ils ne font aucun mal
|
||
pour l'instant. C'est à la leçon trente que vous passerez un dossier de jeu en
|
||
revue pour en retirer tout ce qui n'est pas le jeu.
|
||
|
||
La règle derrière cette organisation, c'est qu'un jeu ne va jamais rien chercher
|
||
hors de son propre dossier. Ni une illustration, ni un son, ni une bibliothèque
|
||
dont vous vous servez aussi dans un autre jeu -- si vous partagez du code entre
|
||
deux jeux, chacun garde sa propre copie. Il y a exactement un endroit hors du
|
||
dossier où un jeu a le droit de charger quelque chose, et vous y chargez déjà :
|
||
le dossier `Singe` du moteur lui-même, où se trouve `Singe/Framework.singe`, et,
|
||
depuis la leçon dix, le clic et la musique.
|
||
|
||
Le dossier du jeu se trouve dans votre dossier de travail, à côté du moteur :
|
||
|
||
----
|
||
singe/ Votre dossier de travail
|
||
Singe-v3.00-... Le moteur lui-même, quel que soit le nom du vôtre
|
||
Menu.sh Lance le menu. Menu.bat sous Windows
|
||
Singe/ Fichiers de support. Pas à vous ; n'y touchez pas
|
||
data/ Tout ce qui s'écrit, votre sauvegarde comprise
|
||
rocks/ Votre jeu
|
||
----
|
||
|
||
C'est aussi la forme qu'a la machine d'un joueur. Le moteur a écrit `Singe`,
|
||
`data` et `Menu.sh` (`Menu.bat` sous Windows) la première fois que vous avez
|
||
lancé quoi que ce soit, à la leçon un. La leçon un a parlé des deux premiers. Le
|
||
troisième est nouveau pour vous, et cette leçon le met au travail.
|
||
|
||
[#_paths_count_from_where_singe_started]
|
||
=== Les chemins partent de l'endroit où Singe a démarré
|
||
|
||
Vous faites ça depuis la leçon neuf, donc c'est un rappel, pas un changement.
|
||
|
||
Chaque nom que votre jeu charge -- `art/spaceship.png`, `art/boom.wav` -- est
|
||
cherché à partir du dossier dans lequel Singe a été *lancé*, et non du dossier
|
||
où se trouve votre script. Vous lancez Singe dans votre dossier de travail, donc
|
||
un simple `art/spaceship.png` serait cherché dans `singe/art`, qui n'existe pas.
|
||
`DIR` est le dossier de votre script lui-même, avec la barre oblique déjà au
|
||
bout, donc un nom qu'on y colle désigne votre fichier, d'où que Singe ait été
|
||
lancé :
|
||
|
||
[source,lua]
|
||
----
|
||
local shipSprite = spriteLoad(DIR .. "art/spaceship.png")
|
||
----
|
||
|
||
Le menu lance Singe dans le dossier où se trouve `Menu.sh`, c'est-à-dire de
|
||
nouveau votre dossier de travail, donc `DIR` y fait exactement ce qu'il fait
|
||
pour vous. Il continue de le faire quand le jeu est empaqueté dans un seul
|
||
fichier à la leçon trente, quand le dossier de travail de quelqu'un d'autre
|
||
s'appelle tout autrement, et sur une machine que vous ne verrez jamais. Un nom
|
||
qui commence par `Singe/` désigne le dossier du moteur et n'a jamais besoin de
|
||
`DIR` ; chaque nom qui est à vous en a besoin.
|
||
|
||
[#_games_dat]
|
||
=== games.dat
|
||
|
||
`games.dat`, c'est la façon dont un jeu se présente. Le menu lit le `games.dat`
|
||
de chaque dossier de jeu qui se trouve à côté de lui, et liste ce qu'il trouve.
|
||
Pas de `games.dat`, pas de place dans la liste : votre dossier est invisible,
|
||
aussi bon que soit le jeu qu'il contient.
|
||
|
||
Créez un nouveau fichier appelé `games.dat` dans votre dossier `rocks`. Voici le
|
||
plus petit qui marche :
|
||
|
||
[source,lua]
|
||
----
|
||
GAMES = {
|
||
{
|
||
TITLE = "Rocks",
|
||
SCRIPT = "rocks/rocks.singe"
|
||
}
|
||
}
|
||
----
|
||
|
||
C'est du Lua, et c'est une table du genre de celles que vous avez rencontrées à
|
||
la leçon six : `GAMES` est une liste, et chaque élément de la liste est un
|
||
enregistrement qui décrit un jeu. Un dossier peut contenir plusieurs jeux --
|
||
c'est pour ça que c'est une liste -- mais le vôtre n'en contient qu'un.
|
||
|
||
`SCRIPT` est le champ dont le moteur a besoin pour lancer le jeu, et `TITLE`
|
||
celui dont le menu a besoin pour le lister. Le chemin du script part du dossier
|
||
*au-dessus* du `games.dat`, et non du dossier où se trouve le
|
||
`games.dat`. Donc un `games.dat` placé dans `rocks` désigne son propre script
|
||
par `rocks/rocks.singe`. On dirait que ça dit `rocks` deux fois, et c'est
|
||
correct. Tous les autres chemins du fichier marchent de la même façon.
|
||
Trompez-vous, et rien ne proteste quand vous tapez le nom : l'entrée ne
|
||
correspond simplement jamais au script que vous avez lancé.
|
||
|
||
`TITLE`, c'est le nom pour les gens du début de cette leçon. C'est ce
|
||
qu'affiche le menu, et les jeux sont listés dans l'ordre de leurs titres, donc
|
||
le titre décide aussi de la place de votre jeu dans la liste.
|
||
|
||
[#_telling_the_menu_more]
|
||
=== En dire plus au menu
|
||
|
||
Le menu a tout un panneau à remplir à côté de la liste, et il le remplit avec le
|
||
reste de l'entrée :
|
||
|
||
[source,lua]
|
||
----
|
||
GAMES = {
|
||
{
|
||
TITLE = "Rocks",
|
||
SCRIPT = "rocks/rocks.singe",
|
||
CANVAS_X = 720,
|
||
CANVAS_Y = 480,
|
||
YEAR = 2026,
|
||
GENRE = "Shooter",
|
||
DEVELOPER = "Your Name Here",
|
||
PUBLISHER = "Your Name Here",
|
||
DESCRIPTION = "Shoot the rocks before they reach your ship.",
|
||
CABINET = "rocks/cabinet.png",
|
||
MARQUEE = "rocks/marquee.png"
|
||
}
|
||
}
|
||
----
|
||
|
||
`CABINET` et `MARQUEE` sont des fichiers d'image ordinaires dans le dossier de
|
||
votre jeu, dans n'importe quel format que Singe sait lire. L'illustration de
|
||
borne est la grande image à côté de la liste, et le fronton est la bande
|
||
au-dessus. Donnez-leur la taille que vous voulez ; le menu les ajuste à leurs
|
||
panneaux.
|
||
|
||
Vous n'avez pas besoin d'un logiciel de dessin pour les faire, parce que votre
|
||
jeu peut prendre sa propre photo. Lancez-le, et quand l'écran ressemble à ce que
|
||
vous voulez montrer au monde, appuyez sur F12 (ou F11, parce que certains
|
||
bureaux gardent F12 pour eux). Singe enregistre une image de la fenêtre dans le
|
||
dossier de données de votre jeu, `data/rocks`, sous le nom `singe000.png`, puis
|
||
`singe001.png`, et ainsi de suite. Prenez-en une de l'écran titre et une au
|
||
milieu d'un combat. Copiez-les dans votre dossier `rocks` et renommez-les : le
|
||
combat devient `cabinet.png`, le titre `marquee.png`.
|
||
|
||
Un vrai fronton est une large bande avec le nom du jeu en grosses lettres, et un
|
||
écran entier tassé dedans ressemble à un timbre-poste. Ça fera l'affaire en
|
||
attendant mieux. Laissez de côté `MARQUEE` et le menu met à la place l'image
|
||
manquante du moteur lui-même, un damier rose qui dit MISSING, ce qui est pire.
|
||
|
||
`YEAR`, `GENRE`, `DEVELOPER`, `PUBLISHER` et `DESCRIPTION` sont le texte en
|
||
dessous, et le moteur ne les regarde jamais. Ils sont là pour la personne qui
|
||
lit le menu, et c'est bien le but.
|
||
|
||
`CANVAS_X` et `CANVAS_Y` sont la taille du monde de votre jeu, et 720 sur 480
|
||
est la valeur par défaut -- le même monde que celui où vous dessinez depuis la
|
||
leçon un. Ne les réglez que si votre jeu veut une autre forme. Un jeu sans champ
|
||
`VIDEO` est un jeu sans vidéo, ce qui est le cas du vôtre ; c'est à la leçon
|
||
quatorze que ce champ commence à compter.
|
||
|
||
La section `games.dat` de la Référence donne tous les champs qui existent, dont
|
||
plusieurs pour du matériel que vous n'avez pas encore. Quelques autres méritent que
|
||
vous connaissiez leur nom dès maintenant.
|
||
|
||
`REQUIRES` dit ce dont un jeu a besoin de la part de la machine au-delà de la
|
||
simple 2D : `"GUI"` pour les menus et les pages de la leçon vingt, `"SCENE"`
|
||
pour la 3D qui commence à la leçon vingt-deux, et quelques autres. Le menu le
|
||
lit pour pouvoir dire à un joueur « cette machine ne peut pas faire tourner ce
|
||
jeu » au lieu de laisser le jeu échouer en plein milieu. Rocks, c'est de la 2D
|
||
toute simple, et laisser de côté `REQUIRES` veut dire exactement ça, donc
|
||
laissez-le de côté. Vous aurez rarement à dresser la liste vous-même, parce que
|
||
Singe remarque ce dont un jeu se sert pendant qu'il tourne, et le dit quand
|
||
l'entrée ne le liste pas. À partir de la leçon vingt, vous verrez des lignes
|
||
comme celle-ci, que le jeu ait un `games.dat` ou non :
|
||
|
||
----
|
||
Warning: this game uses GUI, which its games.dat does not list in REQUIRES.
|
||
----
|
||
|
||
C'est un conseil, pas une erreur ; le jeu tourne dans les deux cas. Le remède
|
||
tient en une ligne dans l'entrée, `REQUIRES = { "GUI" },`, et empaqueter un jeu
|
||
à la leçon trente écrit la liste pour vous si l'entrée n'en a pas. Son
|
||
partenaire `TIER`, un nombre de 0 à 3, dit quelle puissance de machine un jeu
|
||
demande, et peut attendre que vous écriviez un jeu assez lourd pour que ça
|
||
compte.
|
||
|
||
`GAME_ID` est une identité unique pour votre jeu, dont les tableaux des scores
|
||
en ligne de la leçon vingt-huit ont besoin, et rien d'autre.
|
||
Et `RESOLUTION_X` et `RESOLUTION_Y` demandent une taille de fenêtre précise.
|
||
Ignorez le reste jusqu'à ce que quelque chose vous envoie le chercher.
|
||
|
||
[#_running_it_from_the_menu]
|
||
=== Le lancer depuis le menu
|
||
|
||
Lancez `Menu.sh` -- `Menu.bat` sous Windows -- depuis votre dossier de travail.
|
||
Il trouve le Singe le plus récent à côté de lui et lance le menu.
|
||
|
||
Votre jeu est dans la liste, avec ses illustrations à côté et sa description en
|
||
dessous. C'est la seule chose dans la liste, parce que `rocks` est le seul
|
||
dossier auquel vous avez donné un `games.dat` ; `hello`, `dodge` et les autres
|
||
ne sont pas des jeux, pour autant que le menu puisse en juger. Haut et bas
|
||
avancent d'un jeu, gauche et droite d'une page, et start ou un bouton de tir
|
||
lance celui qui est sélectionné. Quittez le jeu avec Échap et vous voilà de
|
||
retour au menu, sur le même jeu, prêt à repartir. Le menu se souvient aussi du
|
||
jeu sur lequel vous étiez d'un lancement à l'autre.
|
||
|
||
C'est tout ce qu'il faut pour publier un jeu, du point de vue du moteur. Un
|
||
joueur copie votre dossier à côté de Singe, et le jeu apparaît.
|
||
|
||
Taper le nom marche toujours, et marche de la même façon :
|
||
|
||
----
|
||
Singe rocks
|
||
----
|
||
|
||
Quand vous lancez un script à la main comme ça, Singe cherche un `games.dat` à
|
||
côté de lui -- et jusqu'à trois dossiers au-dessus -- et si une entrée nomme le
|
||
script que vous avez lancé, les réglages de cette entrée s'y appliquent. Un jeu
|
||
se comporte donc de la même façon depuis un terminal que depuis le menu, ce qui
|
||
veut dire que vous pouvez continuer à travailler comme avant, avec `-R` et un
|
||
éditeur de texte, tout en vous fiant à ce qu'un joueur obtiendra. Il écrit aussi
|
||
au même endroit : quelle que soit la façon dont votre jeu est lancé, sa
|
||
sauvegarde est celle de `data/rocks`.
|
||
|
||
[#_later_one_file]
|
||
=== Plus tard : un seul fichier
|
||
|
||
Un dossier, c'est facile pour travailler et un peu malcommode à donner : une
|
||
douzaine de fichiers, un dossier dans un dossier, et un joueur qui le
|
||
décompresse au mauvais endroit. Un jeu Singe terminé peut être empaqueté dans un
|
||
seul fichier `.game` que le moteur lance directement, illustrations, sons et
|
||
tout le reste compris, et qu'un joueur copie à côté de Singe, un point c'est
|
||
tout.
|
||
|
||
Rien dans votre jeu n'a besoin de changer pour ça. C'est la leçon trente, et ça
|
||
vaut la peine d'attendre : empaquetez un jeu qui n'est pas fini et vous
|
||
l'empaquetterez de nouveau demain.
|
||
|
||
[#_what_just_happened_9]
|
||
=== Ce qui vient de se passer
|
||
|
||
[source,lua]
|
||
----
|
||
GAMES = {
|
||
{
|
||
----
|
||
|
||
Deux accolades, parce que c'est une liste d'enregistrements. L'extérieure, c'est
|
||
la liste. L'intérieure, c'est le premier élément de la liste, c'est-à-dire
|
||
l'enregistrement d'un jeu. Se tromper sur l'une des deux est l'erreur
|
||
habituelle, et Lua vous donnera la ligne.
|
||
|
||
[source,lua]
|
||
----
|
||
SCRIPT = "rocks/rocks.singe",
|
||
----
|
||
|
||
Compté à partir du dossier au-dessus du `games.dat`, c'est-à-dire votre dossier
|
||
de travail. C'est le même nom que celui que vous taperiez après `Singe` pour
|
||
lancer le script à la main, et c'est la façon la plus simple de vous en
|
||
souvenir.
|
||
|
||
La virgule au bout de la ligne sépare un champ du suivant, exactement comme à la
|
||
leçon six. Le dernier champ d'un enregistrement n'a pas de virgule après lui --
|
||
Lua ne s'en offusque pas s'il en a une, mais laissez-la de côté et votre fichier
|
||
ressemblera à celui de tout le monde. Une virgule qui manque au milieu, c'est
|
||
une autre affaire, et c'est l'erreur de cette leçon.
|
||
|
||
[source,lua]
|
||
----
|
||
CABINET = "rocks/cabinet.png",
|
||
----
|
||
|
||
Une image que charge le menu, pas votre jeu, donc elle est nommée comme
|
||
`SCRIPT`, à partir du dossier du dessus, et pas avec `DIR`. `DIR` appartient à
|
||
votre script pendant qu'il tourne, et le menu et le moteur lisent `games.dat`
|
||
avant que votre script ait démarré.
|
||
|
||
[#_try_it_13]
|
||
=== Essayez
|
||
|
||
. *Faites de meilleures illustrations.* Si vous avez un logiciel de dessin,
|
||
faites un vrai `marquee.png` : une large bande avec ROCKS écrit en travers en
|
||
grosses lettres. Mettez-le à la place de la capture d'écran et regardez de
|
||
nouveau le menu.
|
||
. *Donnez un games.dat à Dodge.* Écrivez un `games.dat` dans votre dossier
|
||
`dodge` de la leçon sept et lancez le menu. Deux jeux maintenant, dans l'ordre
|
||
des titres. Puis changez le `TITLE` de Rocks en `Asteroid Field` et
|
||
regardez-le passer au-dessus de Dodge : la liste est triée par titre, pas par
|
||
dossier.
|
||
. *Cassez games.dat pour le menu.* Supprimez l'une des accolades fermantes du
|
||
`games.dat` de `rocks` et lancez le menu. Votre jeu a disparu de la liste, et
|
||
le terminal dit pourquoi. Remettez-la.
|
||
. *Trompez-vous de SCRIPT.* Mettez `CANVAS_X` à `1280` et `CANVAS_Y` à `720`,
|
||
et lancez `Singe rocks`. L'aire de jeu est plus large. Changez maintenant
|
||
`SCRIPT` en `rocks.singe` et relancez-le. Le jeu a retrouvé son ancienne
|
||
taille, et rien ne vous l'a dit : l'entrée ne nomme plus le script que vous
|
||
avez lancé, donc elle ne s'applique pas. Remettez les deux comme avant.
|
||
. *Trouvez votre sauvegarde.* Lancez le jeu depuis le menu, établissez un
|
||
meilleur score, quittez pour revenir au menu, et quittez le menu. Lancez
|
||
`Singe rocks` et regardez l'écran titre. Puis cherchez dans `data/rocks` le
|
||
fichier qui s'en est souvenu.
|
||
|
||
[#_break_it_on_purpose_12]
|
||
=== Cassez-le exprès
|
||
|
||
Retirez la virgule au bout de la ligne `TITLE`, pour que le haut du fichier
|
||
devienne :
|
||
|
||
[source,lua]
|
||
----
|
||
GAMES = {
|
||
{
|
||
TITLE = "Rocks"
|
||
SCRIPT = "rocks/rocks.singe",
|
||
----
|
||
|
||
Lancez `Singe rocks`. Le jeu démarre, et le terminal dit ceci :
|
||
|
||
----
|
||
Note: rocks/games.dat ignored: [string "rocks/games.dat"]:4: '}' expected (to close '{' at line 2) near 'SCRIPT'
|
||
----
|
||
|
||
Votre jeu tourne quand même, parce qu'un jeu lancé par son nom n'a pas besoin de
|
||
son entrée. Il tourne simplement sans elle. Lancez le menu, en revanche, et
|
||
votre jeu a disparu. Si c'était le seul, la liste affiche `No games yet`, et le
|
||
terminal dit la même chose autrement :
|
||
|
||
----
|
||
rocks/games.dat: rocks/games.dat:4: '}' expected (to close '{' at line 2) near 'SCRIPT' Skipped.
|
||
----
|
||
|
||
Lisez-le comme n'importe quelle autre erreur Lua. Le fichier est
|
||
`rocks/games.dat` et la ligne est la 4. Mais la ligne 4 est la ligne `SCRIPT`,
|
||
et elle n'a rien de faux. L'erreur est au bout de la ligne 3. Après
|
||
`TITLE = "Rocks"`, Lua attendait soit une virgule et un autre champ, soit le
|
||
`}` qui ferme l'enregistrement commencé à la ligne 2. Il a trouvé `SCRIPT` à
|
||
la place, donc c'est à la ligne 4 qu'il s'en est aperçu. Sa proposition de
|
||
correction -- un `}` -- est fausse ; sa ligne est décalée d'une. Quand une
|
||
erreur désigne le début d'une ligne, regardez la fin de la ligne d'avant.
|
||
|
||
Remettez la virgule, et relancez le menu.
|
||
|
||
[#_what_you_learned_13]
|
||
=== Ce que vous avez appris
|
||
|
||
* Un jeu est un dossier : le script, ses illustrations et un `games.dat`, et
|
||
rien qui vienne de l'extérieur, sauf le dossier `Singe` du moteur lui-même.
|
||
* Le nom du dossier est pour l'ordinateur, donc gardez-le simple. Le nom pour
|
||
les gens, c'est `TITLE`.
|
||
* Les noms que charge votre script partent de l'endroit où Singe a été lancé,
|
||
et c'est pourquoi chacun d'eux est construit à partir de `DIR`.
|
||
* `games.dat` est un fichier Lua qui contient une liste `GAMES`, et chaque
|
||
entrée est un jeu.
|
||
* Une entrée a besoin de `TITLE` et de `SCRIPT` et de rien d'autre ; ses
|
||
chemins partent du dossier au-dessus du `games.dat`.
|
||
* `CABINET`, `MARQUEE`, `YEAR`, `GENRE`, `DEVELOPER`, `PUBLISHER` et
|
||
`DESCRIPTION` sont ce que le menu montre au joueur, et F12 prend une image
|
||
dont vous pouvez vous servir pour les deux premiers.
|
||
* `REQUIRES` dit au menu ce dont un jeu a besoin au-delà de la 2D, et Singe vous
|
||
prévient quand un jeu se sert de quelque chose que son entrée ne liste pas.
|
||
* `Menu.sh` ou `Menu.bat` lance le menu fourni, qui liste chaque dossier de jeu
|
||
à côté de lui, trié par titre.
|
||
* Un jeu lancé par son nom reçoit lui aussi son entrée de `games.dat`, donc il
|
||
se comporte de la même façon dans les deux cas, et un `games.dat` qui ne se
|
||
charge pas est signalé, puis ignoré.
|
||
* Un jeu terminé peut être empaqueté dans un seul fichier plus tard, à la leçon
|
||
trente.
|
||
|
||
[#_next_time_13]
|
||
=== La prochaine fois
|
||
|
||
Voilà la deuxième partie terminée : vous avez un jeu, avec des illustrations, du
|
||
son, des collisions, un score, et un moyen pour quelqu'un d'autre de le lancer.
|
||
La troisième partie porte sur ce que presque aucun autre moteur ne fait -- lire
|
||
du film comme le monde où se déroule le jeu -- et la leçon quatorze commence par
|
||
le disque, l'image et l'attente.
|