Aller au menu - Aller au contenu

Icône TP: Plus ou Moins, votre premier jeu

Avatar
Avatar
Mise à jour : 14/10/2009
Difficulté : Facile Facile
282 visites depuis 7 jours, classé 354/786
Hé hé ! Si vous pensiez vous être débarrassés de ce maudit TP après la première partie du cours de M@teo21, détrompez-vous ! Il est de retour et désormais il compte bien s'attaquer à votre Nintendo DS ! :D
Sommaire du tutoriel :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Préparatifs

Gestion du nombre aléatoire



Cette fois-ci nous n'allons pas utiliser time.h puisque ça ne fonctionnera pas avec la DS, il faut utiliser une autre fonction qui utilise l'horloge interne de la console, sans que vous ayez besoin de connaître les éléments qui permettent de récupérer l'heure. Nous allons juste utiliser des fonctions qui nous facilitent la vie en récupérant déjà l'heure.

Tout d'abord dire à la console que nous allons lui demander un nombre aléatoire :
Code : C
1
u32 PA_InitRand ();


Et utiliser la fonction qui renvoie le nombre:
Code : C
1
u32 PA_RandMax (u32 max);

Cette fonction renvoie un nombre en 0 et max INCLUS.

Voilà une autre fonction utile :
Code : C
1
u32 PA_RandMinMax (u32 min, u32 max);

Vous remarquerez que la fonction renvoie et demande des u32 (32 bits), nos variables pourront être de type int ou long, il n'y a pas de soucis de ce coté. ;)

Cette fonction marchera aussi si vous testez votre programme sur votre ordinateur à l'aide d'un émulateur ;) .


La gestion du clavier



Ne vous êtes-vous pas demandés comment diable l'utilisateur rentrera-t-il son nombre ? La solution : utiliser le clavier de la Nintendo DS bien sûr ;) !

Initialisation du clavier


Il faut d'abord initialiser le clavier avec :
Code : C
1
void PA_InitKeyboard(numero_bg);


Vous n'avez pas besoin de préciser l'écran puisque vous devez utiliser le stylet pour appuyer sur les touches du clavier.


Apparition du clavier


Sachez que le clavier part du bas pour venir à la position voulue. Il faut juste que vous rentriez les coordonnées idéales du clavier pour voir une belle animation.
On utilisera :
Code : C
1
void PA_KeyboardIn (s16 x, s16 y);

Mais le clavier vient du bas et un seul mouvement est possible (du bas vers le haut).
Je vais vous donner une fonction toute faite pour faire un déplacement comme vous le voulez :
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//PROTOTYPE
void defiler_clavier(int,int,int,int,int);
//FONCTION
void defiler_clavier(int x,int y,int x1,int y1,int nvbl)
{
    /*Le clavier va de (x;y) à (x1;y1) avec nvbl VBL pour chaque étape du déplacement*/
    int i=0;
    PA_ScrollKeyboardXY(x,y); //On met le clavier à la position (x;y)
    while(1)
    {
        /*On se rapproche des coordonnées (x1;y1)*/
        if(x<x1)
            x++;
        else if(x>x1)
            x--;
        if(y<y1)
            y++;
        else if(y>y1)
            y--;
        if(x==x1 && y==y1)
            break;
        PA_ScrollKeyboardXY(x,y); //On replace le clavier à la nouvelle position
        /*On attend en fonction du nombre de VBL donné par la variable nvbl*/
        for(i=0;i<nvbl;i++)
            PA_WaitForVBL();
    }
}

Le clavier passera de (x;y) à (x1;y1) et à chaque tour de boucle, il y aura nvbl PA_WaitForVBL.
Souvenez-vous que 1 VBL=\frac {1}{60} s, car la fréquence de la Nintendo DS est de 60 Hz.


Traitement du clavier


