Dans la section précédente, nous avons écrit le programme rendant le jeu jouable. Mais on est contraint
de résoudre la même grille à chaque fois. Aussi, l'utilisateur n'a pas d'aide pour comprendre le but du jeu ni pour
savoir comment y jouer.
Nous allons dans cette section ajouter un écran d'accueil à notre programme. Cet écran sera muni d'un
menu principal donnant accès à plusieurs choix tels que : Nouveau jeu - Aide du jeu - A Propos - Quitter.
Bien avant que le menu principal apparaisse, on demandera à l'utilisateur s'il veut activer ou désactiver
la musique de fond. Le choix d'un menu fera éventuellement apparaître un autre menu ou effectuer une tâche
particulière.
Nous allons utiliser un système de menu bien simple mais avec un peu de fantaisie.
Chaque menu a un titre général, et des options que nous conserverons dans un tableau. L'affichage du menu
se fera par groupe de trois options. Selon qu'on clique sur les touches de direction basse et haute, les autres options
deviennent visibles. On affichera une boule à coté du menu en surbrillance quelques secondes après l'affichage des options.
procedure afficherMenu(index : integer);
var
y, z, d : integer;
avant, apres : integer;
begin
SetFont(FONT_FACE_SYSTEM, FONT_STYLE_PLAIN, FONT_SIZE_SMALL);
d := GetStringHeight('H');
setColor(0, 0, 55);
FillRect(0, menuPos.y-d*2, getWidth, (d+9)*5);
setColor(204, 207, 57);
centrerTexteX(TitreMenu, menuPos.y-d*2);
avant := index-1;
if (avant<1) then
avant := dimMenu;
apres := index+1;
if (apres > dimMenu) then
apres := 1;
setColor(116, 138, 113);
centrerTexteX(menu[avant], menuPos.y);
y := menuPos.y+d+8;
z:= y+(d div 2)-7;
setColor(100, 192, 91);
centrerTexteX(menu[index], y);
y := y+d+8;
setColor(116, 138, 113);
centrerTexteX(menu[apres], y);
repaint;
delay(400);
drawImage(check, ObtenirCentreX(menu[index])-20, z);
end;
Pour créer par exemple l'écran d'accueil, on définit les options du menu dans le tableau Menu,
puis le nombre d'options dans le la variable dimMenu ainsi que le titre du menu. On demandera
ensuite au joueur de choisir une option.
procedure AfficheMenuAccueil ;
var
x, etat : integer;
img : Image;
begin
img := loadImage('/sokoban.png');
x := (getWidth div 2)-(getImageWidth(img) div 2);
repeat
setColor(0, 0, 55);
fillRect(0, 0, getWidth, getHeight);
menu[1] := 'Jouer';
menu[2] := 'Aide du jeu';
menu[3] := 'A propos';
menu[4] := 'Quitter';
dimMenu := 4;
TitreMenu := 'MEMU PRINCIPAL';
drawImage(img, x, 10);
afficherMenu(1);
Repaint;
etat :=choixMenu;
if (etat=1) then
AfficheMenuNiveau
else if (etat=2) then
annexe.aide;
else if (etat=3) then
annexe.apropos;
until etat= 4;
end;
La sélection d'une option entraîne l'exécution d'une action, que
nous codons dans une procédure. Les actions à effectuer pour le choix des options sont écrites dans
l'unité annexe.mprsc. Voici tout le code gerant la gestion des menus.
unit menu;
interface
procedure AfficheMenuAccueil ;
procedure AfficheMenuSon ;
implementation
uses misc, jeu, header, annexe;
const
dimMax = 15;
NiveauMax = 10;
var
logoPos, menuPos : record
x, y :integer;
end;
Menu : array[1..dimMax] of string;
TitreMenu : String;
dimMenu : integer;
check, imgEtoile : Image;
procedure centrerTexteX(ch : String; y : integer);
var x : integer;
begin
x:=(getWidth div 2) - (getStringWidth(ch) div 2);
drawText(ch, x, y);
end;
function ObtenircentreX(ch : String) : integer;
var x : integer;
begin
x:=(getWidth div 2) - (getStringWidth(ch) div 2);
ObtenirCentreX := x;
end;
procedure afficherMenu(index : integer);
var
y, z, d : integer;
avant, apres : integer;
begin
SetFont(FONT_FACE_SYSTEM, FONT_STYLE_PLAIN, FONT_SIZE_SMALL);
d := GetStringHeight('H');
setColor(0, 0, 55);
FillRect(0, menuPos.y-d*2, getWidth, (d+9)*5);
setColor(204, 207, 57);
centrerTexteX(TitreMenu, menuPos.y-d*2);
avant := index-1;
if (avant<1) then
avant := dimMenu;
apres := index+1;
if (apres > dimMenu) then
apres := 1;
setColor(116, 138, 113);
centrerTexteX(menu[avant], menuPos.y);
y := menuPos.y+d+8;
z:= y+(d div 2)-7;
setColor(100, 192, 91);
centrerTexteX(menu[index], y);
y := y+d+8;
setColor(116, 138, 113);
centrerTexteX(menu[apres], y);
repaint;
delay(400);
drawImage(check, ObtenirCentreX(menu[index])-20, z);
end;
function choixMenu : integer;
var
fin : boolean;
choix : integer;
touche :integer;
begin
fin := false;
choix := 1;
repeat
touche := GetKeyPressed;
if (touche<>KE_NONE ) then
begin
if (touche=KE_KEY2) or (KeyToAction(touche)=GA_UP) then
begin
choix := choix-1;
if choix<1 then
choix := dimMenu;
afficherMenu(choix);
Repaint;
end
else if (touche=KE_KEY8) or (KeyToAction(touche)=GA_DOWN) then
begin
choix:=choix+1;
if choix>dimMenu then
choix := 1;
afficherMenu(choix);
Repaint;
end
else if (touche=KE_KEY5) or (KeyToAction(touche)=GA_FIRE) then
begin
fin := true;
choixMenu := choix;
end;
touche := KE_NONE;
end;
until fin;
end;
procedure AfficheMenuSon ;
var
etat : integer;
begin
menu[1] := 'OUI';
menu[2] := 'NON';
dimMenu := 2;
TitreMenu := 'ACTIVEZ LE SON ?';
setColor(0, 0, 55);
fillRect(0, 0, getWidth, getHeight);
afficherMenu(1);
Repaint;
etat := choixMenu;
if(etat<=1) then
annexe.music;
end;
procedure afficheNiveau(id : integer);
var
x, y : integer;
begin
setColor(0, 0, 55);
fillRect(0, 0, getWidth, getHeight);
x:= (getWidth div 2) - (getStringWidth('NIVEAU '+id) div 2) -20;
y:= (getHeight div 2) - (getStringHeight('N') div 2);
setColor(100, 192, 91);
drawText('NIVEAU '+id, x+20, y);
drawImage(imgEtoile, x, y);
repaint;
delay(1500);
end;
procedure ActionJouer(id : integer);
var
etat : integer;
quitter : boolean;
begin
quitter := false;
repeat
afficheNiveau(id);
misc.chargerGrille('grille'+id);
etat:=jeu.jouer;
if (etat= jeu.statutJeu.gagne) then
begin
quitter := false;
if(id<NiveauMax) then
id :=id+1;
end
else
quitter := true;
until quitter;
end;
procedure AfficheMenuNiveau ;
var
i, etat : integer;
begin
for i := 1 to NiveauMax do
menu[i] := 'Niveau '+i;
menu[NiveauMax+1] := 'Anuler';
dimMenu := NiveauMax+1;
TitreMenu := 'CHOISISSEZ UN NIVEAU';
afficherMenu(1);
Repaint;
etat := choixMenu;
if(etat<=NiveauMax) then
ActionJouer(etat);
end;
procedure AfficheMenuAccueil ;
var
x, etat : integer;
img : Image;
begin
img := loadImage('/sokoban.png');
x := (getWidth div 2)-(getImageWidth(img) div 2);
repeat
setColor(0, 0, 55);
fillRect(0, 0, getWidth, getHeight);
menu[1] := 'Jouer';
menu[2] := 'Aide du jeu';
menu[3] := 'A propos';
menu[4] := 'Quitter';
dimMenu := 4;
TitreMenu := 'MEMU PRINCIPAL';
drawImage(img, x, 10);
afficherMenu(1);
Repaint;
etat :=choixMenu;
if (etat=1) then
AfficheMenuNiveau
else if (etat=2) then
annexe.aide;
else if (etat=3) then
annexe.apropos;
until etat= 4;
end;
initialization
menuPos.x := 50;
menuPos.y := 100;
check := loadImage('/10118.png');
imgEtoile := loadImage('/etoile.png');
end.
Et le code de l'unité comportant les actions :
unit annexe;
interface
procedure music;
procedure aPropos;
procedure aide;
implementation
uses header, affichage;
var imgRetour : Image;
procedure music;
var
b : boolean;
begin
if OpenPlayer('/bgsound.mid', 'audio/midi') then
if SetPlayerCount(-1) then
b:=StartPlayer ;
end;
procedure centrerTexte(ch : String; y : integer);
var
x : integer;
begin
x:=(getWidth div 2) - (getStringWidth(ch) div 2);
drawText(ch, x, y);
end;
procedure attente;
begin
while (GetKeyPressed<> KE_NONE) do
begin
end;
repeat
until KeyToAction(GetKeyPressed)=GA_FIRE;
end;
procedure afficheEntete;
var
img : Image;
x : integer;
begin
img := loadImage('/sokoban.png');
x := (getWidth div 2)-(getImageWidth(img) div 2);
drawImage(img, x, 10);
end;
procedure aPropos;
var
x, y, dy , clicked: integer;
begin
setColor(0, 0, 55);
fillRect(0, 0, getWidth, getHeight);
afficheEntete;
drawImage(imgRetour, (getWidth div 2)-8, (GetHeight)-20) ;
setColor(116, 138, 113);
SetFont(FONT_FACE_MONOSPACE, FONT_STYLE_PLAIN, FONT_SIZE_SMALL);
y:=45;
dy:=getStringHeight('H');
dy:=dy+dy div 3;
y:=y+dy;
centrerTexte('Par Kpizingui Darryl', y);
y:=y+dy;
centrerTexte('nobi_8@hotmail.com', y);
y:=y+dy;
centrerTexte('http://darrylsite.tk/', y);
y:=y+dy;
centrerTexte('© Copyright 2010', y);
y:=y+dy;
drawImage(loadImage('/logo.png'), (getWidth div 2)-25, y);
Repaint;
attente;
end;
procedure aide;
var x, y, d : integer;
begin
setColor(0, 0, 55);
fillRect(0, 0, getWidth, getHeight);
afficheEntete;
setColor(116, 138, 113);
SetFont(FONT_FACE_MONOSPACE, FONT_STYLE_PLAIN, FONT_SIZE_SMALL);
x := 20;
y := 60;
d := 20;
drawImage(affichage.imgMario, x, y);
drawText('Mario', x+d, y);
y:=y+d+(d div 3);
drawImage(affichage.imgCible, x, y);
drawText('Cible', x+d, y);
y:=y+d+(d div 3);
drawImage(affichage.imgCaisse, x, y);
drawText('Caisse', x+d, y);
y:=y+d+(d div 3);
drawImage(affichage.imgOKCaisse, x, y);
drawText('Caisse bien placée', x+d, y);
y:=y+d+(d div 3);
drawImage(affichage.imgMur, x, y);
drawText('Mur', x+d, y);
drawImage(imgRetour, (getWidth div 2)-8, (GetHeight)-20) ;
repaint;
attente;
setColor(0, 0, 55);
fillRect(0, 50, getWidth, getHeight);
setColor(116, 138, 113);
SetFont(FONT_FACE_MONOSPACE, FONT_STYLE_PLAIN, FONT_SIZE_SMALL);
y:=45;
d:=getStringHeight('H')+(d div 3);
y:=y+d;
centrerTexte('Utilisez les touches de', y);
y:=y+d;
centrerTexte('direction pour diriger', y);
y:=y+d;
centrerTexte('Mario afin qu''il deplace', y);
y:=y+d;
centrerTexte('les caisses sur les cibles.', y);
y:=y+d;
centrerTexte('La partie est gagnée s''il', y);
y:=y+d;
centrerTexte('ne reste plus aucune cible', y);
drawImage(imgRetour, (getWidth div 2)-8, (GetHeight)-20) ;
repaint;
attente;
end;
initialization
imgRetour := loadImage('/return.png');
end.