Pages: [1]   Bas de page
Imprimer
Auteur Fil de discussion: [wii/Tuto]Tutos Wii/GRRLIB - Plus ou Moins - Partie 1 : Les bases  (Lu 6825 fois)
0 Membres et 1 Invité sur ce fil de discussion.
EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« 24 Juin 2010, 15:53:37 »

Partie 1 : Les bases


Installation de GRRlib
Note : je développe sur Windows (jetez les tomates si vous voulez), donc je décris l'installation sur Windows. Pour les autres, si vous avez des remarques, je complèterai le tuto quand j'aurais les démarches pour Mac et Linusk.

Pour commencer ce tuto, faisons déjà un tour des outils dont nous avons besoin :
devkitpro (dl ici : http://sourceforge.net/projects/devkitpro/)
GRRlib (dl ici : http://code.google.com/p/grrlib/)

L'IDE qui sera utilisé pour ce tuto sera Programmer's Notepad (PN) qui est compris avec devkitpro.
Pour devkitpro, choisissez en priorité d'installer devkitPPC et bien sûr Programmer's Notepad (Le reste est pour d'autres plateformes comme la GBA et la NDS).
En ce qui concerne GRRlib, décompressez l'archive dans un dossier de votre choix, allez ensuite dans grrlib/libs/ et lancez install.bat qui copiera les librairies dont a besoin GRRlib pour fonctionner.
Ensuite il faut lancer une ligne de commande pour installer le moteur de GRRlib en lui-même :
allez dans /grrlib/grrlib/ (attention pas le dernier dossier grrlib de l'arborscence, arrêtez-vous à celui qui contient grrlib.h)
exécutez : make clean all install.
Voilà ! GRRlib est installé !

La dernière étape est de copier le dossier « template » présent dans grrlib/examples dans votre dossier de travail pour pouvoir commencer. Ici on renommera le projet en « plus_ou_moins » (avec v1, v2, … pour chaque partie).


Mon premier programme avec GRRlib
Bon on va commencer avec un pseudo "Hello World", mais on affichera plutôt le titre du jeu Azn

Tout d'abord, ouvrez votre projet plus_ou_moins_v1. Il ne doit contenir que les fichiers makefile et  main.c dans le dossier source.
Premièrement, pour vérifier que tout marche bien, on va compiler ce code. Sur PN, ça se fait avec Alt+& (la touche 1 en fait). Si vous avez des problèmes lors de la première compilation, envoyez-moi un MP, j'essaierai de vous aider, et je posterai une FAQ plus tard.
Ce programme devrait afficher un écran noir, et quitter lorsqu'on appuie sur la touche Home de la Wiimote n°1.


Tester son code
Pour tester son code, il y a 2 solutions :
L'émulateur Dolphin, mais les contrôles ne marchent pas correctement en mode Wii (si quelqu'un sait le faire marcher, je suis preneur)
Directement sur la HomBrew Channel (HBC) grâce à l'utilitaire WiiLoad ou par copie sur la SD (en direct ou par le homebrew FTPii), mais je recommende chaudement d'utiliser WiiLoad, très pratique.


Le code du template
Bon bon bon... On va regarder brièvement ce code pour comprendre ce qu'il fait.
Tout d'abord les #include :
  • #include <grrlib.h> : c'est le coeur de la librairie graphique GRRlib, indispensable pour l'affichage
  • #include <wiiuse/wpad.h> : c'est la librairie qui permet de prendre en charge la wiimote.

Ensuite les instruction dans la fonction main :
  • GRRLIB_Init() : c'est la commande qui initialise GRRlib, elle est indispensable au début de chaque programme tournant avec cette lib.
  • WPAD_Init() : c'est la commande qui initialise le gestionnaire de WiiMotes. Là pareil, à lancer systématiquement au début du programme.
  • WPAD_ScanPads() : Cette commande est à lancer à chaque boucle, elle met à jour l'état de chaque wiimote dans la mémoire.
  • if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) :
    Là, je vais devoir rentrer un peu plus dans le détail. WPAD_ButtonsDown est une fonction qui permet de connaitre l'état de chaque bouton de la wiimote sélectionnée (D-Pad, A, B, +, -, Home, 1, 2) et indique s'il viennent d'être pressés. Le paramètre (0) fait référence à la manette 1, les suivantes étant 1, 2 et 3 pour les manettes respectivement 2, 3, et 4.
    WPAD_BUTTON_HOME permet de récupérer uniquement la valeur pour le bouton Home grâce à l'opération & logique.
  • GRRLIB_Render() : à la fin de la boucle principale on utilise cette fonction pour générer l'affichage à l'écran.
  • GRRLIB_Exit() : permet de vider de la mémoire l'espace alloué par GRRlib.


Modifier ce code
Boucles infinies = caca
Alors ! Première modification, parce que je déteste les while(1), on va remplacer ce 1 par une variable bool qu'on aura déclaré juste au dessus :
Code:
bool finProgramme = false;
while (!finProgramme){

Ensuite il faudra modifier cette variable, lorsqu'on appuie sur Home, soit :
Code:
if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) finProgramme = true;


Ajouter du texte
Maintenant, on va afficher notre premier texte. Entre WPAD_ScanPads() et GRRLIB_Render(), c'est là qu'on va rajouter tout le code qui devra être exécuté à chaque frame. Pour afficher du texte, on rajoute ici :
Code:
GRRLIB_Printf(112, 16, texFont, CLR_WHITE, 2, "Super jeu de Plus ou Moins");

Cette fonction prend plusieurs paramètres, que je vais décrire maintenant :
  • 112 et 16 sont les coordonnées du début du texte (le coin en haut à gauche) 112 pour l'axe X et 16 pour l'axe Y.
  • texFont est la texture qui contient les caractères de notre police
  • CLR_WHITE est la couleur de notre texte
  • 2 est la taille du texte (1 pour la taille de base, ensuite c'est un grossissement de l'image)
  • ensuite le texte que l'on veut écrire

A ce moment du tuto, le code ne peut pas compiler. En effet, le programme n'a aucune idée de ce que peuvent être texFont et CLR_WHITE.

CLR_WHITE est une constante qu'il faut définir qui permet de simplifier la lecture des couleurs.
Pour l'utiliser, il suffit de rajouter en haut de votre document (juste après les lignes #include) :
Code:
#define CLR_WHITE 0xFFFFFFFF

Nous allons maintenant créer la variable texFont qui doit contenir la police de caractères.
Tout d'abord, nous avons besoin d'une image, font.png, que j'ai mis en pièce jointe de ce post das l'archive du projet. Nous allons la copier dans un dossier data qu'on va créer dans notre arborescence, à coté du dossier source. Pour que ce fichier soit pris en charge dans notre programme, nous allons rajouter un include en haut du document :
Code:
#include "font_png.h"
Explication rapide : les fichiers qui sont dans le dossier data sont transformés lors de la compilation, sont alors générées des variables contenant le contenu de ces fichiers. Ces nouveaux fichiers se nomment alors : "nomDuFichier_Extension.h".

Enfin la variable en elle-même, à rajouter dans la fonction main, juste avant la boucle principale :
Code:
GRRLIB_texImg * texFont = GRRLIB_LoadTexture(font_png);
GRRLIB_InitTileSet(texFont, 8, 16, 0);

Que font ces deux lignes ?
La première charge l'image font.png dans la variable texFont, en faisant d'elle une texture utilisable par GRRlib. Notez que la variable en paramètre est sans guillemets, c'est le nom de la variable créée lors de la compilation.
La seconde définit cette texture comme étant découpée en petite briques de 8x16, taille de chaque caractère de notre police.


Resultat
Et voilà ! Vous pouvez à présent compiler et vous aurez ça :


Et la tronche de votre main.c :
Code:
#include <grrlib.h>
#include <wiiuse/wpad.h>
#include <stdlib.h> // Nécessaire pour la fonction exit();

#include "font_png.h"
#define CLR_WHITE 0xFFFFFFFF

int main() {

// Initialiser le moteur graphique
GRRLIB_Init();

// Initialise the Wiimotes
WPAD_Init();

GRRLIB_texImg * texFont = GRRLIB_LoadTexture(font_png);
GRRLIB_InitTileSet(texFont, 8, 16, 0);

bool finProgramme = false;

while (!finProgramme){ // Boucle Principale

WPAD_ScanPads();  //On met à jour l'état des wiimotes

// pour sortir de la boucle principale
if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) finProgramme = true;


GRRLIB_Printf(112, 16, texFont, CLR_WHITE, 2, "Super jeu de Plus ou Moins");

GRRLIB_Render();

}

// Vider la mémoire occupée par GRRlib
GRRLIB_Exit();

exit(0);
}


Et si on faisait un jeu maintenant ?


Le concept

C'est parti mon kiki ! (ouais je suis né dans les années 80, c'est bon on a compris)
On va commencer par parler de la logique de ce programme. Il est simple, mais encore faut-il ne pas faire n'importe quoi.

