10
DELL Quentin TS 01/06/2013 Projet ISN 1 Projet ISN Lycée Louis Marchal Année 2012/2013

Projet ISN - ISN-Marchalisn-marchal.com/site/dossier.pdf · Cette année scolaire, en terminale S, option ISN, le choix du projet à présenter était libre. Ce projet est codé par

Embed Size (px)

Citation preview

DELL Quentin TS 01/06/2013 Projet ISN

1

Projet ISN

Lycée Louis Marchal Année 2012/2013

DELL Quentin TS 01/06/2013 Projet ISN

2

Sommaire

I/ Introduction Page 3 II/ Principe du jeu Page 3 III/ Réalisation du jeu Page 4-6

1. Répartition des tâches Page 4 2. Explications des fonctions codées Page 4-6 3. Problème rencontrés Page 6

IV/ Conclusion Page 6 Annexes Page 7-9

DELL Quentin TS 01/06/2013 Projet ISN

3

I/ Introduction Cette année scolaire, en terminale S, option ISN, le choix du projet à présenter était libre. Ce projet est codé par des groupes de 2 à 3 personnes. Il est codé en Python. Nous utilisons l’éditeur Pyscripter pour le coder, ainsi que l’extension Pygame, qui a une meilleure gestion de l’affichage graphique. Pour ma part je me suis associé avec Léa REEB. Notre projet était de faire un jeu du type « line runner ». Ce type de jeu consiste à faire sauter un petit personnage appelé un stickman pour éviter de se prendre des obstacles. Le score est en général en fonction des mètres parcourus ou du temps. Pour notre projet nous avons décidé de le faire en fonction du temps. Notre programme est constitué de 3 parties :

- le programme « Projet.py » : l’outil principal - les 3 images : permettant d’avoir l’affichage graphique - le document texte « record.txt » : permettant de sauvegarder les scores.

Pour faire tourner le jeu, il faut avoir installé le langage Python ainsi que Pygame sur son ordinateur et avoir les 3 parties citées ci-dessus.

II/ Principe du jeu

Dans notre jeu, une petite boule noire, faisant office de stickman, est le personnage principal. Le but du jeu est simple : il suffit de faire sauter la petite boule noire au-dessus des trous pour que celle-ci puisse continuer à rouler le plus longtemps possible. Pour faire sauter la boule il faut appuyer sur la touche espace du clavier. La boule noire reste à la même position sur l’écran, elle ne fait que monter et descendre afin de pourvoir sauter. C’est le paysage qui défile et non pas la boule qui se déplace sur l’écran. Les trous arrivent de façon aléatoire. Plus le joueur arrive à sauter au-dessus des pièges, plus la vitesse du défilement augmente, le jeu devient ainsi de plus en plus difficile. Le jeu est terminé lorsque la boule noire tombe dans un trou, le temps s’affiche et une indication montre si le joueur a battu ou non l’ancien record.

Piège

Chronomètre

Axe des abscisses (x)

Boule

Axe des ordonnées

(y)

DELL Quentin TS 01/06/2013 Projet ISN

4

III/ Réalisation du jeu

1. Répartition des tâches Au début du projet, afin de bien comprendre le squelette du jeu, Léa et moi, avons

commencé à coder ensemble. Je me suis occupé de différentes fonctions :

- depiege : cette fonction permet de faire défiler les pièges - reset_piege : cette fonction permet de remettre le piège au début, soit tout à droite - active_piege : cette fonction vérifie s’il y a déjà un piège, s’il n’y en a pas alors

elle prend un nombre aléatoire, si celui si vaut un alors un piège commencera à défiler sur l’écran.

- chronometre : cette fonction est un chronomètre permettant d’obtenir le temps du joueur

- aff_chrono : cette fonction permet d’afficher le chronomètre lorsque le joueur joue - de la collision entre la boule et le trou.

Léa s’est occupée des fonctions suivantes :

- saut : cette fonction permet de faire sauter le personnage - desaut : cette fonction permet de faire retomber le personnage - defilement : cette fonction permet de faire défiler le fond - écrire le score dans un fichier et de le comparer pour voir s’il s’agit d’un meilleur

score.

2. Explications des fonctions codées

