Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Là, c'est la partie difficile qui commence... En effet, on va faire des maths et de la physique !
Commençons avec la première méthode.
Les sauts, une question de paraboles
Tout est dans le titre. En effet, d'après la les lois physiques, un objet est en chute libre si
uniquement son poids travaille. Par conséquent, ayant une vitesse initiale plus ou moins grande, sa vitesse horizontale est constante, mais la vitesse verticale devient rapidement négative (dès que l'objet a atteint le plus haut point de son saut) ... ... Ne faites pas attention à ce que je viens de vous dire si vous n'y comprenez rien

.
En gros, un saut, c'est le mouvement d'un objet en chute libre ce qui aura pour conséquence que la courbe de sa trajectoire est ... une
parabole ! Non pas un texte qui cache un enseignement moral ou religieux

, mais un courbe arrondie au-dessus qui imite les vrais sauts.
L'objet monte vite, ralentit, puis redescend lentement en accélérant. C'est donc bien une
parabole.
Trouver l'équation d'une parabole
Pour définir la trajectoire du saut de l'image, il faut définir l'équation de la parabole correspondante.
Qui connait les équations des paraboles ?
Bon, je vais vous le dire

: une parabole a pour équation
y = ax²+bx+c.
C'est là la partie fondamentale de notre saut : on connait l'altitude de notre personnage (y) en fonction de son déplacement horizontal (x) !
Je vous montre à quoi ressemblerait cette parabole :
On va donc dessiner un repère fictif dans notre programme.

Je vous expliquerai ça plus en détail après

.
On va maintenant s'occuper à trouver les
coefficients a, b et c dans cette équation. En effet, si on connait l'équation de notre parabole, on pourra donner le
déplacement horizontal à notre programme pour qu'il calcule le
déplacement vertical.

Très pratique parce que cela s'appelle un saut

!
Trouver b
Et oui je commence bien dans l'ordre !

b est le plus facile. En effet, comme on le voit sur mon schéma
terrible de la mort qui tue,
la courbe est symétrique par rapport à l'axe des abscisses. Ce qui veut dire que le déplacement horizontal est nul, tout comme b.
Donc : b = 0.
Trouver c
Qui connait la méthode pour trouver c ? c est ce qu'on pourrait appeler l'ordonnée à l'origine. C'est en gros
l'ordonnée du sommet de la parabole.
Par quoi cette ordonnée est-elle définie ?
Par la
hauteur du saut, bien sûr !
Allez, combien on fait sauter notre mario ? 50 pixels ? 100 pixels ? Je choisirai 100 pour cet exemple, mais vous pouvez choisir plus, bien entendu.
Donc : c = 100.
Trouver a
Aïe, les choses se corsent
encore 
. Où en somme-nous d'ailleurs ? L'équation qu'on a pour le moment est :
y = a*x²+100 (car b = 0).
De quoi peut bien dépendre a ? Je vous donne deux pistes :
- Si a est positif, la parabole est tournée vers le haut, et inversement.
- La parabole devient de plus en plus large quand a devient de plus en plus petit.
Pour la première info, a doit bien sûr être
négatif. En effet, on ne veut pas que notre personnage tombe et remonte, mais qu'il saute et qu'il redescende.
Exemple de parabole tournée vers le haut, où a est par conséquent positif :
Et une tournée vers le bas, où a est négatif :
J'ai surligné avec mes grands talents artistiques

la partie qui va nous intéresser. Les coordonnées négatives, c'est pas pour tout de suite. On prend donc un a négatif !
La seconde information est capitale.
Une parabole devient de plus en plus large quand a diminue... Il faudrait donc peut-être choisir un point de départ et d'arrivée. Le
point de départ est le moment du saut, et le
point d'arrivée, le moment d'atterrissage.
Je choisis comme point de départ, 200 px, et 301 px comme moment d'atterrissage. Pourquoi 301 ? Si j'avais choisi un nombre pair, il serait plus difficile de placer notre repère fictif. Les demi-pixels n'existent malheureusement pas

...
Où sera donc placé notre repère fictif ?
Au point 251 bien sûr ! C'est le milieu entre 200 et 301.
Maintenant, on veut savoir les coordonnées de ces points, que j'appelle A, le point de départ, et B, le point d'arrivée. Le personnage est au sol pendant ces deux moments, non ? Dans ce cas :
A(200;300)
B(301;300)
Je vous rappelle que le sol, le trait que j'ai tracé, est à 300 px du bord inférieur de notre fenêtre

. D'où le schéma suivant, avec les coordonnées absolues :
Malheureusement, on ne peut utiliser ça pour notre parabole, car la parabole a un autre repère que notre fenêtre (
l'origine est (251;300)). Réfléchissons donc : A et B sont distants de 101 px; l'origine est au milieu de cette distance; par conséquent,
on peut dire que B est distant de 50px de l'origine, et A aussi. Mais A est à gauche de l'axe des ordonnées. Donc, les abscisses de A sont
négatives.
Ce qui nous donne ces points relatifs :
A(-50;0)
B(50;0)
D'où le second schéma, avec les coordonnées dans le repère fictif :
On met 0 en ordonnées car les ordonnées de l'origine sont identiques à celles de nos points.
Il est capital d'avoir compris cette partie, n'hésitez pas à relire 
.
Maintenant qu'on a ces nouveaux points (dont vous pouvez personnaliser les abscisses d'ailleurs), on reconsidère notre équation :
y = a*x²+100.
On peut remplacer x et y par les coordonnées de l'un ces points. Je choisis A; par conséquent,
0 = a*(-50)² + 100 ; on résout l'équation :
2500a = -100.
Donc : a = -0,04.
a est-il bien négatif ? Oui, donc nous pouvons continuer !
Pourquoi faire tout ça
Et bien, parce que nous allons l'utiliser dans notre programme. Le repère choisi sera fictif, non dessiné, et ce qui sera surtout intéressant, c'est que nous allons positionner mario selon un intervalle régulier du temps, pour créer un mouvement fluide.
Argh

pourquoi on était là déjà ? Ah oui, pour programmer !
Mario, il est présent dans 2 repères, un fictif, et le repère de notre fenêtre. L'ennui avec le repère de notre fenêtre, c'est qu'il est inversé; le 0 est tout en haut. On ne va pas s'embêter, on verra ça plus tard

.
2 repères, ça veut dire ... 2 positions ! Et oui ! J'ai nommé ...
Code : C1
2
3
4
5
6
7 | SDL_Rect posMarioAbs;
posMarioAbs.x = 200;
posMarioAbs.y = 300;
SDL_Rect posMarioRel;
posMarioRel.x = -50;
posMarioRel.y = 0;
|
Hein ? Abs et Rel ?
Et oui, il y a une position que j'appelle
absolue : c'est la position de Mario dans la fenêtre. La seconde position est
relative : c'est la position de Mario dans notre nouveau repère.
J'ai pris les coordonnées du point A pour la première position de notre Mario ; cf. ci-dessus.
Pourquoi en faire 2 ? Eh bien, parce que la SDL ne comprend rien aux repères relatifs : lui, y a que la fenêtre ! Et nous, on ne peut pas travailler dans le repère de la fenêtre; conséquence, on travaille autre-part, et ça nous fait deux positions.
Ne vous inquiétez pas, elles sont liées, c'est ça le plus grand intérêt

.
Ne reposons pas sur nos lauriers tout de suite ; notre Mario est toujours immobile

.
Nous allons donc nous intéresser au code, et plus particulièrement à la partie qui suit la gestion d'évènements, la partie que j'appelle
"l'évolution".
L'évolution
Ici, on va travailler sur les coordonnées de notre Mario.
L'évolution se situe ici :
Code : C 1
2
3
4
5
6
7
8
9
10
11 | main()
{
initialisation();
while
{
gestion_évènements();
EVOLUTION();
affichage();
}
quitter();
}
|
Je vous ai fait un schéma bien sympathique de là où on va travailler. On va d'abord s'intéresser au temps.
Le temps
Comme vous travaillez tous avec des ordis 4.0 GHz, le code va s'exécuter super vite

. Vous n'aurez même pas le temps de voir votre pauvre Mario sauter... On va donc mettre un
intervalle de temps régulier, entre chaque affichage :
Code : C
SDL_Delay interrompt le programme pendant un temps exprimé en
ms. L'intervalle est de 10 ms, assez petit pour qu'on voit un mouvement bien fluide. On place cette fonction à la fin du code de l'évolution.
Maintenant, on veut qu'à chaque fois que la boucle passe, Mario avance. On va d'abord s'intéresser à sa vitesse horizontale.
La vitesse horizontale
Dans une chute libre, la
vitesse horizontale ne varie pas. Si vous ne savez pas ce qu'est la vitesse horizontale, sachez que tout objet a une vitesse que l'on peut décomposer en vitesse horizontale et une vitesse verticale. Sous forme de vecteurs, on obtient ça :
Conséquence : on incrémente les abscisses de notre Mario à chaque fois que la boucle passe.
Les abscisses absolues ou relatives ?
Bonne question

. Nous travaillons dans le repère fictif, donc ce seront les abscisses relatives :
Code : C
Voilà pour la vitesse horizontale.
La vitesse verticale
Pour la vitesse verticale, c'est là que notre équation de parabole va venir en aide. En effet, on avait dit qu'on pouvait trouver y en fonction de x :
y = 0,04x² + 100;
Donc :
Code : C1 | posMarioRel.y=(-0.04*(posMarioRel.x*posMarioRel.x)+100);
|
En C, "²" n'existe pas donc il faut le faire manuellement.
Voilà, nous avons géré nos variables relatives. Quant aux absolues, il faut se référer à la loi de Chasles ; si I est l'origine de notre nouvelle origine, et M un point quelconque dans le plan, on a :
Par conséquent, on peut ajouter les coordonnées :
Code : C1
2 | posMarioAbs.x = posMarioAbs.x + posMarioRel.x +50;
posMarioAbs.y = posMarioAbs.y + posMarioRel.y;
|
NB : dans le repère fictif, on commence à -50 px. Par conséquent, quand notre Mario saute dans le repère absolu, il sera décalé de 50 px de son point de départ absolu. D'où le "+50" dans la formule.
Il nous reste une dernière chose à faire : à chaque passage de boucle, les variables absolues sont modifiées ; si on ne veut pas que notre Mario parte à Saint-Perpète-les-Bains

, il faut les remettre comme elles étaient avant ; on rajoute donc :
Code : C1
2 | posMarioAbs.x = 200;
posMarioAbs.y = 300;
|
Affichage
N'oubliez pas non plus de blitter vos surfaces :
Code : C1
2 | SDL_BlitSurface(fond, 0, ecran, &posFond);
SDL_BlitSurface(mario, 0, ecran, &posMarioAbs);
|
Lancez votre code, et observez ...
Corriger les erreurs
Hé hé hé vous avez dû oublier quelque chose !
On va corriger les erreurs une à une :
Mon Mario commence avec la tête en-dessous du sol !
C'est normal, l'origine du repère de dessin est l'angle supérieur gauche de notre surface. Pour remédier à cela, il faut enlever la hauteur de Mario aux coordonnées absolues :
Code : C1
2 | posMarioAbs.x = 200;
posMarioAbs.y = 300-(mario->h);
|
Mon Mario tombe et remonte !
Là on va voir ceux qui ont bien écouté : je l'ai dit un peu au-dessus ; le repère de la SDL est inversé. Il faut donc rajouter un "-" en ajoutant les ordonnées absolues et relatives :
Code : C1
2 | posMarioAbs.x = posMarioAbs.x + posMarioRel.x;
posMarioAbs.y = posMarioAbs.y - posMarioRel.y;
|
Mon Mario quitte l'écran à la fin du saut !
Il faut remettre à zéro les variables relatives quand elles deviennent trop grandes ; rajoutez ça au début de l'évolution , juste après avoir incrémenté la valeur relative des abscisses :
Code : C1
2
3
4 | if(posMarioRel.x>=50)
{
posMarioRel.x=-50;
}
|
Pour éviter que Mario ne s'enfonce dans le sol !
Voilà, normalement, il n'y a plus d'erreurs.
Tenez, voici le code complet pour ceux qui n'ont pas écouté

:
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 | #ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
int main ( int argc, char** argv )
{
//Init de la SDL
SDL_Init( SDL_INIT_VIDEO );
//Et on quitte bien
atexit(SDL_Quit);
// On crée une fenêtre
SDL_Surface* ecran = SDL_SetVideoMode(640, 480, 16,
SDL_HWSURFACE|SDL_DOUBLEBUF);
// On charge le fond
SDL_Surface* fond = SDL_LoadBMP("fond.bmp");
//On charge mario
SDL_Surface* mario = IMG_Load("mario.png");
// La position du fond
SDL_Rect posFond;
posFond.x = 0;
posFond.y = 0;
// La position absolue de mario
SDL_Rect posMarioAbs;
posMarioAbs.x = 200;
posMarioAbs.y = 300-(mario->h);
// La position relative de mario
SDL_Rect posMarioRel;
posMarioRel.x = -50;
posMarioRel.y = 0;
// program main loop
bool done = false;
while (!done)
{
// message processing loop
SDL_Event event;
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
done = true;
break;
// check for keypresses
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
done = true;
break;
}
}
}
// EVOLUTION
//On avance de 1
posMarioRel.x++;
if(posMarioRel.x>=50)
{
posMarioRel.x=-50;
}
//On met à "0" les pos abs:
posMarioAbs.x = 200;
posMarioAbs.y = 300-(mario->h);
//On calcule la valeur relative de y:
posMarioRel.y=(-0.04*(posMarioRel.x*posMarioRel.x)+100);
//On calcule maintenant les valeurs abs
posMarioAbs.x = posMarioAbs.x + posMarioRel.x+50;
posMarioAbs.y = posMarioAbs.y - posMarioRel.y;
//Intervalle de 10ms
SDL_Delay(10);
// FIN EVOLUTION
// DRAWING STARTS HERE
// clear ecran
SDL_FillRect(ecran, 0, SDL_MapRGB(ecran->format, 0, 0, 0));
// draw bitmap
SDL_BlitSurface(fond, 0, ecran, &posFond);
SDL_BlitSurface(mario, 0, ecran, &posMarioAbs);
// DRAWING ENDS HERE
// finally, update the ecran :)
SDL_Flip(ecran);
} // end main loop
// free loaded bitmap
SDL_FreeSurface(fond);
SDL_FreeSurface(mario);
return 0;
}
|
Hé, moi je le trouve moche ce saut ! En vrai, je suis sûr que les lois physiques empêchent de sauter de cette façon !
Oui, vous devez sûrement
tous penser ça