Ça, c'est une toute autre histoire ! :p
Il faut opérer en ce sens :
  • créer un entier qui va contenir le nombre progressivement entré par l'utilisateur (caractère par caractère).
    Mais comment allons nous ajouter des chiffres ou en retirer ?

    Bonne question... A chaque fois qu'on ajoute un chiffre, il doit aller tout à droite (à la place des unités). Donc on multiplie le nombre par 10 et on y ajoute tout simplement le chiffre entré. Pour retirer le dernier chiffre (lorsqu'on appuie sur Backspace) il suffira de diviser le nombre par 10 car le résultat sera tronqué à l'unité.
  • créer une variable de type int contenant le nombre de tentatives ;
  • créer une variable s32 qui contiendra le nombre de lettres ;
  • créer une variable char qui contiendra la lettre actuelle ;
  • Vous aurez sûrement besoin de <string.h>.
    </puce>
  • coder la boucle en reconnaissant la lettre entrée et en l'analysant :
    Code : C
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    char lettre=0;
    /*INITIALISATIONS A METTRE*/
    while(1)
    {
        lettre=PA_CheckKeyboard();
        if(lettre>='0' && lettre<='9')
            PA_OutputText(1,0,3,"%d",lettre-'0');
        else if(lettre==PA_BACKSPACE)
            //ON EFFACE LE DERNIER CARACTÈRE, PENSEZ A FAIRE UNE FONCTION
        else if(lettre=='\n')
            //ON VALIDE
        /*RESTE DE LA BOUCLE*/
    }
    

    Si l'utilisateur appuie sur 0, lettre vaudra 48 ; sur 1, lettre vaudra 49 et ainsi de suite... C'est pour cela qu'il faut soustraire 48 à notre numéro de touche.

Bon, côté interface, on écrira tout sur l'écran supérieur.
En premier, la console affichera :
Code : Console
Entrez un nombre entre 1 et 100 inclus :

Au-dessous, (ligne 3) vous écrirez l'entrée du joueur.
Si le nombre entré est plus petit que le nombre à trouver, on effacera l'écran supérieur pour écrire :
Code : Console
Le nombre %s est trop petit. Veuillez attendre 2 secondes...

Où %s est la chaîne entrée par l'utilisateur.
Si le nombre est trop grand, on écrira :
Code : Console
Le nombre %s est trop grand. Veuillez attendre 2 secondes...

Et si le nombre est trouvé, on écrira :
Code : Console
Bravo ! Vous avez réussi à trouver le nombre %s en %d tentative%s ! Veuillez attendre 2 secondes...

Où %d est le nombre de tentatives et le 2ème %s est le résultat d'une ternaire pour savoir si on met le pluriel ou pas.
N'oubliez pas de faire l'attente pour les 2 secondes.
Au passage, on effacera l'écran à chaque tour de boucle (si on efface le dernier caractère, la mise à jour sera automatique). Et si le joueur a trouvé le nombre, on quitte la boucle (utiliser while(1) avec un break lorsque l'objectif est atteint, afin d'attendre que l'utilisateur appuie sur Entrée). Et, après celle-ci, on affichera :
Code : Console
Bravo ! Vous avez réussi à trouver le nombre %s en %d tentative%s !


Disparition du clavier


La simple fonction Code : C
1
void  PA_KeyboardOut (void);

nous "rangera" automatiquement notre clavier ;) . Si vous ne voulez pas l'utiliser, vous pouvez utiliser notre fonction defiler_clavier.

Customisation du clavier :)


Vous pouvez personnaliser votre clavier. Vous devez créer d'abord un fichier image qui contiendra votre clavier. Ce fichier mesurera 256*1024 pixels. Aux coordonnées (0;0) dessinez votre clavier qui doit mesurer 208x96 pixels. La contrainte est que les touches doivent être de même dimensions que le clavier par défaut (il y a un exemple ci-dessous pour que vous puissiez bien voir les dimensions). Aux coordonnées (0;512) dessinez votre clavier (quand le joueur appuiera sur la touche Shift ou Caps).
Voici un exemple de clavier :
Keyboard personnalisé^^

Il s'agit de l'image devkitPro\PAlibExamples\Input\Keyboard\KeyboardCustom\source\gfx ^^ .
Bien sûr, il faut l'ajouter à votre dossier gfx comme ceci :
Citation
#TranspColor Magenta

#Sprites :

#Backgrounds :
clavier.png 16colors

Pour utiliser un clavier personnalisé, on utilise Code : C
1
void PA_InitCustomKeyboard(numero_bg, fichier_contenant_votre_clavier);

Voilà, vous savez tout à présent sur les claviers ;) .

Correction

Voici une correction parmi d'autres :) :
Secret (cliquez pour afficher)
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <PA9.h>

void defiler_clavier(int,int,int,int,int);

