N.G.C.K

« Newbie Game Construction Kit »

(V2.1 par Christophe Kohler 31Jan2004, mise à jour 9 Février 2010)

 

 

 

 

 

I – « NGCK » Qu’est ce que c’est ?

 

NGCK est un environnement simplifié de développement pour PC. L’idée est d’avoir une abstraction complète de la machine en proposant des fonctions d’affichages très rudimentaires (par exemple la fonction KPrintSquare(X,Y) qui affiche un carré blanc à l’écran).

 

NGCK s’adresse aux débutants en programmation. Il permet de créer des premiers programmes simples sans avoir la contrainte de comprendre comment fonctionne une librairie d’affichage sur PC et ainsi de pouvoir se concentrer sur l’apprentissage du langage C/C++.

 

NGCK possède une structure similaire à celle d’un jeu vidéo. C'est-à-dire qu’on retrouve une partie « initialisation » qui sera le code exécuté au lancement du jeu, et ensuite une parti « boucle de jeu » qui sera exécutée à chaque balayage de l’écran.

 

Il est très important de garder ce conseil en mémoire : Quand vous arriverai au moment des exercices difficiles, il est impératif de penser son programme avant de l’écrire en C/C++. Cela permet de définir correctement ce que l’on doit faire et comment on doit le faire. Ainsi vous éviterez le piège de programmer a la volée (on ne peut plus penser lorsqu’on programme). Je vous conseille donc de faire un algorithme sur papier avant chaque début de programmation (dans un langage pseudo informatique et français, genre « si je fais ça, il se passe ça et j’affiche ça »).

 

Un second conseil : il est important de séparer le gestion du jeu et l’affichage. Dans un jeu, la boucle principale est toujours composée de ces deux parties (il est dangereux pour la compréhension de gérer un élément et de l’afficher tout de suite, d’en gérer un autre et de l’afficher, etc … mieux vaut tout gérer d’un coup puis tout afficher d’un coup).

 

NGCK utilise le moteur de jeu « SDL ». Une fois que vous serez plus expérimenté vous pourrez directement faire votre jeu en utilisant ce moteur. Il est simple et puissant et possède la même structure que NGCK, vous ne serez pas perdus.


II – NGCK Volume 1

 

La version de NGCK décrite par ce doc est la version facile (« Easy »).

 

Cette version possède un affichage simplifié. L’écran comprend 30 cases de larges et 20 cases de haut. Les commandes graphiques permettent d’afficher des carrées, ronds et barres.

 

Exemple : Un carré affiché au milieu de l’écran

 

 

 

 

 

Ces fonctions primaires se suffisante pour créer l’affichage de petits programmes et des petits jeux.

 

Les programmes devront être fait en C et utiliser des variables de type entier (« int »).

Des consignes seront données pour chaque exercice pour indiquer les composantes du C qu’il est possible d’utiliser pour l’exercice.

 

Une fois de plus, NGCK ne vous apprendra pas le C/C++. Il vous faut avoir un livre ou un tutorial internet sur le C/C++ pour apprendre les notions nécessaires pour réaliser les exercices.

 

 


III - REQUIS

 

 

Ngck s’adresse aux élèves qui débutent en langage C. Il est conseillé d’avoir déjà parcouru un livre de C et d’en avoir pratiqué les exercices.

 

La philosophie pédagogique de NGCK est de faire utiliser le C pour obtenir un résultat graphique ce qui est bien plus motivant et encourageant que les exercices des livres.

 

NGCK est l’étape qui suit directement la théorie car il est basé sur la pratique.

 

L’utilisation de Ngck passe par la compilation des programmes et l’exécution de ceux-ci.

 

Pour compiler un programme, il est nécessaire d’avoir :

 

- Visual Studio 2008

ou

- Visual Studio 2008 Express

 

Ce dernier est gratuit. Il se télécharge depuis le site microsoft.

 


IV - UTILISATION

 

Tout est contenu dans le répertoire « NGCK ».

 

- Dans le répertoire « Projets » se trouve les projets Visual de chaque exercice.