. Voilà pourquoi je vous présente maintenant une seconde méthode ... plus compliquée, plus déroutante, plus sanglante, plus horrible que jamais ...

J'ai nommé ...
les courbes paramétriques 
!
Un poil plus dure que la précédente

, cette méthode relève du programme de Terminale S.
Attention ! Je ne vais pas m'amuser à redémontrer les acquis mentionnés ci-dessus. Soit tout cela est dans votre cours, soit vous l'acceptez comme c'est écrit

!
À quoi ça sert de faire encore plus compliqué ?

Pour obtenir des sauts
réalistes, bien sûr ! En effet, les paraboles permettent parfois de faire... trop de choses. Je m'explique : on peut, avec la méthode précédente, faire sauter Mario de 200 px vers la droite, en ne l'élevant au total que de 1 px ; c'est complètement contre les lois de la nature ! Ou plutôt, les lois de Newton

...
La seconde loi de Newton
Je ne vous la citerai pas ici, elle est trop barbare et elle va sûrement vous faire peur et vous décourager pour le QCM

. Sachez simplement que l'on se base dessus pour le reste du tutorial, car le saut que l'on va programmer a une vitesse non rectiligne ni uniforme.
Le principe de cette méthode est bien plus réaliste, car elle permet de s'adapter à des situations plus "réalistes" qu'avec la méthode précédente. En effet, imaginez que votre perso court avec une vitesse initiale V et qu'il saute... Comment reproduire ça avec une parabole