int main(int argc, char ** argv)
{
    int nombre,entre=0,i,compteur=0;
    char lettre;

    /*INITIALISATIONS*/
    PA_Init();

    PA_LoadDefaultText(1,0);
    PA_InitRand(); //On initialise le Rand
    PA_InitKeyboard(2); //On initialise le clavier sur le fond 2

    defiler_clavier(50,48,25,96,1); //Un défilement du clavier pour le faire apparaître, vous pouvez le changer
    nombre=PA_RandMinMax(1,100); //La variable nombre contient un nombre compris entre 1 et 100 inclus

    while(1) //Tant que le nombre entré par le joueur est différent de la variable nombre
    {
        PA_OutputText(1,0,0,"Entrez un nombre entre 1 et 100 inclus :");
        lettre=PA_CheckKeyboard(); //On récupère la valeur numérique de l'entrée de l'utilisateur
        if(lettre>='0'&&lettre<='9'&&entre<100) //Il faut que la touche pressée soit comprise entre 0 et 9 (et rien d'autre), et que le nombre entré soit inférieur à 100, car le nombre maximum est 100
        {
            entre*=10; //On décale tous les chiffres d'un cran vers la gauche (une dizaine)
            entre+=lettre-'0'; //On ajoute les nouvelles "unités"
        }
        else if(lettre==PA_BACKSPACE) //Si on appuie sur Backspace
            entre/=10; //On décale tous les chiffres d'un cran vers la droite
        else if(lettre=='\n') //Si on appuie sur l'équivalent de la touche Entrée
        {
            compteur++; //Le compteur de tentatives est augmenté
            PA_ClearTextBg(1); //On efface le texte de l'écran supérieur (celui où sont écrits tous les textes à afficher)
            if(entre<nombre)
            {
                PA_OutputText(1,0,0,"Le nombre %d est trop petit. Veuillez attendre 2 secondes...",entre);
                entre=0;
            }
            else if(entre>nombre)
            {
                PA_OutputText(1,0,0,"Le nombre %d est trop grand. Veuillez attendre 2 secondes...",entre);
                entre=0;
            }
            else
                break;
            for(i=0;i<120;i++)
                PA_WaitForVBL(); //On attend 2 secondes
        }
        if(entre!=0) //On écrit pas le nombre s'il est "vide"
            PA_OutputText(1,0,3,"%d",entre); //On laisse le nombre affiché
        PA_WaitForVBL();
        PA_ClearTextBg(1); //On efface l'écran supérieur
    }
    PA_OutputText(1,0,0,"Bravo ! Vous avez réussi à trouver le nombre %d en %d tentative%s !",entre,compteur-1,compteur-1<2?"":"s"); //Ternaire pour vérifier si, en fonction de compteur-1, on doit mettre du singulier ou du pluriel. Et je mets compteur-1 car je fais cadeau de la bonne tentative
    PA_KeyboardOut(); //On range notre clavier

    while(1)
        PA_WaitForVBL();

    return 0;
}

void defiler_clavier(int x,int y,int x1,int y1,int nvbl)
{
    /*Le clavier va de (x;y) à (x1;y1) avec nvbl VBL pour chaque étape du déplacement*/
    int i=0;
    PA_ScrollKeyboardXY(x,y); //On met le clavier à la position (x;y)
    while(1)
    {
        /*On se rapproche des coordonnées (x1;y1)*/
        if(x<x1)
            x++;
        else if(x>x1)
            x--;
        if(y<y1)
            y++;
        else if(y>y1)
            y--;
        if(x==x1&&y==y1)
            break;
        PA_ScrollKeyboardXY(x,y); //On replace le clavier à la nouvelle position
        /*On attend en fonction du nombre de VBL donné par la variable nvbl*/
        for(i=0;i<nvbl;i++)
            PA_WaitForVBL();
    }
}


Merci à daminator pour son optimisation du code !

Améliorations

On peut :
  • créer plusieurs niveaux de jeu ;
  • créer une aide qui réagit en fonction du nombre à trouver et du nombre entré par l'utilisateur comme ceci, par exemple :
    Code : Console
    Le nombre à trouver se trouve entre %d et %d.