Nous avons commencé par coder la partie principale : Tout d’abord nous avons commencé par charger les modules que nous allons utiliser. Ensuite, nous avons mis au programme principal un « try » qui se termine par « finally » ce qui permet de quitter le jeu sans le faire planter. On commence par initialiser Pygame, puis on définit la taille de la fenêtre de jeu. Ensuite on charge les images : le fond, le personnage et le trou. Le .convert_alpha() permet de rendre le blanc transparent et .convert() qui permet de rendre l’affichage au bon format. Ensuite avec la fonction Pygame.rect (position en largeur, en hauteur, taille de l’image en largeur, en hauteur) nous avons pu donner la position de la petite boule noire sachant que les coordonnées correspondent au coin en haut à gauche de l’image.

a. Chronomètre

J’ai d’abord commencé par coder la fonction chronomètre : Cette fonction prend une variable appelé Start_Time qui est le temps depuis lequel le joueur a commencé à jouer. Puis on soustrait time.time(), qui est l’heure de l’horloge de l’ordinateur, par Start_Time. Ceci est enregistré dans la variable Actual_Time qui est le temps actuel de jeu. A la fin, on retourne la valeur de la variable Actual_Time afin de pouvoir la réutiliser dans la fonction permettant d’afficher le chronomètre.

DELL Quentin TS 01/06/2013 Projet ISN

5

J’ai ensuite continué avec la fonction permettant d’afficher le chronomètre (aff_chrono) : cette fonction reprend la variable Actual_Time qui servira plus tard. Tout d’abord on définit la taille et le style de l’écriture via la variable fond. On définit ensuite la variable text, elle est composée d’Actual_Time puis d’un 2 qui limite les chiffres après la virgule à 2. Ensuite, on choisit la couleur du texte en RVB. Puis on définit la position du texte avec la variable textpos qui est un rectangle, puis on centre le texte en x et on colle sur le fond.

b. Pièges

Après avoir réalisé le chronomètre j’ai commencé à coder les pièges. J’ai débuté par la fonction active_piege qui permet de générer aléatoirement le piège : la fonction commence par acquérir la variable PiegeActif qui est à 0 au début, dès qu’il n’y a pas de piège sur l’écran. Ensuite, si aucun piège n’est présent, on génère un nombre aléatoirement entre 0 et 11, s’il vaut 1 alors on génère un piège, la variable PiegeActif prend la valeur : 1, s’il vaut une autre valeur alors la valeur du PiegeActif reste à 0. Pour le moment le piège n’est pas visible. J’ai codé la fonction permettant le défilement du piège : la fonction prend l’image du piège ainsi que la variable contenant la position du piège. On prend ensuite la variable de la position du piège appelé pos_piege que l’on déplace de 10 pixels vers la gauche ce qui correspond au -10 dans pos_piege.move(-10,0). On colle ensuite l’image sur le fond puis on retourne la variable pos_piege afin de permettre au piège de se déplacer lorsque la boule saute. Par contre il manque une fonction permettant de remettre le piège à sa position initiale, je me suis donc occupé de cette fonction nommée reset_piege : Cette fonction reprend la variable pos_piege pour la réinitialiser ; il faut la remettre à la position 640 en abscisse et 355 en ordonnée. Puis la fonction retourne cette position ainsi que la valeur 0 que prend ActivePiege. Pour augmenter la difficulté, j’ai défini le time.delay, qui est le temps d’attente avec une variable. Cette variable change lorsque l’on passe deux pièges. Le temps d’attente étant réduit, le jeu défilera plus rapidement.

c. Défilement du paysage

Pour faire défiler le paysage, il faut d’abord charger deux fois la même image de fond afin qu’il y en a toujours une qui défile. Ensuite on prend la valeur de fondrect et fondrectbis qui sont les positions des fonds. On les déplace de -10 avec la fonction move(-10,0), soit suivant l’axe des abscisses afin qu’ils se déplacent à la même vitesse. Puis on vérifie s’il y a ou non un fond qui a entièrement défilé, en regardant la position du rectangle. Si un fond à entièrement défilé on le remet au début. Puis on termine la fonction en « collant » les fonds et en retournant leurs positions pour pouvoir les utiliser en dehors d’une boucle comme celle du saut par exemple. Cette fonction est à mettre en « première » dans la boucle saut afin de coller les autres images sur le fond et non pas l’inverse.

