La base était facile, nous allons donc nous attaquer à la pratique

!
Coloration du passage du stylet
Nous allons coder un programme qui colore le passage du stylet sur l'écran !
Si vous ne vous souvenez plus du stylet (ce dont je doute

), vous pouvez à tout moment retourner au chapitre sur les événements...
Petite fantaisie : le dessin sera sur les deux écrans !
Mais comment on va faire ? Les deux écrans ne sont pas tactiles !

Le joueur va dessiner sur l'écran tactile, et le dessin sera reproduit sur l'écran supérieur.
Correction
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 | #include <PA9.h>
int main(int argc, char ** argv)
{
PA_Init();
PA_InitVBL();
PA_Init16bitBg(0,0);
PA_Init16bitBg(1,0);
while(1)
{
PA_WaitFor(Stylus.Newpress||Stylus.Held); //On attend un nouvel appui du stylet ou un maintient de celui-ci sur l'écran tactile
PA_Put16bitPixel(0,Stylus.X,Stylus.Y,PA_RGB8(255,0,0)); //On dessine le pixel sur l'écran tactile
PA_Put16bitPixel(1,Stylus.X,Stylus.Y,PA_RGB8(0,255,255)); //On dessine le pixel sur l'écran supérieur
PA_WaitForVBL();
}
return 0;
}
|
Vous avez vu que le tracé est saccadé, il serait donc mieux d'utiliser des lignes.
Il faut utiliser un compteur, attendre un événement du stylet et bien sûr tracer des lignes

.
Correction
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 | #include <PA9.h>
int main(int argc, char ** argv)
{
int i=0;
s16 x1=0,y1=0,styletX=0,styletY=0;
PA_Init();
PA_InitVBL();
PA_Init16bitBg(0,0);
PA_Init16bitBg(1,0);
while(1)
{
PA_WaitFor(Stylus.Newpress||Stylus.Held);
styletX=Stylus.X;
styletY=Stylus.Y;
if(i==1)
{
x1=styletX;
y1=styletY;
}
else
{
PA_Draw16bitLine(0,x1,y1,styletX,styletY,PA_RGB8(255,0,0));
PA_Draw16bitLine(1,x1,y1,styletX,styletY,PA_RGB8(0,255,255));
x1=styletX;
y1=styletY;
}
i++;
if(i>2)
i=2; // Permet d'éviter que i prenne une valeur trop importante
PA_WaitForVBL();
}
return 0;
}
|
Bon, je suis sûr que vous allez me détester, mais il existe une fonction toute faite et meilleure que la nôtre pour le faire :
void PA_16bitDraw (u8 ecran,u16 couleur)
. Ce n'est pas grave, c'est le
besoin d'accomplissement personnel de la pyramide de Maslow qui vient de se combler

.
Dessiner des cercles
De cette définition (ainsi que de la représentation graphique qui en découle), on peut se dire qu'on ne travaillera que sur un quart, et qu'on reportera les pixels sur les trois autres par miroir. Je travaille toujours sur le quart en haut à gauche, mais vous pouvez en choisir un autre

.
Vous le savez peut-être déjà, dans un repère orthonormé (ce qui est le cas des écrans de votre Nintendo DS), l'équation du cercle de centre

et de rayon

est

.
On va exprimer

en fonction de

(on peut faire l'inverse aussi

).
Donc nous avons :

Donc

et

.
On peut donc dire que

et

.
Mais vu que l'on ne travaillera que sur le côté gauche, nous ne retiendrons que

.
Ne vous arrêtez pas à la racine carrée, je sais que la racine carrée est une opération lourde, mais la technique employée est légère. En effet, pour un cercle de 100 pixels de diamètre, il n'y a que 50 tours de boucles contenant chacune 2 racines carrées, soit 100 racines carrées. De plus, j'ai testé le fps, il reste à 60 donc on ne peut pas dire que ça prenne beaucoup de CPU...
Comme on l'a fait dans l'exercice de la coloration du passage du stylet, il faudra utiliser les lignes et non les points.
Voici ce que le programme doit faire : par défaut, le centre du cercle doit être au centre de l'écran, et son rayon doit être de 100 px. En appuyant sur L, le rayon doit être augmenté de 1 px ; sur R, le rayon doit être diminué de 1 px ; et sur les touches multidirectionnelles, le centre doit se déplacer dans la direction voulue de 1 px. Bien sûr, à chaque fois que vous appuyez sur ces touches, l'écran doit être effacé. Le cercle
ne doit pas dépasser de l'écran, sinon vous aurez une belle surprise

...
Je vous laisse coder