Comment se présentera l'écran grâce à un ASCII Art magnifique :
---------------------------------------------------------------
|                                                             |
|                                                             |
|                                                             |
|                  Super jeu de Plus ou Moins                 |
|                                                             |
|                                                             |
|                                                             |
|                                                             |
|                     /\      /\      /\                      |
|                                                             |
|                     0       0       0                       |
|                                                             |
|                     \/      \/      \/                      |
|                                                             |
|                                                             |
|                          --------                           |
|                          |  OK  |                           |
|                          --------                           |
|                                                             |
|                                                             |
|                 ( MESSAGE SELON RESULTAT )                  |
|                                                             |
|                                                             |
|                                                             |
---------------------------------------------------------------


En cliquant sur les flèches on augmentera ou diminuera la valeur de chaque chiffre, en cliquant sur OK, on calcule le nombre ainsi créé qu'on compare au nombre à trouver. Si c'est supérieur on indiquera "plus petit", si c'est inférieur on indiquera "plus grand" et si c'est égal, on indiquera "Yeah ! Rock'N Roll !".

Voilà les données dont nous aurons besoin pour faire avancer le bousin :
  • nombreATrouver
  • chiffre1, chiffre2, chiffre3 (dans cet ordre : 1 pour unités, 2 pour dizaines, 3 pour centaines)
  • nombrePropose (calculé d'après chiffres 1->3)
  • positionCurseur
  • coordonnées des différents boutons :
    • plusChiffre1
    • plusChiffre2
    • plusChiffre3
    • moinsChiffre1
    • moinsChiffre2
    • moinsChiffre3
    • boutonOK


Initialiser et afficher le pointeur de la WiiMote
J'aurais pu commencer par faire modifier les valeurs en fonction de l'appui sur certaines touches mais, bordel de Zeus, on est sur Wii et on a un pointeur alors on va s'en servir !

Ça peut paraître curieux, mais le capteur infrarouge de la WiiMote n'est pas géré par la même structure de donnée que les boutons. Pour chacune de ces fonctionnalités, il va falloir faire appel à une structure différente, que ce soit pour le capteur infra-rouge ou une extension comme le Nunchuk.

Pour initialiser la gestion du capteur, voilà ce qu'il faut rajouter après WPAD_Init() :
Code:
static GXRModeObj *rmode = NULL;
rmode = VIDEO_GetPreferredMode(NULL);

WPAD_SetVRes(WPAD_CHAN_ALL,rmode->fbWidth,rmode->xfbHeight);
WPAD_SetDataFormat(WPAD_CHAN_0,WPAD_FMT_BTNS_ACC_IR);

ir_t pointeurIR;

Je ne vais pas expliquer en détails toutes ces lignes, ce qu'il faut savoir :
La ligne WPAD_SetDataFormat(WPAD_CHAN_0,WPAD_FMT_BTNS_ACC_IR); permet de définir le format des données pour une wiimote. Si vous voulez en gérer plusieurs, il faut ajouter une ligne par wiimote en modifiant WPAD_CHAN_X (X = 0, 1, 2, 3) ou une seule avec  WPAD_CHAN_ALL pour toutes les WiiMotes.

La structure ir_t pointeurIR est une structure qui contiendra les coordonnées à l'écran de notre pointeur (ainsi que d'autres information dont nous n'aurons pas besoin).

Afin de mettre à jour cette variable pointeurIR il faut ajouter dans la boucle principale sous WPAD_ScanPads() cette commande :
Code:
WPAD_IR(WPAD_CHAN_0, &pointeurIR);
Ainsi, à chaque boucle, la variable pointeurIR recevra les données à jour concernant l'état de la wiimote.

Maintenant nous allons afficher un pointeur. L'image qui est dans l'archive en pièce jointe est pointer.png, à copier dans data et à inclure au programme avec #include "pointer_png.h".
Petite variante lors de son initialisation (à ajouter sous l'init de texFont) :
Code:
GRRLIB_texImg * texPointer = GRRLIB_LoadTexture(pointer_png);
GRRLIB_SetMidHandle(texPointer, true);
La fonction GRRLIB_SetMidHandle permet de définir la position d'un sprite non pas par son coin supérieur gauche, mais par son centre. Dans le cas de cette texture, c'est d'autant plus pratique qu'elle a été conçue de sorte que le bout du doigt soit au centre de l'image. Cette fonction permet également de gérer la rotation d'un sprite par son centre.

Le pointeur étant le sprite qui doit toujours être au premier plan à l'écran, nous allons écrire la commande pour l'afficher juste avant GRRLIB_Render() :
Code:
GRRLIB_DrawImg(pointeurIR.x, pointeurIR.y, texPointer, 0, 1, 1, CLR_WHITE);
Cette fonction permet d'afficher une texture à l'écran, voici les paramètres qui la composent:
  • pointeurIR.x et pointeurIR.y sont bien sûr les coordonnées à l'écran
  • texPointer est la texture à afficher
  • 0 représente l'angle de rotation du sprite (ici il est droit donc 0)
  • les deux 1 suivant représentent la modification de l'échelle sur X et Y, ici pas de déformation, donc 1 et 1.
  • Pour réduire la taille de la texture, on utilise une valeur inférieure à 1, et supérieure à 1 pour grossir.
  • CLR_WHITE est la couleur que l'on applique à la texture. Le blanc permet d'afficher la texture normalement. On peut utiliser d'autres couleurs pour teinter, assombrir ou rendre transparente une texture.

Ici on a indiqué comme coordonnées du sprite les valeurs récupérés dans la variable pointeurIR.
Voilà ! Le pointeur s'affiche désormais Smiley

Précision sur la notion de "Sprite"
Un sprite est normalement un objet graphique composé de différentes données comme la position, la rotation, l'échelle, la texture, etc. et est présent une fois à l'écran et on peut avoir plusieurs sprites utilisant la même texture. Dans le cas GRRlib et plus particulièrement de la structure GRRLIB_texImg, il s'agit plutôt de textures que l'on "imprime" à l'écran que vraiment de sprites.



L'affichage
Il est l'heure de créer toutes les variables nécessaires au fonctionnement du jeu.
Dans la fonction main, nous allons ajouter ces lignes :
Code:
int chiffre1 = 0, chiffre2 = 0, chiffre3 = 0;
int nombreATrouver = 56; //chiffre au pif
int nombrePropose = 0;
int numMessage = 0;
Le nom de ces variables sont suffisamment explicites pour que je me passe de décrire ce qu'elles contiennent Tongue

Ensuite nous allons créer une structure servant à contenir les coordonnées et tailles des différents boutons. Au dessus de la fonction main, rajouter :
Code:
typedef struct{
int x, y; //coordonnées
int w, h; //dimensions : w = Width = Largeur, h = Height = Hauteur
} Bouton;

On rajoute ensuite ces lignes à la suite des précédentes déclarations de variables :
Code:
Bouton plusChiffre1,  plusChiffre2,  plusChiffre3;
Bouton moinsChiffre1,  moinsChiffre2,  moinsChiffre3;
Bouton boutonOK;

On va maintenant remplir ces variables ! Bon faites moi confiance pour les valeurs des positions et tailles, vous pourrez vous amuser à la modifier à votre gré. Je commence par le chiffre3 en allant vers le 1 pour la bonne raison que, comme dit plus haut, le chiffre 1 représente les unités et sera donc à droite. On ajoute ces lignes sous la déclaration des variables, avant la boucle principale :
Code:
plusChiffre3.x = 208; plusChiffre3.y = 152;
plusChiffre3.w = 64; plusChiffre3.h = 32;

plusChiffre2.x = 288; plusChiffre2.y = 152;
plusChiffre2.w = 64; plusChiffre2.h = 32;

plusChiffre1.x = 364; plusChiffre1.y = 152;
plusChiffre1.w = 64; plusChiffre1.h = 32;

moinsChiffre3.x = 208; moinsChiffre3.y = 256;
moinsChiffre3.w = 64; moinsChiffre3.h = 32;

moinsChiffre2.x = 288; moinsChiffre2.y = 256;
moinsChiffre2.w = 64; moinsChiffre2.h = 32;

moinsChiffre1.x = 364; moinsChiffre1.y = 256;
moinsChiffre1.w = 64; moinsChiffre1.h = 32;

boutonOK.x = 256; boutonOK.y = 320;
boutonOK.w = 128; boutonOK.h = 80;

Je suis conscient qu'il y a des moyens plus propres de faire ça, notamment avec des tableaux, mais pour ce tuto, je préfère avoir des noms de variables évidents. Le passage aux tableaux se fera lors de la partie 2.

Pour chaque bouton, nous allons afficher un rectangle contenant le symbole + ou -, et bien sûr OK pour le bouton de validation.

Maintenant pour l'affichage de chaque bouton, nous allons utiliser une nouvelle fonction de GRRlib : GRRLIB_Rectangle(x, y, w, h, color, filled). Ces paramètres sont :
x et y : coordonnées
w et h : dimensions
color : duh, la couleur
filled : rectangle plein (1) ou seulement ses contours (0).

Pour afficher le texte par dessus ces boutons blancs, nous allons ajouter une nouvelle couleur en haut du document :
Code:
#define CLR_BLACK 0x000000FF

Écrire ce qui suit au dessus de l'affichage du pointeur :
Code:
//Affichage des textes et boutons
GRRLIB_Rectangle(plusChiffre3.x,  plusChiffre3.y, plusChiffre3.w,  plusChiffre3.h, CLR_WHITE, 1);
GRRLIB_Rectangle(plusChiffre2.x,  plusChiffre2.y, plusChiffre2.w,  plusChiffre2.h, CLR_WHITE, 1);
GRRLIB_Rectangle(plusChiffre1.x,  plusChiffre1.y, plusChiffre1.w,  plusChiffre1.h, CLR_WHITE, 1);

GRRLIB_Rectangle(moinsChiffre3.x,  moinsChiffre3.y, moinsChiffre3.w,  moinsChiffre3.h, CLR_WHITE, 1);
GRRLIB_Rectangle(moinsChiffre2.x,  moinsChiffre2.y, moinsChiffre2.w,  moinsChiffre2.h, CLR_WHITE, 1);
GRRLIB_Rectangle(moinsChiffre1.x,  moinsChiffre1.y, moinsChiffre1.w,  moinsChiffre1.h, CLR_WHITE, 1);

GRRLIB_Rectangle(boutonOK.x,  boutonOK.y, boutonOK.w,  boutonOK.h, CLR_WHITE, 1);

Et écrire le texte par dessus grâce aux instructions suivantes :
GRRLIB_Printf(plusChiffre3.x + 24, plusChiffre3.y + 4, texFont, CLR_BLACK, 2, "+");
GRRLIB_Printf(plusChiffre2.x + 24, plusChiffre2.y + 4, texFont, CLR_BLACK, 2, "+");
GRRLIB_Printf(plusChiffre1.x + 24, plusChiffre1.y + 4, texFont, CLR_BLACK, 2, "+");

GRRLIB_Printf(moinsChiffre3.x + 24, moinsChiffre3.y + 4, texFont, CLR_BLACK, 2, "-");
GRRLIB_Printf(moinsChiffre2.x + 24, moinsChiffre2.y + 4, texFont, CLR_BLACK, 2, "-");
GRRLIB_Printf(moinsChiffre1.x + 24, moinsChiffre1.y + 4, texFont, CLR_BLACK, 2, "-");

GRRLIB_Printf(boutonOK.x + 48, boutonOK.y + 28, texFont, CLR_BLACK, 2, "OK");

Il ne reste plus qu'à afficher les 3 chiffres selon leur valeur. Pour ce faire, nous allons utiliser une particularité de la fonction GRRLIB_Printf(...) qui permet d'ajouter de nouveaux paramètres pour spécifier des variables à afficher dans notre chaine de caractères.
Par exemple pour afficher les chiffres 1 et 2, il suffit de faire :
Code:
GRRLIB_Printf(0, 0, texFont, CLR_WHITE, 1, "%d%d", chiffre1, chiffre2);
Les caractères "%d" seront remplacés par des entiers dans leur ordre dans la liste des paramètres supplémentaires. Pour afficher du texte, il faut utiliser "%s", pour un nombre décimal c'est "%f".

Pour afficher nos 3 nombres, nous allons donc écrire :
Code:
GRRLIB_Printf(224, 200, texFont, CLR_WHITE, 4, "%d", chiffre3);
GRRLIB_Printf(304, 200, texFont, CLR_WHITE, 4, "%d", chiffre2);
GRRLIB_Printf(384, 200, texFont, CLR_WHITE, 4, "%d", chiffre1);

Ayé ! Notre interface est quasiment complète.
Ça devrait donner ça chez vous :



Gestion des boutons
Maintenant, votre code devrait ressembler à ça :
Code:
#include <grrlib.h>
#include <wiiuse/wpad.h>
#include <stdlib.h>

#include "font_png.h"
#include "pointer_png.h"

#define CLR_WHITE 0xFFFFFFFF
#define CLR_BLACK 0x000000FF

typedef struct{
int x, y; //coordonnées
int w, h; //dimensions : w = Width = Largeur, h = Height = Hauteur
} Bouton;


int main() {

// Initialiser le moteur graphique
GRRLIB_Init();

// Initialiser les Wiimotes
WPAD_Init();
static GXRModeObj *rmode = NULL;
rmode = VIDEO_GetPreferredMode(NULL);

WPAD_SetVRes(WPAD_CHAN_ALL,rmode->fbWidth,rmode->xfbHeight);
WPAD_SetDataFormat(WPAD_CHAN_0,WPAD_FMT_BTNS_ACC_IR);

ir_t pointeurIR;

GRRLIB_texImg * texFont = GRRLIB_LoadTexture(font_png);
GRRLIB_InitTileSet(texFont, 8, 16, 0);

GRRLIB_texImg * texPointer = GRRLIB_LoadTexture(pointer_png);
GRRLIB_SetMidHandle(texPointer, true);

bool finProgramme = false;

int chiffre1 = 0, chiffre2 = 0, chiffre3 = 0;
int nombreATrouver = 56;
int nombrePropose = 0;
int numMessage = 0;

Bouton plusChiffre1,  plusChiffre2,  plusChiffre3;
Bouton moinsChiffre1,  moinsChiffre2,  moinsChiffre3;
Bouton boutonOK;

plusChiffre3.x = 208; plusChiffre3.y = 152;
plusChiffre3.w = 64; plusChiffre3.h = 32;

plusChiffre2.x = 288; plusChiffre2.y = 152;
plusChiffre2.w = 64; plusChiffre2.h = 32;

plusChiffre1.x = 364; plusChiffre1.y = 152;
plusChiffre1.w = 64; plusChiffre1.h = 32;

moinsChiffre3.x = 208; moinsChiffre3.y = 256;
moinsChiffre3.w = 64; moinsChiffre3.h = 32;

moinsChiffre2.x = 288; moinsChiffre2.y = 256;
moinsChiffre2.w = 64; moinsChiffre2.h = 32;

moinsChiffre1.x = 364; moinsChiffre1.y = 256;
moinsChiffre1.w = 64; moinsChiffre1.h = 32;

boutonOK.x = 256; boutonOK.y = 320;
boutonOK.w = 128; boutonOK.h = 80;

while (!finProgramme){ // Boucle Principale

WPAD_ScanPads();  //On met à jour l'état des wiimotes
WPAD_IR(WPAD_CHAN_0, &pointeurIR); //met à jour le capteur InfraRouge


if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) finProgramme = true; // on quitte la boucle principale

/*--------------------------------------------------
C'est ici qu'on fera les modifications sur les variables
en fonction des données de la wiimote
--------------------------------------------------*/

GRRLIB_Printf(112, 16, texFont, CLR_WHITE, 2, "Super jeu de Plus ou Moins");

//Affichage des textes et boutons
GRRLIB_Rectangle(plusChiffre3.x,  plusChiffre3.y, plusChiffre3.w,  plusChiffre3.h, CLR_WHITE, 1);
GRRLIB_Rectangle(plusChiffre2.x,  plusChiffre2.y, plusChiffre2.w,  plusChiffre2.h, CLR_WHITE, 1);
GRRLIB_Rectangle(plusChiffre1.x,  plusChiffre1.y, plusChiffre1.w,  plusChiffre1.h, CLR_WHITE, 1);

GRRLIB_Rectangle(moinsChiffre3.x,  moinsChiffre3.y, moinsChiffre3.w,  moinsChiffre3.h, CLR_WHITE, 1);
GRRLIB_Rectangle(moinsChiffre2.x,  moinsChiffre2.y, moinsChiffre2.w,  moinsChiffre2.h, CLR_WHITE, 1);
GRRLIB_Rectangle(moinsChiffre1.x,  moinsChiffre1.y, moinsChiffre1.w,  moinsChiffre1.h, CLR_WHITE, 1);

GRRLIB_Rectangle(boutonOK.x,  boutonOK.y, boutonOK.w,  boutonOK.h, CLR_WHITE, 1);

GRRLIB_Printf(plusChiffre3.x + 24, plusChiffre3.y + 4, texFont, CLR_BLACK, 2, "+");
GRRLIB_Printf(plusChiffre2.x + 24, plusChiffre2.y + 4, texFont, CLR_BLACK, 2, "+");
GRRLIB_Printf(plusChiffre1.x + 24, plusChiffre1.y + 4, texFont, CLR_BLACK, 2, "+");

GRRLIB_Printf(moinsChiffre3.x + 24, moinsChiffre3.y + 4, texFont, CLR_BLACK, 2, "-");
GRRLIB_Printf(moinsChiffre2.x + 24, moinsChiffre2.y + 4, texFont, CLR_BLACK, 2, "-");
GRRLIB_Printf(moinsChiffre1.x + 24, moinsChiffre1.y + 4, texFont, CLR_BLACK, 2, "-");

GRRLIB_Printf(boutonOK.x + 48, boutonOK.y + 28, texFont, CLR_BLACK, 2, "OK");

GRRLIB_Printf(224, 200, texFont, CLR_WHITE, 4, "%d", chiffre3);
GRRLIB_Printf(304, 200, texFont, CLR_WHITE, 4, "%d", chiffre2);
GRRLIB_Printf(384, 200, texFont, CLR_WHITE, 4, "%d", chiffre1);

//Affichage du pointeur
GRRLIB_DrawImg(pointeurIR.x, pointeurIR.y, texPointer, 0, 1, 1, CLR_WHITE);

GRRLIB_Render();

}

// Vider la mémoire occupée par GRRlib
GRRLIB_Exit();

exit(0);
}

Dans la zone désignée dans le code ci-dessus, il y a un espace que j'ai désigné comme étant celui où ferait les nouvelles modifications. Avant d'y mettre les doigts, nous allons créer une fonction qui dira si des coordonnées sont comprises dans un rectangle ou pas. Elle aura pour but final de dire si le pointeur est situé ou pas sur un des boutons.

Au dessus de la fonction main(),  écrire :
Code:
bool PtrSurBouton(int x, int y, Bouton btn);

et sous la fonction main():
Code:
bool PtrSurBouton(int x, int y, Bouton btn){
return (x > btn.x && x <  btn.x + btn.w && y > btn.y && y < btn.y + btn.h);
}
Cette fonction est relativement simple et va nous éclaircir un peu le code principal. Revenons-y d'ailleurs. Dans la fameuse zone à modifier il va falloir tester si d'une part, le bouton A a été pressé, et si en plus le pointeur était au dessus d'un bouton à ce moment-là.

Nous avons déjà vu comment récupérer l'appui d'un bouton avec Home. Pour le bouton A, nous devons utiliser la valeur WPAD_BUTTON_A.
Rajoutons maintenant :
Code:
if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A){

if (PtrSurBouton(pointeurIR.x, pointeurIR.y, plusChiffre3)){
chiffre3++;
}else if (PtrSurBouton(pointeurIR.x, pointeurIR.y, plusChiffre2)){
chiffre2++;
}else if (PtrSurBouton(pointeurIR.x, pointeurIR.y, plusChiffre1)){
chiffre1++;
}else if (PtrSurBouton(pointeurIR.x, pointeurIR.y, moinsChiffre3)){
chiffre3--;
}else if (PtrSurBouton(pointeurIR.x, pointeurIR.y, moinsChiffre2)){
chiffre2--;
}else if (PtrSurBouton(pointeurIR.x, pointeurIR.y, moinsChiffre1)){
chiffre1--;
}else if(PtrSurBouton(pointeurIR.x, pointeurIR.y, boutonOK)){

//calcul de nombrePropose en fonction des chiffres

//comparaison de ce nombre à nombreATrouver


}

//Rotation des valeurs
if (chiffre1 > 9) chiffre1 = 0; if (chiffre1 < 0) chiffre1 = 9;
if (chiffre2 > 9) chiffre2 = 0; if (chiffre2 < 0) chiffre2 = 9;
if (chiffre3 > 9) chiffre3 = 0; if (chiffre3 < 0) chiffre3 = 9;
}