Dans chacun de ses répertoires se trouve un fichier « MyGame.cpp »

L’élève ne devra modifier que ce fichier.

Pour charger un projet, il suffit de charger le fichier prj/Ex.sln contenu dans chaque répertoire

 

Ouvrir un projet …

 


Compiler (F7), vous devez voir ceci :

 

 


Si vous êtes en debug et que vous voulez lancer depuis visual (F5), vous devez indiquer quel sera le répertoire de travail (par défaut c’est le répertoire du projet, mais les données graphiques sont dans un autre répertoire).

 


Lorsque le programme est exécuté, une fenêtre noire apparaît :

 

 

Une fois ouvert, vous avez sur la gauche les fichiers contenus dans le projet. Cliquez sur MyGame.cpp pour l’éditer.

 

Les fichiers « MyGame.cpp » sont vides (ils contiennent le programme minimum, voir chapitre V).

Si on compile et exécute le programme dans son état initial, on obtient un écran noir. C’est normal.

 

Si vous exécuté et qu’il y a une erreur ‘mémoire trop basse’ ou alors ‘cette application ne peut pas être lancée » alors c’est qu’il y a un problème d’installation du compilateur (surtout si vous utilisez Visual 2005 Express).

 

- Le répertoire « Exécutables » contient le résultat des compilations. Ici se trouvent les fichiers exécutables que vous créerez. Si vous voulez donner votre exécutable de jeu a quelqu’un, il suffit de lui donner ce répertoire

 

- Le répertoire « Corriges» contient la solution de tous les exercices. Pour un débutant, la tentation de lire le corrigé dés la moindre difficulté est grande. Mais malheureusement cela ne suffit pas pour apprendre. Donc si vous vous contentez de lire les corriges pour passer le plus vite possible aux exercices suivant, vous aurez au final rien appris du tout et malgré que vous soyez arrivé a la fin de la série d’exercice vous serez toujours incapable de programmer.

Pour les exercices le plus complexes, ils existent plusieurs solutions. A vous de trouver la votre, c’est cela qui est très intéressant et formateur.

 

 


V - PROGRAMME

 

 

Le programme de départ minimum contenu par « MyGame.cpp » est :

 

 

#include "../Ngck_moteur/Ngck.h"

void InitialiseGame()

{

}

void GameLoop()

{

}

 

 

Il faut toujours partir d’au moins cela, sinon le jeu ne compilera pas.

 

 

 

 


VI - FONCTIONNEMENT

 

Affichage

 

NGCK permets d’afficher des caractères de 16x16 pixels. Sur un écran de 30 caractères en largeur et 20 en hauteur.

Les coordonnées 0,0 sont en haut à gauche d’écran

 

Pour afficher un carré blanc en haut à gauche de l’écran, il faut écrire :

 

KPrintSquare(0,0) ;

 

(Voir chapitre suivant pour la liste complète des commandes)

 

Ainsi le programme :

 

#include "../Ngck_moteur/Ngck.h"

void InitialiseGame()

{

}

void GameLoop()

{

    KPrintSquare(0,0) ;

}

 

Aura pour résultat :

 

 

Un carré blanc est affiché en haut à gauche de l’écran

 


Avec :

 

KPrintSquare(1,0) ;

 

Un carré blanc sera affiché en haut a gauche, à coté de celui précédemment affiche (à sa droite).

 

 

Traditionnellement, on appelle « x » la première coordonnée (position horizontal a écran) et « y » la seconde (position verticale).

 

KPrintSquare(29,19) ;

 

è Affiche un carré en bas a droite de l’écran (c’est la dernière case).

 

 

 

Structure du programme

 

Le programme est structuré comme le programme d’un vrai jeu.

Il existe une fonction d’initialisation InitialiseGame et une fonction de boucle de jeu GameLoop

 

La fonction d’initialisation est appelée en début d’exécution du jeu, une seule fois.

Elle est utilisé pour initialisé les variables globales et créer l’affichage de départ.

 