On va créer plusieurs niveaux de jeu ^^ . Ce sera utile pour la suite... Ça déborde un peu sur la deuxième partie mais ce n'est pas grave, on va faire un menu très léger. On a 3 choix : un nombre entre 1 et 100 ; entre 1 et 500 et enfin entre 1 et 1000.
Le choix courant sera en rouge par exemple, et les autres seront écrits dans la couleur par défaut.
Bien sûr, il faudra créer une variable max qui sera affichée pour Entrez un nombre entre 1 et [...] inclus.
Le mieux est de créer 2 boucles (une pour le menu, l'autre pour le jeu).
Voilà, vous avez assez de renseignements pour le coder tout seul ^^ .
Mais voici mon amélioration ^^ :
Secret (cliquez pour afficher)
Code : C
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <PA9.h>

void defiler_clavier(int,int,int,int,int);

int main(int argc, char ** argv)
{
    int nombre,entre=0,i,compteur=0,max,menu=0;
    char lettre;

    PA_Init();

    PA_LoadDefaultText(1,0);
    PA_InitRand();

    //Boucle de menu
    while(!Pad.Held.A&&!Pad.Held.Start)
    {
        switch(menu)
        {
            case 0:
                PA_OutputText(1,5,9,"%c11 -> Entre 1 et 100");
                PA_OutputText(1,5,11,"2 -> Entre 1 et 500");
                PA_OutputText(1,5,13,"3 -> Entre 1 et 1000");
                break;
            case 1:
                PA_OutputText(1,5,9,"1 -> Entre 1 et 100");
                PA_OutputText(1,5,11,"%c12 -> Entre 1 et 500");
                PA_OutputText(1,5,13,"3 -> Entre 1 et 1000");
                break;
            default:
                PA_OutputText(1,5,9,"1 -> Entre 1 et 100");
                PA_OutputText(1,5,11,"2 -> Entre 1 et 500");
                PA_OutputText(1,5,13,"%c13 -> Entre 1 et 1000");
                break;
        }
        menu+=Pad.Newpress.Down-Pad.Newpress.Up;
        if(menu<0)
            menu=2;
        else if(menu>2)
            menu=0;
        PA_WaitForVBL();
        PA_ClearTextBg(1);
    }

    switch(menu)
    {
        case 0:
            nombre=PA_RandMinMax(1,100);
            max=100;
            break;
        case 1:
            nombre=PA_RandMinMax(1,500);
            max=500;
            break;
        default: //Il est bon de mettre un defalut, car si le choix n'est pas 3 (un bug ou alors un problème dans le code), une valeur est quand-même attribuée à nombre et à max. De plus, pour être désolé de ce problème, la valeur par défaut est celle comprise entre 1 et 1000 ! *rire sadique*
            nombre=PA_RandMinMax(1,1000);
            max=1000;
            break;
    }

    PA_InitKeyboard(2);
    defiler_clavier(50,48,25,96,1);

    //Boucle du jeu
    while(1)
    {
        PA_OutputText(1,0,0,"Entrez un nombre entre 1 et %d inclus :",max);
        lettre=PA_CheckKeyboard();
        if(lettre>='0'&&lettre<='9'&&entre<=max)
        {
            entre*=10;
            entre+=lettre-'0';
        }
        else if(lettre==PA_BACKSPACE)
            entre/=10;
        else if(lettre=='\n') 
        {
            compteur++;
            PA_ClearTextBg(1);
            if(entre<nombre)
            {
                PA_OutputText(1,0,0,"Le nombre %d est trop petit. Veuillez attendre 2 secondes...",entre);
                entre=0;
            }
            else if(entre>nombre)
            {
                PA_OutputText(1,0,0,"Le nombre %d est trop grand. Veuillez attendre 2 secondes...",entre);
                entre=0;
            }
            else
                break;
            for(i=0;i<120;i++)
                PA_WaitForVBL();
        }
        if(entre!=0)
            PA_OutputText(1,0,3,"%d",entre);
        PA_WaitForVBL();
        PA_ClearTextBg(1); //On efface l'écran supérieur
    }
    PA_OutputText(1,0,0,"Bravo ! Vous avez réussi à trouver le nombre %d en %d tentative%s !",entre,compteur-1,compteur-1<2?"":"s");
    PA_KeyboardOut(); //On range notre clavier

    while(1)
        PA_WaitForVBL();

    return 0;
}

void defiler_clavier(int x,int y,int x1,int y1,int nvbl)
{
    int i=0;
    PA_ScrollKeyboardXY(x,y);
    while(1)
    {
        if(x<x1)
            x++;
        else if(x>x1)
            x--;
        if(y<y1)
            y++;
        else if(y>y1)
            y--;
        if(x==x1&&y==y1)
            break;
        PA_ScrollKeyboardXY(x,y);
        for(i=0;i<nvbl;i++)
            PA_WaitForVBL();
    }
}
Voilà, vous avez assez de bases maintenant pour faire de petits jeux en console sur votre Nintendo DS !
Chapitre précédent Sommaire Chapitre suivant

Partager

10 commentaires pour "TP: Plus ou Moins, votre premier jeu"
Note moyenne : 3.57 / 4 (65 votes)
Pseudo Commentaire
Hors ligne Atbbkaugust # Posté le 05/09/2010 à 16:00:45
ceci est une citation
Avatar

Avis : Très bon

Ville : Saint geours de maremne
Pays : France métropolitaine

snake 48 t'est moin sympas que dans le tuto...puis la correction qui est pas bonne ça fait tout buger et c'est plus important que tu le prétent et même si ton message est vieu, je voulais te le dire!
 
Hors ligne snake_48 # Posté le 05/09/2010 à 16:40:05
Il me manque un bit.
Avatar

Études : INSA Lyon

Ok je modifierai ça, je ne vois pas où est le problème (rechercher "&amp;" remplacer par "&" sur toutes les occurrences). Et je ne vois pas non plus d'intérêt à me juger, moi j'active l'envoi de MP automatique lorsque je reçois un commentaire pour y répondre s'il est constructif sinon je ne sais pas quand on poste dedans. Il se trouve que beaucoup d'entre eux sont écrits sans recherche préalable (et puis cette écriture de kikoolol c'est vraiment désagréable). Combien d'entre eux aussi sont des problèmes alors qu'il est mentionné que c'est du domaine du forum ? Alors ici ceux qui ne sont pas sympa ce sont ceux qui font ça. Et puis je n'étais pas obligé non plus de rédiger ce tuto...
Prends-le pour toi aussi parce que tu ne postes pas au bon endroit (cf. plus bas) et que tes fautes me font mal aux yeux.
Nan mais qu'est-ce qu'on n'entend ne lit pas...