DELL Quentin TS 01/06/2013 Projet ISN

6

d. Saut

Pour faire sauter le personnage, on prend l’image de la boule ainsi que sa position. On ajoute -10 en « y » afin de le faire monter. Puis on le colle et on retourne sa position, puis on insert cette fonction dans une boucle for i in range(10) afin de répéter l’action 10 fois. Pour la fonction permettant de faire descendre le personnage après le saut, il suffit de remplacer le -10 par 10.

3. Problème rencontrés

Au début du projet, quand nous tentions de faire sauter le personnage, le saut était trop rapide au point que nous ne le voyons pas. Pour cela nous avons rajouté un délai grâce à la fonction « time.delay ». Ensuite lorsque nous pouvions voir la boule sauter, il y avait la « trace » de la boule, ceci était lié au fait que l’on n’avait pas recollé le fond après le passage de la boule. Notre second problème fut lors de la création du défilement : dès que le fond arrivait au bout il laissait une trace comme la boule, car il n’y avait pas de deuxième fond pour prendre la relève. Donc nous avons rajouté un fond. Enfin, lors du codage des pièges, lorsque le personnage sautait le piège se remettait à la position avant le saut. Pour cela j’ai intégré la fonction depiege dans la boucle qui faisait sauter la boule.

IV/ Conclusion Durant cette année en ISN j’ai appris à coder un site internet ainsi qu’un jeu. Pour cela il était nécessaire de connaître plusieurs langages : HTML, CSS ainsi que le Python. A travers le codage du jeu j’ai appris énormément, j’ai vu des fonctions que je ne connaissais pas et découvert des solutions à des problèmes. Néanmoins il persiste un problème : le trou se déplace en arrière lorsque que la boule saute à répétition. Il reste aussi à faire une page d’accueil du jeu ainsi qu’un tableau des scores plus performant. On pourrait perfectionner le jeu en rajoutant des pièges : des pics ou des rochers. La possibilité de changer de décors au bout d’un certain moment serait également envisageable. Ce projet d’ISN était plaisant à faire et m’a donné goût à la programmation. Ceci m’a motivé à poursuivre mes études en DUT Informatique. Site internet : http://infinitylinerun.pusku.com/

DELL Quentin TS 01/06/2013 Projet ISN

7

Annexes Code du jeu : import pygame from pygame .locals import * from random import randrange import time # Importe la fonction temps

def saut (stick ,pos_stick ): """ Fonction permettant au joueur de sauter""" pos_stick =pos_stick .move(0,-10) # Saut du personnage fenetre .blit (stick ,pos_stick ) return pos_stick

def desaut (stick ,pos_stick ): """ Fonction permettant de faire retomber le person nage""" pos_stick =pos_stick .move(0,10) # retomber du personnage après un saut fenetre .blit (stick ,pos_stick ) return pos_stick

def depiege (piege ,pos_piege ): """ Fonction permettant de faire défiler les pièges """ pos_piege =pos_piege .move(-10,0) fenetre .blit (piege ,pos_piege ) return pos_piege

def reset_piege (pos_piege ): """Fonction permettant de remmetre le piège au débu t""" return pygame .Rect (640,355,50,50),0

def active_piege (PiegeActif ): """Fonction permettant d'activer ou non le piège""" if PiegeActif ==0: if randrange (0,11)==1: return 1 else: return 0 return 1

def defilement (fond ,fondrect ,fondrectbis ): """ Fonction permettant de faire défiler les pièges """ fondrect = fondrect .move (-10,0) # On déplace les deux fonds fondrectbis = fondrectbis .move(-10,0) if fondrect == pygame .Rect (-640,0,640,480): fondrect = pygame .Rect (640,0,640,480) if fondrectbis == pygame .Rect (-640,0,640,480): fondrectbis = pygame .Rect (640,0,640,480) fenetre .blit (fond , fondrect ) fenetre .blit (fond , fondrectbis ) return fondrect ,fondrectbis

DELL Quentin TS 01/06/2013 Projet ISN

8

def chronometre (Start_Time ): """Fonction chronomètre""" Actual_Time =time .time ()-Start_Time # On importe le temps du début et on le soustrait au temps actuel return Actual_Time