La fonction GameLoop (boucle de jeu) est appelée à chaque balayage de l’écran.

 


VII - FONCTIONS DISPONIBLES

 

- Les fonctions disponibles sont celles qui commencent par « K » (pour le K de « NgcK »)

 

KPrintSquare(x, y)

 

è Affiche un carré à l’écran. L’écran fait 30 de largeur et 20 de hauteur

La première coordonnée est 0,0. La dernière est 29, 19.

 

KGetLeft()

KGetUp()

KGetRight()

KGetDown()

KGetSpace()

 

è Permets de tester les touches du clavier. Si la touche est appuyée, la fonction renvoi 1 sinon elle renvoi 0.

Left= Flèche direction Gauche

Right= Flèche direction Droite

Up= Flèche direction Haut

Down= Flèche direction Bas

Space=Barre espace

 

Ces fonctions sont suffisantes pour réaliser les exercices.

Cependant des fonctions supplémentaires seront données au fur et à mesure pour embellir l’affichage.

 

 

 

 


 

VIII - EXERCICES

 

Série A : Affichage

 

Série B : Utilisation des touches

 

Série C : Premiers mouvements

 

Série D : La balle et la raquette

 

Série E : Scrolling

 

Série F : Vaisseau & Missile

 

Série G : Jeu de Snake

 

 

 

 


Série A : Affichage

 

Série d’exercice basé sur un affichage simple. La partie « initialisation » est laissée vide. Il faut remplie la partie « GameLoop ». A chaque passage dans GameLoop, il faut afficher ce que l’on désire car écran est effacé entre chaque boucle.

 

 

Exercice A1 :

 

En utilisant la fonction KPrintSquare, afficher un carré au milieu de écran

 

Notions utilisées :

Fonction KPrintSquare

 

 

 

 

 

Exercice A2 :

 

Afficher 5 carrés : Un au milieu de l’écran et 1 dans chaque coin.

 

Notions utilisées :

Fonction KPrintSquare

 

 

 

 

Exercice A3 :

 

Tracer un bord tout autour de l’écran

 

Notions utilisées :

Fonction KprintSquare

Variable locale (de type int)

Boucle for

 

 

 

 

 

Exercice A4 :

 

Afficher un damier.

 

Notions utilisées :

Fonction KprintSquare

Variable locale (de type int)

Boucle for

 

 

 

 

 


Série B : Utilisation des touches

 

Utiliser les fonctions de tests des touches du clavier (touches directionnelles et barre espace) et afficher un résultat suivant l’état.

 

 

 

Exercice B1 :

 

Lorsque la barre espace est pressée, afficher un carré au centre de écran. Lorsque qu’elle n’est pas pressée, ne rien afficher.

 

Notions utilisées :

Fonction KprintSquare

Fonction KGetSpace

Test conditionnel (« if »)

 

 

 

 

 

Exercice B2 :

 

Idem que B1 avec en plus un carré affiché pour chaque direction du pad (cad un carré en haut affiché lorsque le bouton haut est pressé, un carré en bas lorsque la touche bas est pressé, etc..)

 

Notions utilisées :

Fonction KprintSquare

Fonctions KGetSpace KgetRight KgetLeft KgetUp KGetDown

Test conditionnel (« if »)

 

 

 

 

Exercice B3 :

 

Afficher un carré et lorsqu’on appuie sur les touches de direction, ça le déplace d’un cran dans la direction choisi. On pourra ainsi promener le carré sur tout l’écran.

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonctions KGetSpace KgetRight KgetLeft KgetUp KGetDown

Test conditionnel (« if »)

Opérateurs + et -

 

 

 


Série C : Premiers mouvements

 

 

 

Exercice C1 :

 

Faire un carré qui de déplace tout seul sur une ligne horizontal. Il change de direction lorsqu’il touche un bord.

 

 

Notions utilisées :

Variables globales (de type int)

Fonction KprintSquare

Test conditionnel (« if »)

Opérateurs + et -

 

 

 

 

 

 

Exercice C2 :

 