?!?
J'ai déjà révélé le premier paramètre de notre saut :
la vitesse initiale ; maintenant, si je vous annonçais qu'on peut programmer un saut uniquement avec
l'angle de saut et cette
vitesse initiale ? Si, si

!
En gros, le début du saut sera comme ceci :
L'angle initial de saut est bien sûr dans le sens direct, par convention opposé aux aiguilles d'une montre

.
Il va maintenant falloir appliquer ces deux paramètres à notre saut. Commençons par les
vitesses horizontale et verticale.
Décomposer la vitesse, et en déduire la trajectoire
Tout d'abord, la vitesse
Bon je vous rappelle mon magnifique schéma

:
Notre but est d'abord de trouver la vitesse horizontale Vx puis la vitesse verticale Vy. Les accros de la trigo verront vite que l'on peut établir ces relations :
Ca, c'était la partie facile.
Trajectoire : deux façons de la trouver
Continuons d'innover ; en effet, nous allons utiliser ici les
axes paramétriques !
En gros,
y ne dépend plus de x.
Et oui ! À partir de maintenant,
y dépend de t, et x aussi.
t ?!?! Qu'est-ce que c'est que ça ?
"Ca" c'est tout simplement notre intervalle de temps régulier que l'on retrouve ici.
"t" est l'instant où y vaudra tant, et x vaudra tant. Pour nous programmeurs, t est l'instant où on blittera notre image à une abscisse donnée et une ordonnée donnée. Or, avec notre
SDL_Delay();, les instants deviennent virtuels. En effet, si on met un délai de 10 ms, toutes les 10 ms notre image sera réaffichée. Ainsi, t = 0 est l'instant donné où mario n'a pas encore quitté le sol, et pour nous ça correspond peut-être au 1er passage de boucle.
Reprenons