Edit : En cas de problème personnel, c'est un MP qu'il faut envoyer.

Edit1 (pour le post ci-dessous) : une remarque personnelle c'est par MP, donc je vais te répondre en utilisant ta boîte de MP (waaah c'est dur à comprendre).

Programmez sur votre Wii ! | Programmez sur votre Nintendo DS ! | Charger des fichiers .OBJ | Introduction au scripting avec Python
Création d'un moteur physique (en cours)
Code Lyoko Strategy Game Coder
Langages connus : AS3, Batch, C, C++, HTML, Java, Javascript, PHP, Python.
Programme sur : PC, Nintendo DS, Wii.
o----}=========>
 
Hors ligne Atbbkaugust # Posté le 05/09/2010 à 21:09:07
ceci est une citation
Avatar

Avis : Très bon

Ville : Saint geours de maremne
Pays : France métropolitaine

C'est fou comme les gens se donne une personnalité, tandis qu'en vrai il ne ressemble pas du tout a ça, ce que j'entent par là c'est que dans le tuto tu avais l'air sympas!

PS: j'aime bien le tuto!

Edit: quand on fait un tuto on le fait j'usqu au bout, c'est pour ça que j'ai été frustré de voir que tu ne prettait aucune attention a une erreur importante! maintenant tu peux pensez que je suis un emme***** ta le droit ^^
 
Hors ligne Tinei # Posté le 04/03/2012 à 16:36:06
...
Avatar

Bonjour, quand je lance build.bat ça bug:

Code : Erreur
1
2
3
4
5
main.c
c:/devkitPro/libnds/include/gbfs.h:1:2: error: #error gbfs is no longer supported on nds
c:/devkitPro/libnds/include/gbfs.h:1:2: error: #error gbfs is no longer supported on nds
make[1]: *** [main.o] Error 1
"make": *** [build] Error 2
Hors ligne Ghost_anon # Posté le 10/03/2012 à 17:15:02
Avatar

Avis : Bon

bon, ça commence à devenir intéressant!
vivement, la gestion d'image et du sons :p

++


Salut Tinei

vérifie ta version de DevKitarm et ta Palib , ça fonctionne bien avec le ARM r21 et palid 080823 et change aussi ton dossier libnds de devkitpro avec celui posté dans un topic qui est sur le forum! (t'as le lien dans les commentaires du chapitre "avant-propos")

j'ai remarqué que l'ordre d'installation est super important:

devkitpro, ensuite change ta version de devkitarm par la r 21, ensuite palib (direct dans le dossier car il se met à jour avec arm à la fin de la decompression) , ensuite libnds, et ça devrait être bon!

voilà, après pour les émules, c'est pas ce qui manque à toi de voir :)

++

Voir tous les commentaires