.
Correction
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 | #include <PA9.h>
#include <math.h>
#define LARGEUR_ECRAN 255
#define HAUTEUR_ECRAN 191
typedef struct
{
int x,y;
}Point;
void dessiner_cercle(Point,int);
int main(int argc, char ** argv)
{
Point centre;
centre.x=LARGEUR_ECRAN/2;
centre.y=HAUTEUR_ECRAN/2;
int rayon=50;
PA_Init();
PA_InitVBL();
PA_Init16bitBg(0,0);
while(1)
{
if(Pad.Held.L)
{
rayon++;
PA_Clear16bitBg(0);
}
if(Pad.Held.R)
{
rayon--;
PA_Clear16bitBg(0);
}
if(Pad.Held.Left)
{
centre.x--;
PA_Clear16bitBg(0);
}
else if(Pad.Held.Right)
{
centre.x++;
PA_Clear16bitBg(0);
}
if(Pad.Held.Up)
{
centre.y--;
PA_Clear16bitBg(0);
}
else if(Pad.Held.Down)
{
centre.y++;
PA_Clear16bitBg(0);
}
if(rayon<10)
rayon=10;
else if(rayon>HAUTEUR_ECRAN/2)
rayon=HAUTEUR_ECRAN/2;
if(centre.x-rayon<0)
centre.x=rayon;
else if(centre.x+rayon>LARGEUR_ECRAN)
centre.x=LARGEUR_ECRAN-rayon;
if(centre.y-rayon<0)
centre.y=rayon;
else if(centre.y+rayon>HAUTEUR_ECRAN)
centre.y=HAUTEUR_ECRAN-rayon;
dessiner_cercle(centre,rayon);
PA_WaitForVBL();
}
return 0;
}
void dessiner_cercle(Point centre,int rayon)
{
int x,x1,y;
for(y=centre.y-rayon;y<centre.y;y++)
{
x=(int)(centre.x-sqrt((rayon+y-centre.y)*(rayon-y+centre.y)));
x1=(int)(centre.x-sqrt((rayon+y+1-centre.y)*(rayon-y-1+centre.y)));
PA_Draw16bitLine(0,x,y,x1,y+1,PA_RGB8(255,0,0)); // En haut à gauche
PA_Draw16bitLine(0,2*centre.x-x,y,2*centre.x-x1,y+1,PA_RGB8(255,0,0)); // En haut à droite
PA_Draw16bitLine(0,x,2*centre.y-y,x1,2*centre.y-y-1,PA_RGB8(255,0,0)); // En bas à gauche
PA_Draw16bitLine(0,2*centre.x-x,2*centre.y-y,2*centre.x-x1,2*centre.y-y-1,PA_RGB8(255,0,0)); // En bas à droite
}
}
|
Dessiner la fonction PA_RandMax !
Vous connaissez sûrement le principe des fonctions mathématiques.
Je ne vais pas vous faire un cours de maths là-dessus

, mais nous allons dessiner PA_RandMax.
Pour cela, nous allons dessiner une suite de lignes qui se suivent pour notre courbe. Nous allons d'abord créer un compteur que l'on incrémentera à chaque tour de boucle. Il représentera nos x. Son image (
PA_RandMax(192)
) sera nos y.
Ce qui est logique puisque c'est comme ça que l'on dessine une fonction.
Les mathématiciens (et pas qu'eux

) mettent l'origine de leur repère orthonormé en bas à gauche. Il faudra donc soustraire à la hauteur de l'écran les y puisque ceux-ci sont inversés (le 0 en haut).
Si un de vos y est négatif, il ne faut pas tracer la courbe, sinon elle piquera vers le bas

.
Vous savez assez de notions pour le faire maintenant.
Correction
Encore une fois, voici ma correction

:
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 | #include <PA9.h>
#define RGB(r,g,b) PA_RGB((int)(r*31./255.),(int)(g*31./255.),(int)(b*31./255.))
#define LARGEUR_ECRAN 256
#define HAUTEUR_ECRAN 192
int main(int argc, char ** argv)
{
int x=0,y=0,y1=0;
PA_Init();
PA_InitVBL();
PA_Init16bitBg(0,0);
PA_InitRand();
while(x<LARGEUR_ECRAN)
{
if(!x)
y=PA_RandMax(HAUTEUR_ECRAN);
else
{
y1=PA_RandMax(HAUTEUR_ECRAN);
if(y>=0&&y1>=0)
PA_Draw16bitLine(0,x-1,y,x,y1,RGB(255,0,0));
y=y1;
}
x++;
PA_WaitForVBL();
}
return 0;
}
|
Et voilà, vous obtiendrez une courbe rouge sur un fond noir qui se trace en direct

!