singe/docs/fr/lessons/13-game-folder.adoc

424 lines
19 KiB
Text
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[#_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.