. Maintenant que nous avons calculé les vitesses, intéressons-nous à la
trajectoire. De quoi dépend-elle exactement ? On vient de dire qu'elle dépendait de l'instant où on affiche, et ... la vitesse horizontale ou verticale ! En fait, on peut dire que :
Pour la vitesse horizontale, on retrouve bien nos paramètres. x(t) veut dire : "x à l'instant t". Mais pour la position verticale ? Ce serait une erreur d'exprimer y de la même façon que x, car on obtiendrait en fin de compte ... une fonction linéaire, c'est-à-dire, une droite

Notre Mario irait droit dans le ciel !

Or nous recherchons une parabole, il nous faut donc des x².
Mais, tu ne nous avais pas dit que y ne dépendait plus de x ?
C'est là la réponse au sujet. En effet, il faut en fait enlever à chaque instant quelques pixels de notre position verticale, à la façon d'une parabole mais par rapport à la constante gravitationnelle. D'où la formule complexe ci-dessus.
Ne vous posez pas trop de questions si vous ne comprenez pas. Dites-vous simplement que l'on retrouve dans ce calcul :
- La vitesse verticale Vy ;
- L'instant t par rapport à la vitesse verticale ;
- La constante gravitationnelle g. Sur Terre, elle vaut 9,81 N/kg environ ;
- Encore une fois l'instant t par rapport à la constante gravitationnelle, et au carré pour bien confirmer que la trajectoir est une parabole.
Voilà

