Projet ISN - ISN

Transcription

Projet ISN - ISN
DELL Quentin
TS
Projet ISN
01/06/2013
Projet ISN
Lycée Louis Marchal
Année 2012/2013
1
DELL Quentin
TS
Projet ISN
01/06/2013
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
2. Explications des fonctions codées
3. Problème rencontrés
Page 4
Page 4-6
Page 6
IV/ Conclusion
Page 6
Annexes
Page 7-9
2
DELL Quentin
TS
Projet ISN
01/06/2013
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.
Axe des abscisses (x)
Chronomètre
Axe des
ordonnées
(y)
Boule
Piège
3
DELL Quentin
TS
Projet ISN
01/06/2013
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.
4
DELL Quentin
TS
Projet ISN
01/06/2013
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.
5
DELL Quentin
TS
Projet ISN
01/06/2013
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/
6
DELL Quentin
TS
Projet ISN
01/06/2013
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 personnage"""
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ébut"""
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
7
DELL Quentin
TS
Projet ISN
01/06/2013
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)
8
DELL Quentin
TS
Projet ISN
01/06/2013
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,fondr
ectbis)
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)
9
DELL Quentin
TS
Projet ISN
01/06/2013
for i in range(10):
fondrect,fondrectbis=defilement(fond,fondrect,fondr
ectbis)
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()
10

Documents pareils