Faire un carré qui rebondit sur les 4 bords (il se déplace donc horizontalement et verticalement).

Variante : Le carré se déplace 2 fois plus vite verticalement.

 

Notions utilisées :

Variables globales (de type int)

Fonction KprintSquare

Test conditionnel (« if »)

Opérateurs + et -

 

 


Série D : La balle et la raquette

 

Voici le moment de faire quelque chose qui ressemble un peu a un jeu.

 

 

 

Exercice D1 :

 

Afficher un cadre blanc (sauf en bas). Dans cette exercice il faut gérer une raquette (barre qui peut se déplacer de gauche a droite). La raquette se déplace avec les touches gauche/droite.

La raquette sera gérée par son centre.

La taille de la demi-raquette sera stockée dans une variable « TailleDemiRaquette »

(C’est le nombre de carré qui se trouve de chaque coté du centre).

La raquette doit s’arrêter lorsqu’elle touche le mur de gauche ou de droite.

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonctions KgetRight KgetLeft

Test conditionnel (« if »)

Boucle “for”

Opérateurs + et -

 

 

 

 

 

 

Exercice D2 :

 

Suite de l’exercice D1.

Ici il faut ajouter une balle qui se déplace a la vitesse de 1 horizontalement et 1 verticalement (reprendre le code fait en C2).

La balle doit rebondir sur les murs du haut et des cotés (sans rentrer dedans).

Elle doit aussi rebondir sur la raquette (sans rentrer dedans).

Si le joueur n’a pas mis la raquette au moment ou la balle arrive, la balle est replacée au centre et repars aussitôt (en se dirigeant vers le haut). Utiliser la fonction « KprintBall(x,y) » pour afficher une balle.

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonction KprintBall

Fonctions KgetRight KgetLeft

Test conditionnel (« if » et “else” )

Boucle “for”

Opérateurs + et -

 

 

 

 

 


 

 

Exercice D3 : (Bonus)

 

Afficher un bord autours de l’écran en pointillé qui alterne a chaque image. Attention, deux cases ne doivent pas se suivre, même dans les coins.

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Test conditionnel (« if » et “else” )

Boucle “for”

Opérateur binaire ET (“&”) ou modulo (“%”)

 

 

 


Série E : Scrolling

 

Scrolling signifie « déplacer écran ». Ca peut se faire de haut en bas, de droite a gauche ou dans tous les sens. Il existe plusieurs méthodes pour faire cela. Nous allons en voir quelques unes au travers de ces exercices.

 

 

Exercice E1 : La pente

 

Faire défiler de haut en bas une grande pente (qui fait deux fois la taille de écran, ….. 1 carré sur la première ligne (en commencant par la gauche), 2 sur la seconde, etc …Les dernières lignes seront toutes pleines.)

 

Il y a plusieurs façons de résoudre le problème.

Pour obtenir des indices sur la façon que j’ai utilisée, il suffit de sélectionner le texte ci-dessous et de changer sa couleur à noir.

 

Attention : Si vous lancer l’exe du corrigé, vous pourrez avoir l’impression que l’écran se déplace de gauche à droite. Ce n’est pas le cas. Il se déplace de haut en bas.

 

Indice1 :

Déclarer dans le programme un tableau qui sera deux fois la taille de écran (30 par 40).

On peut utiliser un type « int » puisqu’on va juste y stocker des 0 et des 1.

On décide que 0=vide et 1=1 carré

Dedans y construire la pente (ça nous évite de la reconstruire à chaque fois)

Pour mieux comprendre, voir l’image dans Corrigé/Scrolling.png

 

Indice2 :

Pour simuler un défilement, il suffit de recopier une partie de ce tableau dans l’écran En fait on déplace uniquement un compteur qui indique quel ligne de départ il faut commencer a copier dans écran C’est une méthode de scrolling (on déplace uniquement un pointeur sur une grande carte).

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Test conditionnel (« if » et “else” )

Boucle “for”

Tableau à 2 dimensions

 

 

 

 

