Aller au contenu principal

TP2 - Interfaces Graphiques

Objectifs
  1. Mettre en place des interfaces ;
  2. Programmer des comportements et des actions.
Au préalable
  1. Se créer un dossier Première NSI sur votre ordinateur ou clé USB
  2. Dans ce dossier, créer un dossier Langage_Programmation

Sur EduPython ou autre instance python, faire :

  1. Créer un nouveau fichier en cliquant sur l'icône 📄, ou en appuyant sur CTRL+N
  2. Enregistrer le fichier sous le nom TP2_Interface_Graphique en cliquant sur l'icône 💾, ou en appuyant sur CTRL+S
TP

L'ensemble des exercices se fait sur python.

Pyxel

Pour manipuler des interfaces graphiques, nous allons utiliser la bibliothèque Pyxel, permettant de créer des jeux en 2 dimensions, dans un style rétro (16 bits) :

La bibliothèque est un petit moteur de jeu, comportant un nombre conséquent de fonctionnalités pour créer un jeu.

Installation

Sur Édupython

  • Télécharger l'archive sur ce lien ;
  • Se rendre dans le dossier d'installation Édupython (en général : C://Edupython) ;
  • Se rendre dans App, puis Lib et enfin site-packages ;
  • Copier et coller les 2 dossiers de l'archive dans le dossier site-packages ;
  • Relancer Édupython.

Sur VS Code

  • En partage de connexion (bloqué sur la WiFi du lycée), écrire dans la console pip install pyxel.

Programme principal

Le code minimum de pyxel (et donc a toujours avoir) est celui-ci :

import pyxel                            #On importe la bibliothèque
pyxel.init(longueur, largeur, [titre]) #On initialise la fenêtre suivant une longueur, largeur et un titre (optionnel)

#FONCTIONS OBLIGATOIRES
def update(): #Contiendra toutes les fonctionnalités du jeu (déplacements etc)
pass

def draw(): #Permet de dessiner des éléments à l'écran
pass

pyxel.run(update, draw) #Permet l'exécution en boucle du jeu suivant les fonctions update et draw

Documentation

Voir la page officielle.

FPS

L'interface graphique de pyxel tourne en 30 fps, cela signifie que les fonctions update et draw sont actualisées 30 fois par seconde.

Couleurs

Étant un moteur en 16 bits, il n'existe que 16 couleurs dans la bibliothèque, numérotée de 0 à 15.

Prise en main

Dessiner un carré

import pyxel
pyxel.init(100, 100, "Première NSI - Carré") #Définition de ma fenêtre

def update():
pass

def draw():
#fonction "cls" signifie "clear screen"
pyxel.cls(0) #pyxel.cls(0) : à chaque exécution, toute la fenêtre à la couleur 0 (noir)
pyxel.rect(20,20,15,15,1) #dessine un rectangle au point de coordonnée (20;20), de taille 15x15, de couleur 1
pyxel.run(update, draw)

Déplacer un carré

Pour déplacer un carré, il faut changer ses coordonnées x et y suivant des événements (touches clavier etc) :

import pyxel
pyxel.init(100, 100, "Première NSI - Carré")

#On définit les valeurs des coordonnées du carré
x = 20
y = 20

def update():
global x,y #Signifie que les variables x et y sont accessibles dans la fonction sans paramètres

#pyxel.btn : prend une touche en paramètre et donne True si la donne donnée est pressée
#pyxel.KEY_RIGHT : correspond à la flèche directionnelle droite
if pyxel.btn(pyxel.KEY_RIGHT) : #Si j'appuie sur la flèche directionnelle droite
x+=1 #J'incrémente la coordonnée x

def draw():
pyxel.cls(0)
pyxel.rect(x,20,15,15,1) #Ici, je dessine mon carré suivant la variable x
#Si la variable x est modifiée, comme la fonction s'actualise 30 fois par seconde, le carré se "déplacera"

pyxel.run(update, draw)

À vous !

  1. Compléter le programme pour que le carré se déplace dans tous les sens.
  2. Modifier le programme pour que, lorsque l'on appuie sur la touche espace, le carré change de couleur.