. Votre Mario est prêt à être lancé

. Passons donc à la programmation.
Ce que ça donne en C
Résumons ce qu'il faut faire

.
Les variables
Il y a plus de variables à définir que chez les paraboles.
Tout d'abord, il y a la
constante gravitationnelle, qui fera "l'effet poids" :
Code : C
Puis, on définit un instant t que l'on initialise à 0 :
Code : C
Enfin, on établit les paramètres initiaux de notre saut :
Code : C1
2 | int v_init = 2;
int angle_init = 70;
|
On peut ainsi tout de suite calculer nos vitesses horizontale et verticale :
Code : C1
2 | double v_x = cos(angle_init)*v_init;
double v_y = sin(angle_init)*v_init;
|
Gardez bien nos positions absolues et relatives. On peut maintenant passer à l'évolution !
Evolution
Dans l'évolution, on va d'abord faire changer le temps. Placez votre SDL_Delay(); à la fin, et occupez-vous de l'instant t :
Code : C
t est ici exprimé en ms. Cela sera conséquent pour la suite. Continuons donc avec nos formules pour les trajectoires :
Code : C1
2 | posMarioRel.x=(int)(v_x*t);
posMarioRel.y=(int)((v_y*t)-((g*t*t)/2000));
|
Ca fait une expression barabare, je l'admets

. J'ai rajouté un convertisseur en entiers devant, car la fonction cosinus et la fonction sinus, à partir desquelles sont calculées les décompositions de la vitesse intiale, sont loin de donner un résultat toujours entier. Or, notre compilateur risque de nous insulter poliment si on donne un nombre décimal à une variable sensée contenir un nombre entier. D'où le (int), ayant le même effet qu'une troncature. Vous pouvez vous amuser à trouver la fonction pour arrondir si jamais vous avez besoin d'avoir des résultats précis

.
De plus, ici, ce n'est plus gt²/2 mais gt²/2000

. En effet, t est exprimé en ms, et nous on veut un résultat en secondes, d'où la division supplémentaire par mille.
Gardez bien sûr ça :
Code : C1
2
3
4
5 | posMarioAbs.x = 200;
posMarioAbs.y = 300-(mario->h);
posMarioAbs.x = posMarioAbs.x + posMarioRel.x;
posMarioAbs.y = posMarioAbs.y - posMarioRel.y;
|
Et pour remettre à 0 notre position de Mario, tapez ceci :
Code : C1
2
3
4 | if((posMarioAbs.y)>=(300))
{
t=0;
}
|
Je vous rapelle que tout dépend de t ici

!
Cette fois, il ne devrait pas y avoir d'erreurs...
Le code complet
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 | #ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <math.h>
int main ( int argc, char** argv )
{
//Init de la SDL
SDL_Init( SDL_INIT_VIDEO );
//Et on quitte bien
atexit(SDL_Quit);
// On crée une fenêtre
SDL_Surface* ecran = SDL_SetVideoMode(640, 480, 16,
SDL_HWSURFACE|SDL_DOUBLEBUF);
// On charge le fond
SDL_Surface* fond = SDL_LoadBMP("fond.bmp");
//On charge mario
SDL_Surface* mario = IMG_Load("mario.png");
// La position du fond
SDL_Rect posFond;
posFond.x = 0;
posFond.y = 0;
// La position absolue de mario
SDL_Rect posMarioAbs;
posMarioAbs.x = 200;
posMarioAbs.y = 300-(mario->h);
// La position relative de mario
SDL_Rect posMarioRel;
posMarioRel.x = 0;
posMarioRel.y = 0;
//Variables méthode 2:
const double g = 9.81;
int v_init = 2;
int angle_init = 89;
int t = 0;
double v_x = cos(angle_init)*v_init;
double v_y = sin(angle_init)*v_init;
// program main loop
bool done = false;
while (!done)
{
// message processing loop
SDL_Event event;
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
done = true;
break;
// check for keypresses
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
done = true;
break;
}
}
}
// EVOLUTION
//On avance de 1
//On met à "0" les pos abs:
posMarioAbs.x = 200;
posMarioAbs.y = 300-(mario->h);
//On calcule la valeur relative de y:
posMarioRel.x=(int)(v_x*t);
posMarioRel.y=(int)((v_y*t)-((g*t*t)/2000));
//On calcule maintenant les valeurs abs
posMarioAbs.x = posMarioAbs.x + posMarioRel.x;
posMarioAbs.y = posMarioAbs.y - posMarioRel.y;
//Intervalle de 10ms
t+=1;
// FIN EVOLUTION
if((posMarioAbs.y+(mario->h))<=(100))
{
t=0;
}
// DRAWING STARTS HERE
// clear ecran
SDL_FillRect(ecran, 0, SDL_MapRGB(ecran->format, 0, 0, 0));
// draw bitmap
SDL_BlitSurface(fond, 0, ecran, &posFond);
SDL_BlitSurface(mario, 0, ecran, &posMarioAbs);
// DRAWING ENDS HERE
// finally, update the ecran
SDL_Flip(ecran);
} // end main loop
// free loaded bitmap
SDL_FreeSurface(fond);
SDL_FreeSurface(mario);
return 0;
}
|
Adapter et améliorer
Essayez de modifier les paramètres du saut ; vous vous rendrez vite compte que vos modifications n'auront que très peu d'effet. Le saut est souvent très large, et, à moins de modifier la formule de la trajectoire d'une chute libre ou la constante gravitationnelle, votre saut est vraiment très peu maniable. Toutefois, il existe une solution

.
On obtient une parabole. Vous me direz, une parabole peut s'écrire de la façon y = ax²+bx+c. Et bien, je vous annonce un scoop : d'après la formule hyper-compliquée ci-dessus, on peut en tirer
une équation de parabole ! Je ne le démontrerai pas ici

, mais ça donne :
Normalement il y a un "+ h" à la fin de cette équation
de suicidaire 
. h correspondrait à c dans une équation parabolique. Ainsi, h = 0 car nous sommes toujours dans les coordonnées relatives. Têta correspond à notre angle initial. Si vous remplacez la parabole dans la méthode 1 ci-dessus par cette équation, vous donnez en fait à votre ordinateur l'équation suivante :
Code : C1
2
3 | posMarioRel.y = (int)(-(g/2)*((posMarioRel.x*posMarioRel.x)/
((v_init*cos(angle_init))*(v_init*cos(angle_init))))
+((v_init*sin(angle_init)*posMarioRel.x)/(v_init*cos(angle_init))));
|
Normalement je n'ai pas oublié de parenthèses

. Il faut avouer que cette méthode est vraiment barbare. Mais si vous calculez a, b et c auparavant, cela ne devrait pas trop poser de problèmes à l'ordinateur de les recalculer lorsque vous voulez adapter la parabole
à vos rêves les plus fous 
.
Et maintenant, QCM !