Exercice E2 : La ligne qui descend

 

Avec les flèches gauche/droite, on peut déplacer un carré en haut de écran Ce carré laisse une trace derrière lui, donnant l’impression qu’il monte et que la ligne descend.

 

Indice 1 :

Il déclarer un tableau en local de 30 cases sur 20. Ce tableau nous servira à construire le vrai écran a la fin de la gameloop. Ce tableau sera des « int » car nous avons que 2 valeurs a géré « vide » ou « carré ». Nous choisissons 0 et 1.

 

Indice 2 :

Pour simuler un déplacement vers le haut, il faut recopier chaque ligne dans celle du dessous (dans notre tableau). La ligne du bas disparaît.

 

 

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonctions KgetRight KgetLeft

Test conditionnel (« if » et “else” )

Boucle “for”

Tableau à 2 dimensions

 

 


 

 

Exercice E3 : Un jeu de voiture

 

En utilisant la technique vue à l’exercice E2, faire une route qui descend. La route sera symbolisée par deux carrés (bord droit et bord gauche de la route). Largeur de départ = 18 points. Cette route doit osciller de droite a gauche.

Sur la ligne du bas, positionner une balle (la voiture) qui peut être contrôlée avec les touches gauche/droite.

Lorsque la balle touche un bord de route, la partie est perdue. Effacer écran et continuer le jeu.

 

Variante : La largeur de la route peut varier au cours du jeu.

Idée : Pour cela compter le nombre de « rebonds » de la route, lorsque c’est égale à la moitié de la valeur de la largeur de la route, diminuer la taille de la route de 1 et recommencer a compter les rebonds.

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonctions KgetRight KgetLeft

Test conditionnel (« if » et “else” )

Boucle “for”

Tableau à 2 dimensions

Opérateurs + et -

 

 


Série F : Vaisseau & Missile

 

 

 

Exercice F1 : Vaisseau et son missile

 

Un vaisseau (le carré) peut se déplacer sur la ligne du bas, avec les touches droite/gauche.

Il peut tirer (avec la touche A) un missile (une balle). Ce missile se déplacera en ligne droite verticale (a partir de la ou il a été tiré) jusqu’en haut de écran

Le vaisseau peut tirer un seul missile à la fois. C'est-à-dire tant que le missile est visible a écran, le vaisseau ne peut pas tirer (mais il peut se déplacer).

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonction KPrintBall

Fonctions KgetRight KgetLeft KgetSpace

Test conditionnel (« if » et “else” )

Boucle “for”

Opérateurs + et -

 

 

 

 

 

Exercice F2 : Vaisseau et obstacles

 

Poursuivre l’exercice précèdent en ajoutant des obstacles a écran, en utilisant la fonction rand().

Mettre 30 obstacles sur écran Ne pas en mettre sur les 3 dernières lignes.

Le vaisseau peut toujours tirer son missile, si le missile touche un obstacle, l’obstacle est détruit, il disparaît ainsi que le missile. Le vaisseau peut tirer a nouveau

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonction KPrintBall

Fonctions KgetRight KgetLeft KgetSpace

Test conditionnel (« if » et “else” )

Boucle “for”

Opérateurs + et –

Tableau à 2 dimensions

Fonction rand ( rand() ) et modulo (« % »)

Utilisation de #define

 

 

 

 


 

 

Exercice F3 : Vaisseau et obstacles (Bonus)

 

Coloriser le programme F2 en utilisant les nouvelles commandes :

KPrintBar() pour afficher une barre verticale.

KSetDisplayColor(numero_couleur) pour changer la couleur d’affichage.

