1. Pong
Pong est un des premiers jeux vidéo d’arcade et le premier jeu vidéo d’arcade de sport. Il a été imaginé par l’Américain Nolan Bushnell et développé par Allan Alcorn, et la société Atari le commercialise à partir de novembre 1972. Bien que d’autres jeux vidéo aient été inventés précédemment, comme Computer Space, Pong est le premier à devenir populaire.
Le jeu est inspiré du tennis de table en vue de dessus, et chaque joueur s’affronte en déplaçant la raquette virtuelle de haut en bas, via un bouton rotatif, de façon à garder la balle dans le terrain de jeu. Le joueur peut changer la direction de la balle en fonction de l’endroit où celle-ci tape sur la raquette, alors que sa vitesse augmente graduellement au cours de la manche. Un score est affiché pour la partie en cours et des bruitages accompagnent la frappe de la balle sur les raquettes.
Pong est à l’origine un exercice demandé par Bushnell à Alcorn en guise d’entraînement. Une version similaire a été créée précédemment par Ralph Baer pour la console de jeu Odyssey de Magnavox, mais son existence reste peu connue. Surpris par la qualité du résultat, Bushnell et Ted Dabney, fondateurs d’Atari, décident de commercialiser le jeu dès 1972. La copie du concept entraîne d’ailleurs une poursuite en justice de Magnavox contre Atari pour violation de brevet en 1976.
Mise sur le marché fin 1972, la borne d’arcade est un succès : elle est vendue à près de 8 000 exemplaires l’année suivante et engrange jusqu’à 40 millions de dollars de chiffres d’affaires en 1975, dépassant toutes les prédictions de Bushnell et Dabney. Ce succès incite de nombreuses sociétés à se lancer dans le jeu vidéo en copiant le concept, notamment sur console de salon. À la suite des bons chiffres de la borne d’arcade et de l’engouement généré par les concurrents pour le jeu de salon, Pong est porté sur une console de salon dédiée, sous le nom Home Pong à partir de 1975, commercialisée par Sears puis directement par Atari un an après. Ce double succès est considéré comme l’évènement précurseur de l’industrie du jeu vidéo, avec une forte augmentation de l’offre, des centaines de consoles de salon reprenant le concept.
https://fr.wikipedia.org/wiki/Pong
2. Objectif
Notre objectif est de développer une version Python de ce jeu en s’appuyant sur les concepts de programmation que nous avons appris jusqu’à maintenant :
-
Utilisation de modules
-
les fonctions
-
les dictionnaires
-
les tests conditionnels
-
les boucles
Notre jeu se limitera à un joueur unique. Cette version du jeu est connue sous le nom Pong Survivor ou Single Player Pong
Le développement du jeu est basé sur l’utilisation de la bibliothèque Pygame
3. Au travail…
-
Sur github classroom, clonez le dépot
PythonSinglePlayerPong
: https://classroom.github.com/a/P-ZwpAK5 -
Créez un nouveau projet associé à votre dépot dans votre environnement de développement sur Pycharm ou sur repl.it (new repl Python
-
Ne pas oublier de comiter puis de pousser le code après chaque étape du développement.
3.1. Pygame
3.1.1. Qu’est ce que c’est ?
Pygame est une bibliothèque libre multiplate-forme qui facilite le développement de jeux vidéo temps réel avec le langage de programmation Python.
Elle est distribuée selon les termes de la licence GNU LGPL.
Construite sur la bibliothèque SDL, elle permet de programmer la partie multimédia (graphismes, son et entrées au clavier, à la souris ou au joystick), sans se heurter aux difficultés des langages de bas niveaux comme le C et ses dérivés. Cela se fonde sur la supposition que la partie multimédia, souvent la plus contraignante à programmer dans un tel jeu, est suffisamment indépendante de la logique même du jeu pour qu’on puisse utiliser un langage de haut niveau (en l’occurrence le Python) pour la structure du jeu.
Pygame, en plus d’adapter la SDL au Python, fournit également un petit nombre de fonctions spécifiques au développement de jeux.
On peut aussi remarquer que Pygame n’est plus utilisée exclusivement pour des jeux vidéo, mais également pour des applications diverses nécessitant du graphisme.
https://fr.wikipedia.org/wiki/Curses
3.1.2. Utilisation
Utilisation basic de Pygame
Les méthodes principales sont très simples :
|
3.1.3. Codage d’une fenêtre de jeu
-
Ouvrez le fichier
pong1.py
-
Modifiez le programme pour que la fenêtre ait pour dimensions 600x400
-
Modifez le titre de la fenêtre : "My Single Player Pong"
-
Changez la couleur du fond en noir
Le jeu est contenu dans une boucle qui s’achève lorsque le booléen end
est vrai, ce qui arrivera lorsque le joueur cliquera sur la croix de fermeture de la fenêtre (événement QUIT
).
import pygame
pygame.init()
WIDTH = 300
HEIGHT = 200
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('My Game')
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 255)
screen.fill(RED)
pygame.display.update()
end = False
while not end:
for event in pygame.event.get():
if event.type == pygame.QUIT:
end = True
pygame.quit()
3.2. Ajouter une forme
Pygame permet de dessiner des formes élémentaires comme des rectangles, des cercles, …
Nous allons maintenant dessiner un cercle qui servira plus tart à la représentation de la balle :
-
Ouvrez le fichier
pong2.py
-
Ajouter un cercle rempli de couleur blanche de rayon
radius
, en plein centre de la fenêtre de jeu.
radius = 25
pygame.draw.circle(___, ___, (___, ___), ___)
3.3. Gérer les événements
Le contôle du jeu est assuré par les touches de direction LEFT, RIGHT et Escape pour quitter la partie en cours. On ajoute généralement une touche pour assurer la mise en pause du jeu. Ce rôle est souvent attribué à la touche SPACE. On utilisera également la touche ENTER pour reprendre la partie.
Commençons par découvrir comment acquérir et gérer les événements liés à l’utlisation des touches :
3.3.1. Gestion des touches du clavier
Le type d’événement créé lorsque l’on appuie sur une touche est Le module Il fourni également des constantes qui identifies toutes les touches du clavier : Lettres: K_a ... K_z Nombres: K_0 ... K_9
|
-
Ouvrez le fichier
pong3.py
-
Codez l’utilisation des touches A, Z, Q et S pour déplacer le cercle dans la fenêtre de jeu :
-
A : dans le coin supérieur gauche
-
Z : dans le coin supérieur droit
-
Q : dans le coin inférieur gauche
-
S : dans le coin inférieur droit
-
3.3.2. Déplacement d’un objet
Comme nous venons de le voir, déplacer le cercle revient à calculer les coordonnées
|
Les variations de positions sur les axes x
et y
sont nommées dans le schéma ci-dessous : Δx
et Δy
La durée de la boucle est définie par la durée des actions à exécuter et à l’attente qu’on lui imposera avant de recommencer. Cette attente est obtenue par l’uilisation de la méthode |
Comme vous avez du l’apprendre en Sciences Physique :
Si l’on choisi de déplacer identiquement sur les deux axes notre cercle, les quantités Comme la durée d’une itération de boucle est fixée, la vitesse ne dépend que de cette quantité. On peut donc établir les nouvelles coordonnées du centre du cercle comme suit :
Le sens de déplacement est matérialisé par l’opérateur
ce qui donne les équations :
|
-
Ouvrez le fichier
pong4.py
-
Complétez le code pour que le cercle puisse se déplacer manuellement comme précédemment et en utilisant également les touches UP, DOWN, RIGHT et LEFT pour générer des déplacements fins. Le cercle doit s’arrêter lorsqu’il est en contact avec un bord.
-
Complétez le code pour que le cercle puisse se déplacer automatiquement lorsque l’on a utilisé la touche O (O comme Automatique !) et manuellement lorsqu’on utilise la touche kbd[M] (M comme Manuel !)
Attention : Il faudra gérer les rebonds sur les bords !
speed = 1
x_sens = y_sens = 1
auto = True
end = False
while not end:
SCREEN.fill(RED)
for event in pygame.event.get():
if event.type == pygame.QUIT:
end = True
key = pygame.key.get_pressed()
if key[pygame.K_o]:
auto = ___
if key[pygame.K_m]:
auto = ___
if not auto:
# Manual mode :
# - use A, Z, Q, S to move circle on the corners
# - use UP, DOWN, LEFT, RIGHT to move circle by <speed> pixel
else:
# if the circle touches the right and left edges
# reverse direction on x-axis
if ____:
x_sens = ____
# if the circle touches the lower and upper edges
# reverse direction on y-axis
if ___:
y_sens = ___
# compute new coordonates
x = x + ___
y = y + ___
pygame.draw.circle(SCREEN, WHITE, (x, y), radius)
pygame.display.update()
# wait before trying it again
pygame.time.delay(10)
pygame.quit()
3.4. Première version
3.4.1. Le jeu brut
On sait maintenant :
-
Créer une fenêtre de jeu
-
Dessiner une forme
-
Contrôler les déplacements
Il ne nous reste plus qu’à dessiner une raquette (un simple rectangle), gérer des déplacements et les collisions avec la balle. Si la balle ne touche pas la raquette lorsqu’elle est en bas, le jeu s’arrête.
-
Ouvrez le fichier
pong5.py
-
Modifiez les caractéristiques de la fenêtre de jeu : Fond noir, dimensions 800*600
-
Modifiez les caractéristiques de la balle pour quelle soit blanche et de rayon 10 pixels
-
Modifiez les coordonnées de départ de la balle pour qu’elle tombe depuis le haut de l’écran au milieu
-
Ajouter un rectangle de couleur bleu et de dimensions 200x20 centré en bas de la fenêtre de jeu. Les caractéristiques de ce rectangle seront rassemblées dans un dictionnaire :
paddle = {}
-
Ajoutez dans les contrôles du jeu un mode pause accessible avec la touche SPACE. La reprise du jeu se fait avec la touche ENTER
-
Ajoutez le contrôle de la raquette à l’aide des touches LEFT et RIGHT. La raquette ne doit pas sortir de la fenêtre de jeu.
-
Gérez les collisions avec les bords de gauche, du haut et de droite qui doivent occasionner un rebond.
-
Gérez les collisions avec la raquette qui doit également occasionner un rebond, sinon le jeu s’arrête.
3.4.2. Améliorations
Le jeu fonctionne mais il n’est pas très pratique :
-
Il démarre dès l’exécution du programme : panique !
-
On n’a pas d’indicateur de réussite
Il nous faut donc ajouter du texte pour :
-
Retarder le démarrage de la partie avec un décompte par exemple : 3… 2… 1… 0 secondes.
-
Afficher un score qui pourrait être défini comme le nombre de balles sauvées.
-
Ouvrez le fichier
pong6.py
-
Observez l’utilisation des méthodes :
-
SysFont()
du modulefont
-
render()
de l’objetmyfont
-
blit()
de l’objetscreen
-
-
Identifiez le rôle de chaque méthode pour afficher un texte à un emplacement particulier de l’écran, dans une police, une taille et une couleur spécifique.
-
Ajoutez le décompte des secondes 3… 2… 1… 0 avant le démarrage du jeu
-
Ajouter l’affichage du score qui doit être incrémenté chaque fois que la balle tape la raquette.
import pygame
pygame.init()
...
myfont = pygame.font.SysFont('monospace', 50)
print("pong6")
screen.fill(BLACK)
title = myfont.render("Single Player Pong:", False, GREEN)
screen.blit(title, (WIDTH // 2 - title.get_width() // 2, HEIGHT // 2 - title.get_height() * 2))
pygame.display.update()
pygame.time.delay(1000)
# countdown before start game
# loop from 3 to 0 and write the number in the middle of the screen
???
...
pause = False
end = False
while not end:
screen.fill(BLACK)
# Control the game
# Past your code from pong5.py
pygame.draw.circle(screen, WHITE, (x, y), radius)
pygame.draw.rect(screen, paddle["color"], (paddle["x"], paddle["y"], paddle["width"], paddle["height"]))
# Display the score in position (10, 0) (top left on the screen)
pygame.display.update()
pygame.time.delay(10)
# Wait a bit to be sure the player knows his score
pygame.time.delay(2000)
pygame.quit()
3.5. Deuxième version
3.5.1. On complique un peu le jeu ?
Il y a plusieurs façon de compliquer le jeu. En modifiant la géométrie de l’aire de jeu (compliqué) ou plus simplement en accélérant la balle en cours de jeu, ou encore en diminuant la taille de la raquette. C’est ce que nous allons faire ici.
-
Toutes les 5 balles sauvées, la vitesse est incrémentée
-
Toutes les 10 balles sauvées, la taille de la raquette est diminuée de 20 pixels sans accélérer la balle.
3.5.2. Garder le meilleur score
Le jeu s’arrête dès que le joueur a perdu. Donnons au joueur la possibilité de rejouer et conservons au passage le meilleurs score :
-
La touche R doit être utilisée pour rejouer.
4. On joue !
Amusez vous, quand vous en aurez assez, modifiez le scénario, par exemple, vous pouvez :
-
ajouter un peu d’aléatoire dans les rebonds de la balle sur le bord supérieur de la fenêtre de jeux,
-
offrir au joueur la possibilité de doubler son score en faisant apparaite une balle bonus rouge avec une probabilité d’une chance sur 10,
-
…. Faites preuve d’imagination !