def aff_chrono (Actual_Time ): """Fonction permettant d'afficher le temps de jeu"" " font = pygame .font .Font (None, 36) text = font .render (str (round (Actual_Time ,2)), 1, (0, 255, 0)) textpos = text .get_rect () textpos .centerx = fenetre .get_rect ().centerx fenetre .blit (text , textpos )

try: pygame .init () pygame .font .init () fenetre = pygame .display .set_mode ((640, 480))

# Charger et coller les images: fond = pygame .image .load ("background.jpg" ).convert () fenetre .blit (fond , (0,0)) stick = pygame .image .load ("point.png" ) stick =stick .convert_alpha (stick ) pos_stick = pygame .Rect (105,330,40,40) #Abscisse, ordonnée, longeur, hauteur fenetre .blit (stick ,pos_stick ) piege =pygame.image .load ("trou.png" ) piege =piege .convert_alpha (piege ) pos_piege =pygame.Rect (640,360,50,50)

# On position les deux fonds, qui sont les mêmes fondrect = pygame .Rect (0,0,640,480) fondrectbis = pygame .Rect (640,0,640,480) fenetre .blit (fond , fondrect ) fenetre .blit (fond , fondrectbis )

continuer = 1 #On initialise les variables PiegeActif =0 vitesse =30 # Le temps d'attente du delay rapidite =0

Start_Time =time .time () # On démarre le chronomètre

while continuer : fondrect ,fondrectbis =defilement (fond ,fondrect ,fondrectbis )

PiegeActif =active_piege (PiegeActif ) if PiegeActif ==1 and pos_piege .x>-50: # On vérifie si le piege est présent pos_piege =depiege (piege ,pos_piege ) elif pos_piege .x<-40 and PiegeActif ==1: # On vérifie si le piège n'est plus sur l'écran pos_piege ,PiegeActif =reset_piege (pos_piege )

DELL Quentin TS 01/06/2013 Projet ISN

9

rapidite =rapidite +1

if rapidite ==2: # Lorsqu'on passe 5 piège, la vitesse augmente vitesse =int (vitesse *(9/10)) rapidite =0

fenetre .blit (stick ,pos_stick ) # On recolle le stick sur le fond

if pos_piege .x-5 == pos_stick .x and pos_stick .y==330 or pos_piege .x+45 == pos_stick .x and pos_stick .y==330: # On vérifie si le joueur ne tombe pas dans le trou print("Game Over" ) continuer =0 Temps =round (Actual_Time ,2) fichier =open("record.txt" ,"r" ) fichier .read () fichier .seek (0) score =fichier .readline () if float (Temps)>float (score ): fichier .seek (0) print("Le nouveau record est de : " ,Temps) print("L'ancien record était de : " ,fichier .read ()) score =Temps score =str (score ) fichier .close () fichier =open("record.txt" ,"w" ) fichier .write (score ) fichier .close () else: print("Votre temps est de : " ,Temps) fichier .seek (0) print("Vous n'avez pas battu le record qui est de : " ,fichier .read ()) fichier .close ()

Actual_Time =chronometre (Start_Time ) aff_chrono (Actual_Time ) # On affiche le temps

pygame .display .flip () pygame .time .delay (vitesse )

for event in pygame .event .get (): if event .type == QUIT : #Permet de quitter en appuyant sur la croix continuer = 0 if event .type == KEYDOWN: if event .key == K_SPACE: # Faire sauter le personnage for i in range (10):

fondrect ,fondrectbis =defilement (fond ,fondrect ,fondrectbis )

pos_piege =depiege (piege , pos_piege ) pos_stick =saut (stick ,pos_stick ) Actual_Time =chronometre (Start_Time ) aff_chrono (Actual_Time ) pygame .display .flip () pygame .time .delay (vitesse )

DELL Quentin TS 01/06/2013 Projet ISN

10

for i in range (10):

fondrect ,fondrectbis =defilement (fond ,fondrect ,fondrectbis )

pos_piege =depiege (piege , pos_piege ) pos_stick =desaut (stick ,pos_stick ) Actual_Time =chronometre (Start_Time ) aff_chrono (Actual_Time ) pygame .display .flip () pygame .time .delay (vitesse )

while event in pygame .event .get (): continue # Vide l'événement afin de ne pas sauter à répétition finally: pygame .quit ()