(C'est-à-dire, tout ce qui sera affiché apres la fonction, sera de la couleur indiquée)

 

Les numéros de couleurs vont de 0 a 6. Des defines ont été mis en place pour faciliter l’utilisation de cette fonction, ils sont :

WHITE (blanc)

RED (rouge)

GREEN (vert)

BLUE (bleu)

YELLOW (jaune)

PURPLE (violet)

CYAN (bleu clair)

 

Pour afficher un carré rouge, une carré bleu et un carré cyan (et puis ensuite tout le reste en blanc) :

 

KSetDisplayColor(RED); // Tout se qui suit sera rouge

KPrintSquare(0,0) ;

KSetDisplayColor(BLUE); // Tout ce qui suit sera bleu (ca annule donc le rouge)

KPrintSquare(1,0) ;

KSetDisplayColor(CYAN); // Tout ce qui suit sera cyan

KPrintSquare(2,0) ;

KSetDisplayColor(WHITE); // Tout ce qui suit sera blanc

 

 

Notions utilisées :

Idem F2

Fonction KPrintBar

Fonction KSetDisplayColor

 

 

 


Série G : Jeu de Snake

 

Ceci est l’exercice final. Il est beaucoup plus long que les autres. Ici nous allons utiliser une structure, définir des fonctions, gérer des chaînes de caractères et faire un jeu complet avec un écran de présentation et un écran de fin.

 

Il est très important de bien décomposer le jeu en petites fonctions. Une somme de petits problèmes est beaucoup plus simple à résoudre qu’un seul gros problème. Pensez bien la structure de votre jeu sur une feuille de papier avant de commencer à programmer.

 

 

 

Exercice G1 :

 

Un serpent de déplace dans écran Il avance tout seul. Le joueur peut diriger la direction de sa tête. Au départ le serpent part tout seul sur la droite. Le serpent doit manger le fruit (carré vert). Chaque fois qu’il mange un fruit il grandi de 2 cases. Un nouveau fruit apparaît a nouveau au hasard sur l’écran (pas dans le cadre et pas dans le serpent). Si le serpent touche les bords ou s’il touche sa queue, c’est perdu. Le serpent peut faire jusqu'à 255 éléments de long.

 

Indice :

Le serpent est stocké dans un tableau de 255 éléments. Le premier élément est la tête, les autres sont le corps en allant jusqu'à la queue. Le premier élément a 0 signifie que le serpent est terminé. Une variable contiendra la taille du serpent.

 

Indice :

A chaque tour de boucle, tous les éléments du tableau sont décalé d’un cran et la nouvelle position de la tête est inséré en début de tableau (suivant la direction donnée par le joueur). Chaque élément du tableau est une coordonnées (on définit pour cela une structure qui contient deux éléments x, y). A chaque tour, la taille nous permet d’effacer l’élément de queue.

 

 

Notions utilisées :

Variables globales (de type int)

Variables locales (de type int)

Fonction KprintSquare

Fonction KPrintBall

Fonctions KgetRight KgetLeft KgetUp KgetDown KgetSpace

Test conditionnel (« if » et “else” )

Boucle “for”

Opérateurs + et –

Tableau à 1 dimension

Fonction rand ( rand() ) et modulo (« % »)

Fonction KsetDisplayColor

Création de fonctions

Utilisation d’une structure

 

 


Amélioration :

 

Faire un écran de présentation et un écran de fin. Afficher la taille du serpent (lancer l’exe du corrigé pour voir ce qu’il faut faire).

 

Indice :

On défini une variable « état » qui dans la boucle principale permets d’exécuter une des trois fonctionne principale du jeu « écran d’intro », « jeu » ou « écran de fin ». Le jeu ne peut avoir qu’un état donc à chaque tour de boucle une seule de ces fonctions sera exécutée. Pour faire des transitions, il suffit donc simplement de changer la valeur de la variable d’état.

 

Indice :

On définir une chaîne de character contenant le texte, avec ‘const char [] = « mon texte »’. Chaque tour de boucle on incrémente un compteur qui indiquera la position actuelle de notre scrolling et on recopie dans une chaîne de caractère locale 30 caractères, que l’on affiche. Lorsque le compteur arrive a la fin de la chaine-30 caractères, alors on reviens a zéro.

 

Notions utilisées supplémentaires:

            Chaîne de caractère constante (de type char) (« const char »)

            Manipulation de chaîne de caractère (« strncpy » « strlen »)