Informatique Langage C
Section outline
-
-
1. Lancer et tester le premier programme (projet 1_a_rectangle)
Une introduction à la programmation graphique a été donnée dans la vidéo du dernier chapitre de la deuxième partie (les fonctions partie 2). Je vous invite à revoir cette video avant de commencer le projet. La première chose à faire est de télécharger (si ce n'a pas été déjà fait) le dossier du projet : https://github.com/jlsalvat/CSFML-VisualStudio_2_6_0/ .
Ce premier programme qui est presque identique au programme proposé dans le main.c du projet (vu dans la vidéo des fonctions partie 2)va nous servir de base pour la suite. On retrouve :
- en bleu le code associé à la gestion de la fenêtre graphique et notamment sa création sfRenderWindow_create , puis aprés avoir traiter la boucle des messages windows (ici la gestion du clavier) 1: effacement du buffer video d'arrière plan sfRenderWindow_clear , 2. l'ajout des formes graphiques (ici un rectangle) sur le buffer video d'arrière plan (on prépare la prochaine image) sfRenderWindow_drawRectangleShape 3: le basculement entre le buffer video actuel et le buffer video d'arrière plan sfRenderWindow_display ce qui permet d'éviter les effets de scintillement (principe video du double buffering).
- en jaune le code de gestion d'un rectangle avec en premier la création du contexte graphique du rectangle sfRectangleShape_create suivi du paramétrage de ce rectangle (sfRectangleShape_setFillColor, sfRectangleShape_setSize) permettant d'initialiser les éléments qui ne changeront pas pendant le programme puis aprés la gestion de la boucle des messages windows (une fois que la position du rectangle dans la fenêtre graphique a été mise à jour) la modification de sa position sfRectangleShape_setPosition
- en vert la gestion de la boucle des messages windows avec la fonction sfRenderWindow_pollEvent qui permet de lire tous les messages générées par Windows ( par la souris, le joystick et le clavier) pendant 20ms, c'est pour cela que cette fonction est dans une boucle while. Dans cette boucle de lecture des messages on peut alors traiter chaque évènement avec la structure de données event.type qui renvoie le type d'évènement (l'appui sur la fermeture de la fenêtre event.type == sfEvtClosed ou bien l'appui sur une touche du clavier event.type == sfEvtKeyPressed ).
Code du premier programme
#define INC_DEP_RECT 10
#define L_RECT 50
#define H_RECT 100
#define L_WIN 480
#define H_WIN 380
int main()
{
sfRenderWindow* window;
sfEvent event;
sfRectangleShape* rect;
sfVector2f posRect = { 0,0 };
int dy = INC_DEP_RECT,dx= INC_DEP_RECT;
rect= sfRectangleShape_create();
sfRectangleShape_setFillColor(rect, sfRed);
sfRectangleShape_setSize(rect, (sfVector2f) { L_RECT, H_RECT});
window = sfRenderWindow_create((sfVideoMode) { L_WIN, H_WIN, 32 }, "Rectangle", sfClose, NULL);
while (sfRenderWindow_isOpen(window)) {
// Process events
while (sfRenderWindow_pollEvent(window, &event)){
if (event.type == sfEvtClosed || event.key.code == sfKeyEscape)
sfRenderWindow_close(window);
if (event.type == sfEvtKeyPressed) {
printf("sfEvtKeyPressed\n");
if (event.key.code == sfKeyUp)
posRect.y -= dy;
if (event.key.code == sfKeyDown)
posRect.y += dy;
if (event.key.code == sfKeyLeft)
posRect.x -= dx;
if (event.key.code == sfKeyRight)
posRect.x += dx;
}
}
sfRectangleShape_setPosition(rect, posRect);
sfRenderWindow_clear(window, sfWhite);
sfRenderWindow_drawRectangleShape(window, rect, NULL);
// Update the window
sfRenderWindow_display(window);
// temps de rafraichissement pour pas trop charger le GPU
sfSleep((sfTime) { 20000 });
}
// Cleanup resources
sfRectangleShape_destroy(rect);
sfRenderWindow_destroy(window);
return EXIT_SUCCESS;
}

TRAVAIL A FAIRE
- Lancer le projet que vous avez copier dans le répertoire 1_a_rectangle et vérifier son bon fonctionnement
-
2. Première modification du programme (projet 1_b_rectangle_pas)
TRAVAIL A FAIRE
- Copier le projet initial vers le répertoire 1_b_rectangle_pas qui sera votre premier projet modifié.

- Aprés avoir ouvert le projet se trouvant dans 1_b_rectangle_pas, lancer le projet.
- Modifier le programme principal pour :
- afficher à la place du message générique sfEvtKeyPressed un message spécifique à chaque appui (UP,DOWN,LEFT,RIGHT)
- ajouter la gestion des évènements sfKeyA et sfKeyQ (appui sur les touches A pour incrémenter et Q pour décrémenter) et modifier les pas dx et dy de 5 en 5 avec un maximum à 50 et un minimum à 0 (comme montré dans la vidéo).
- Copier le projet initial vers le répertoire 1_b_rectangle_pas qui sera votre premier projet modifié.
-
3. Blocage du rectangle à l'intérieur de la fenêtre (projet 1_c_rectangle_bloque)
TRAVAIL A FAIRE
-
Recopier le répertoire 1_b_rectangle_pas vers un nouveau répertoire 1_c_rectangle_bloque et ouvrir le projet dans ce nouveau dossier.

- Modifier le programme pour ajouter le blocage du rectangle lorsque pos.x<0 et pos.y<0 (partie à gauche et en haut) mais aussi pos.x>(L_WIN - L_RECT) et pos.y>(H_WIN - H_RECT) (partie à droite et en bas).

-
-
4. Travail avec les fonctions (1_d_fonction_base)
Pour travailler sur cette partie, il est nécessaire que vous ayez validé tous les chapitres de la troisième partie puisque pour pouvoir répondre à ce problème vous avez besoin de comprendre les structures de données, les pointeurs sur structures et les fonctions appelant des structures. Si c'est le cas vous pouvez essayer de travailler sur cette partie, sinon passer à la suite.
Vous allez copier le projet 1_a_rectangle dans le répertoire 1_d_bonus_fonction_base. Le but de ce projet est de créer des fonctions de gestion des rectangles permettant par exemple de créer plusieurs rectangles dans un projet plus grand.
Voici l'organisation du programme :
- en gris on retrouve la définition de la structure de données Rectangle que l'on va utiliser dans nos fonctions. Cette structure va comporter les positions en x et y ainsi que la taille en X et Y du rectangle, sans oublier évidemment un pointeur vers l'objet graphique permettant l'affichage du rectangle.
- en vert vous avez les fonctions que vous devez compléter. La première permet de créer une structure de type rectangle, initialiser la partie graphique et renvoyer la structure ainsi créée et la deuxième doit gérer le dépassement (à réaliser une fois la première fonction validée
- en jaune vous avez les fonctions déjà écrites (le code vous est fourni pour une meilleure compréhension du travail à réaliser)
#define _CRT_SECURE_NO_WARNINGS //pour pouvoir utiliser scanf
#include <SFML/Audio.h>
#include <SFML/Graphics.h>
#include <stdlib.h>
#include <stdio.h>
//Pour pouvoir lancer ce jeu vous devez installer https://www.openal.org/downloads/ sur votre PC
#define INC_DEP_RECT 10
#define L_RECT 50
#define H_RECT 100
#define L_WIN 480
#define H_WIN 380
#define INC_DEP_RECT_KEY 5
typedef struct {
sfRectangleShape* rect;
float x;
float y;
int sizeX;
int sizeY;
} Rectangle;
Rectangle rectangle_create(float x, float y, int sizeX, int sizeY, sfColor fillColor) {
//a compléter programme
}
void rectangle_move(Rectangle* rectangle, float dx, float dy) {
rectangle->x += dx;
rectangle->y += dy;
sfVector2f pos = { rectangle->x,rectangle->y };
sfRectangleShape_setPosition(rectangle->rect, pos);
}
void rectangle_draw(sfRenderWindow* window, Rectangle rectangle) {
sfRenderWindow_drawRectangleShape(window, rectangle.rect, NULL);
}
void rectangle_destroy(Rectangle rectangle) {
sfRectangleShape_destroy(rectangle.rect);
}
void gestion_depassement(Rectangle* rectangle) {
//à compléter
}
int main(){
int dx, dy;
dx = dy = INC_DEP_RECT;
sfRenderWindow* window;
sfEvent event;
Rectangle rectangle1 = rectangle_create(100, 100, L_RECT, H_RECT, sfRed);
window = sfRenderWindow_create((sfVideoMode) { L_WIN, H_WIN, 32 }, "Rectangle", sfClose, NULL);
while (sfRenderWindow_isOpen(window)) {
// Process events
while (sfRenderWindow_pollEvent(window, &event)){
if (event.type == sfEvtClosed || event.key.code == sfKeyEscape)
sfRenderWindow_close(window);
if (event.type == sfEvtKeyPressed) {
if (event.key.code == sfKeyUp)
rectangle_move(&rectangle1, 0, -dy);
if (event.key.code == sfKeyDown)
rectangle_move(&rectangle1, 0, +dy);
if (event.key.code == sfKeyLeft)
rectangle_move(&rectangle1, -dx,0);
if (event.key.code == sfKeyRight)
rectangle_move(&rectangle1, +dx, 0);
//ajout pour gérer le dépassement
gestion_depassement(&rectangle1);
}
}
sfRenderWindow_clear(window, sfWhite);
rectangle_draw(window, rectangle1);
// Update the window
sfRenderWindow_display(window);
// temps de rafraichissement pour pas trop charger le GPU
sfSleep((sfTime) { 20000 });
}
// Cleanup resources
rectangle_destroy(rectangle1);
sfRenderWindow_destroy(window);
return EXIT_SUCCESS;
}
TRAVAIL A FAIRE
- copier le projet 1_a_rectangle dans le répertoire 1_d_fonction_base.
- Ecrire le code de la fonction rectangle_create et tester le programme (sans la partie gestion du dépassement)
- Ecrire le code de la fonction gestion_depassement et tester le programme
- Rendre votre programme modulaire (Rectangle.c, Rectangle.h et main.c).
Ce travail de projet est destiné seulement aux étudiants ayant réussi tous les exercices de la partie 3 (et donc terminé les 14 chapitres).
-