Space Invader

Vous allez créer le jeu du Space Invader avec la bibliothèque.

Reprendre le programme écrit précédemment.
On prendra une fenêtre de taille 128x128, dont le titre sera "Space Invader".

Vaisseau

  1. Le vaisseau sera représenté - pour l'instant - par un carré de taille 8px, de la couleur que vous voulez.
  2. Pour le déplacement, vous mettrez tout ce qui permet au vaisseau de se déplacer dans une fonction appelée déplacement(). Cette fonction sera ainsi appelée dans la fonction update().

Tir du vaisseau

On souhaite représenter les tirs du vaisseau. Ainsi, lorsque l'utilisateur appuie sur la barre espace, un tir doit être créé, qui se déplacera vers le haut de l'écran, et sera supprimé quand il sortira.
Un tir sera représenté par une liste correspondant à ses coordonnées x et y. Ainsi, si mon vaisseau se trouve au point de coordonnée (20,30) et que je tire, dans ma liste de tir j'aurais : [ [20,30] ]. Si je me déplace de 5 pixels sur la droite et que je tire à nouveau, ma liste contiendra : [ [20,30] , [25,30] ].

  1. Créer une liste tirs, initialement vide.
  2. Écrire une fonction creer_tirs() qui permet, lorsque l’on appuie sur la barre espace, d’ajouter dans la liste tirs une liste dont le premier élément sera la position en x et le second élément la position en y du tir.
  3. Appeler cette fonction dans la fonction update().
  4. Dans la fonction draw(), créer pour chaque tir de la liste tirs, un rectangle d’1px d’épaisseur, et 4px de hauteur, avec la couleur numéro 10. Les coordonnées du rectangle créé seront les coordonnées du tir.
  5. Tester l'ajout de tirs en appuyant sur la barre espace. Des rectangles doivent apparaitre.
  6. Écrire une fonction deplacement_tir() qui, pour chaque tir de la liste tirs, réduit leur coordonnée en y de 1.
    Les tirs seront supprimés s’ils sortent de la fenêtre.
    Appeler cette fonction dans update().

Ennemis

Les ennemis fonctionnent de la même façon que pour les tirs. Il y aura une liste ennemis dont chaque élément sera une liste de coordonnées x et y représentant un ennemi.

  1. Créer une liste ennemis, vide, au début du programme.
  2. Écrire une fonction creer_ennemis() qui crée un ennemi toutes les secondes (voir pyxel.frame count%30). La fonction ajoutera dans la liste ennemis une liste avec des points de coordonnées, dont x sera généré aléatoirement.
    Appeler cette fonction dans update().
  3. Dans la fonction draw(), créer pour chaque ennemi de la liste ennemis un carré de 8px, avec la couleur numéro 8.
  4. Écrire une fonction deplacement_ennemis() qui fait la même chose que deplacement_tir(), mais les ennemis vont vers le bas. Appeler cette fonction dans update().

Collisions

  1. Créer une variable vie initialisée à 5, et une variable score à 0.

  2. Afficher le contenu de ces variables en haut de l’écran pour que le joueur ait un visuel.

  3. Écrire une fonction collision_tir() qui permet de supprimer un tir et un ennemi si l’une des coordonnées d’un tir est comprise dans les coordonnées d’un ennemi. Cette fonction augmentera aussi le score de 10.

    Collision

    La collision se fait lorsque la coordonnée en x d’un tir est comprise dans les dimensions d’un ennemi. Ainsi, si un tir est en coordonnées x = 8 y = 10, et qu’un ennemi est en coordonnées x = 5 y = 11, le tir touche car l’ennemi a une taille de 8x8.

  4. Écrire une fonction collision_vaisseau() qui fait la même chose que la fonction précédente, sauf que l’on va vérifier la collision du vaisseau avec un ennemi. S’il y a collision, la vie baissera de 1.

  5. Appeler ces 2 fonctions dans update(). On affichera dans draw() "Game Over" si le joueur n’a plus de vie.