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
.