Nous avons donc de quoi modifier les valeurs des chiffres. Afin que les valeurs passent de 9 à 0 en augmentant, et de 0 à 9 en diminuant, j'ai rajouté les dernières lignes nommées rotation des valeurs.
Maintenant passons au contenu de la dernière condition :
Code:
nombrePropose = chiffre1 + chiffre2 * 10 + chiffre3 * 100;

Reste maintenant à le comparer à la valeur mystère soit la variable nombreATrouver.
Selon le résultat de cette comparaison, il faudra afficher un message à l'écran. Nous allons donc définir 4 constantes pour afficher un des messages.

Retournez en haut du document et ajoutez :
Code:
#define MSG_AUCUN 0
#define MSG_PETIT 1
#define MSG_GRAND 2
#define MSG_GAGNE 3

Revenez maintenant à la ligne précédente et ajoutez dessous :
Code:
if (nombrePropose == nombreATrouver){
numMessage = MSG_GAGNE;
}else if (nombrePropose > nombreATrouver){
numMessage = MSG_PETIT;
}else{
numMessage = MSG_GRAND;
}

Afin de supprimer ce message après un nouveau clic, ajoutez sous if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A){ :
Code:
numMessage = MSG_AUCUN;

Il ne reste plus qu'à afficher le message. Allez juste au dessus l'affichage du pointeur et ajoutez :
Code:
switch(numMessage){
case MSG_PETIT:
GRRLIB_Printf(240, 400, texFont, CLR_WHITE, 2, "Plus petit");
break;
case MSG_GRAND:
GRRLIB_Printf(240, 400, texFont, CLR_WHITE, 2, "Plus grand");
break;
case MSG_GAGNE:
GRRLIB_Printf(152, 400, texFont, CLR_WHITE, 2, "Yeah ! Rock N' Roll !");
break;
case MSG_AUCUN:
default:
break;
}


Pour finir
Le jeu est quasiment terminé !! Il manque cependant 2 choses :
  • la génération d'un nombre aléatoire
  • le reset de la partie en cas de victoire (bah oui... ou alors faut redémarrer la console à chaque partie :/ )

Pour ce qui est de la génération du nombre aléatoire, il va falloir rajouter quelques lignes de code.
D'abord un include en haut du document :
Code:
#include <time.h>
Puis juste avant la déclaration des différentes variables avant la boucle principale rajoutez :
Code:
srand(time(NULL));

Cela va permettre de rendre vraiment aléatoire la génération du nombre à trouver, sinon les séquences de chiffres seront toujours les mêmes d'une partie à l'autre.

Ensuite remplacez nombreATrouver = 56; par :
Code:
nombreATrouver = (rand() % 999) + 1;
Cela va générer un nombre situé entre 0 et 998, en ajoutant 1 on retrouve bien 1 et 999.

Pour finir, le redémarrage de la partie en cas de victoire. Dans la condition qui compare nombrePropose à nombreATrouver, sous numMessage = MSG_GAGNE; ajoutez :
Code:
chiffre1 = chiffre2 = chiffre3 = 0;
nombreATrouver = (rand() % 999) + 1;


Voilà … ouf ! Ce long tuto est terminé !

Vous pouvez retrouver le code complet de ce tuto en pièce jointe de cet article.
Pour toute erreur, faute, amélioration de ce tuto merci de l'écrire là dessous.

La prochaine partie montrera comment améliorer le code en passant en objet, et j'intégrai des super graphismes made in Pyroh !
Petite image pour donner de l'appétit :


A plouche !


Edit : Petit oubli dans l'archive je la mets à jour ici :
http://www.eviltroopa.com/wii/eviltroopa_tuto_plus_ou_moins.rar
parce que je ne peux pas éditer mes pièces jointes Sad


* pom_screen1.png (17.45 Ko, 582x437 - vu 2004 fois.)

* pom_screen2.png (33.31 Ko, 582x437 - vu 1912 fois.)

* pom_screen3.png (36.96 Ko, 640x480 - vu 2102 fois.)
* eviltroopa_tuto_plus_ou_moins.rar (14.89 Ko - Téléchargé 659 fois.)
« Dernière édition: 21 Février 2011, 15:33:14 par EvilTroopa » Journalisée

A mushroom a day, keeps the koopas away.
Zipler Hors ligne
Full Member
***
Messages: 106


Voir le profil
« Réponse #1 : 24 Juin 2010, 18:07:09 »

Bon tuto, ça fait plaisir  Cheesy !

Y'a des petits points sur lesquels je voudrais chipoter cependant:
- pourquoi mettre GXRModeObj *rmode en static ?
- pour la rotation de 0 à 9, ça peut se faire super facilement en utilisant des unsigned et en faisant un modulo 10 à chaque boucle (cela éliminera toutes les conditions)
- pourquoi ne pas choisir le nombre aléatoirement?

Peut-être que c'est pour pas déranger trop les débutants ou tu as peut-être d'autres raisons?
Journalisée
EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« Réponse #2 : 30 Juin 2010, 00:24:34 »

Bon tuto, ça fait plaisir  Cheesy !
Merci Cheesy

- pourquoi mettre GXRModeObj *rmode en static ?
Je sais plus, ça vient sûrement d'un copier/coller. Si ça marche bien sans, je le virerai.

- pour la rotation de 0 à 9, ça peut se faire super facilement en utilisant des unsigned et en faisant un modulo 10 à chaque boucle (cela éliminera toutes les conditions)
Comme tu l'as bien supposé en fin de commentaire, c'est pour que ce soit simple. Et puis modulo c'est lent Langue

- pourquoi ne pas choisir le nombre aléatoirement?
C'est le cas ! Mais je l'ai ajouté seulement à la fin du tuto (la section "Pour finir"), fallait lire jusqu'au bout petit canaillou Azn
Journalisée

A mushroom a day, keeps the koopas away.
Zipler Hors ligne
Full Member
***
Messages: 106


Voir le profil
« Réponse #3 : 30 Juin 2010, 10:33:05 »

Un modulo (division) est bien plus rapide qu'une comparaison + jump + affectation non?

C'est la faute à la belle image, elle m'a fait tourner l'oeil  laugh .
Journalisée
morukutsu Hors ligne
Hero Member
*****
Messages: 500


Voir le profil
Noctambule

« Réponse #4 : 30 Juin 2010, 10:55:14 »

Non le modulo est plus lent que ces 3 opérations Langue
Journalisée
radhan Hors ligne
Newbie
*
Messages: 30


Voir le profil
« Réponse #5 : 01 Juillet 2010, 09:22:27 »

cool le tuto en esperant que ça attire de futur nouveaux dev sur wii  Wink

moi j'attend avec impatience qu'un tuto sur la MLlib arrive Grin
« Dernière édition: 01 Juillet 2010, 09:26:37 par radhan » Journalisée
EvilTroopa Hors ligne
Administrateur
*****
Messages: 649


Voir le profil WWW
1010011010 the Number of the Beast

« Réponse #6 : 01 Juillet 2010, 09:53:54 »

moi j'attend avec impatience qu'un tuto sur la MLlib arrive Grin
Y'en a aussi un en préparation Wink
Journalisée

A mushroom a day, keeps the koopas away.
radhan Hors ligne
Newbie
*
Messages: 30


Voir le profil
« Réponse #7 : 01 Juillet 2010, 11:00:52 »

oh ! yeah ! pressé de le voir (meme si dans deux jours j'ai pu internet whistle ) Azn
Journalisée
Cid2Mizard Hors ligne
Super Mega Member
****
Messages: 4080


Voir le profil WWW
Disciple Kukulcanien

« Réponse #8 : 22 Juillet 2010, 18:31:59 »

C'est pas obsolète cette histoire d'installation de GRRLIB :

Citation
En ce qui concerne GRRlib, décompressez l'archive dans un dossier de votre choix, allez ensuite dans grrlib/libs/ et lancez install.bat qui copiera les librairies dont a besoin GRRlib pour fonctionner.
Ensuite il faut lancer une ligne de commande pour installer le moteur de GRRlib en lui-même :
allez dans /grrlib/grrlib/ (attention pas le dernier dossier grrlib de l'arborscence, arrêtez-vous à celui qui contient grrlib.h)
exécutez : make clean all install.
Voilà ! GRRlib est installé !

Il n'y a aucun .bat dedans !!! Du coup ça compile pas chez moi :/

Edit: ah c'est bon, il faut tout se taper en ligne de commandes Azn
« Dernière édition: 22 Juillet 2010, 19:37:13 par Cid2Mizard » Journalisée

Ludo6431 Hors ligne
Administrateur
*****
Messages: 903


Voir le profil WWW
It flies !

« Réponse #9 : 22 Juillet 2010, 22:26:19 »

... ou créer un .bat avec "make clean all install" dedans.
Journalisée

Mon matériel : DS Lite blanche flashée v8 | DSi noire | SCLite | SCDS ONE v2 | SCDS TWO | DSerial EDGE | MK-R6 gold | rumble pack | R4(r4ds.cn) | M3i Zero | Acekard 2i | iTouch DS | CycloPS' iEvolution
Pages: [1]   Haut de page
Imprimer

Aller à: