Dans cette activité, nous allons apprendre à déplacer le smiley

Quand vous jouez à un jeu sur votre ordinateur (et que votre ordinateur manque de "puissance"), il arrive parfois que l'affichage saccade (on parle de "lag"), pourquoi ?

Il faut savoir que "l'ordinateur" doit, plusieurs dizaines de fois par seconde (le nombre d'images affichées par seconde est souvent désigné par l'acronyme FPS (Frames per second)), afficher une nouvelle image à l'écran.

Cela demande beaucoup de calculs (complexes) au microprocesseur central (CPU).

Petite parenthèse : c'est d'ailleurs pour cela qu'aujourd'hui, cette tâche est très souvent laissée à un microprocesseur spécialisé dans ce genre de calcul : le GPU (Graphics Processing Unit, ce microprocesseur spécialisé se trouve sur la carte graphique de votre ordinateur). Quand ni le CPU, ni le GPU n'arrivent à afficher suffisamment d'images par seconde, votre jeu saccade.

En matière de programmation, il faut, une fois que la nouvelle image est prête à être à afficher (après par exemple avoir bougé de quelques pixels le personnage principal), envoyer l'ordre au CPU d'afficher cette nouvelle image (après avoir fait tous les calculs nécessaires).

On retrouve ici le principe du dessin animé : l'ordinateur affiche à l'écran une succession d'images fixes, si la fréquence d'affichage est assez importante (30 FPS pour que cela paraisse fluide), l'utilisateur aura l'illusion du mouvement.

Nous allons donc devoir, plus de 30 fois par seconde :

Pour souci de clarté, nous allons placer le code gérant l'affichage dans une fonction "animation"

L'appel à cette fonction devra se faire au moins 30 fois par seconde. Nous placerons donc l'appel à cette fonction dans la boucle while (boucle de jeu)

Voici le code :


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygame,sys
from pygame.locals import *
#début fonction animation
def animation():
    fen.fill(0)
    fen.blit(monSmiley,(0,280))
    pygame.display.flip()
#fin de la fonction animation
pygame.init()
fen = pygame.display.set_mode((800, 600))
monSmiley = pygame.image.load("asset/smiley.png").convert_alpha()
while True :
    animation()
    for event in pygame.event.get():
        if event.type==QUIT:
            pygame.quit()
            sys.exit()
			

Il nous reste un problème à gérer : la boucle while sera exécutée le plus rapidement possible par le CPU, le nombre d'images par seconde dépendra donc de la puissance de notre ordinateur. Pour éviter tout problème d'affichage, Pygame permet de mettre en place un système qui limite le nombre de fois où la boucle est exécutée par seconde :

Il nous faut rajouter deux lignes à notre programme :

À faire vous-même 3.1

Saisissez, analysez et testez ce code


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygame,sys
from pygame.locals import *
#début fonction animation
def animation():
    fen.fill(0)
    fen.blit(monSmiley,(0,280))
    pygame.display.flip()
#fin de la fonction animation
pygame.init()
fen = pygame.display.set_mode((800, 600))
clock=pygame.time.Clock()
monSmiley = pygame.image.load("asset/smiley.png").convert_alpha()
while True :
    animation()
    clock.tick(60)
    for event in pygame.event.get():
        if event.type==QUIT:
            pygame.quit()
            sys.exit()
			

Le système attendra donc 1/60 s (17 ms) avant d'exécuter une nouvelle fois la boucle while

Pour l'instant, le fait d'avoir mis en place un système pour l'animation ne change strictement rien au niveau du résultat. En effet, à chaque appel de la fonction animation, les coordonnées du smiley ne changent pas.

À faire vous-même 3.2

Modifiez le code du "À faire vous-même 3.1" pour que le smiley se déplace de gauche à droite horizontalement.

Une petite parenthèse semble nécessaire afin de vous aider un peu :

Analysez et testez ce programme


#!/usr/bin/env python
# -*- coding: utf-8 -*-
i=5
def f():
    i=6
f()
print("la valeur de i est : "+str(i))
			

Vu que la fonction f est appelée juste avant le print et que cette fonction attribut la valeur 6 à la variable i, on pourrait penser que le résultat du print sera : "la valeur de i est : 6"

Pourtant, nous avons "la valeur de i est : 5", comme si l'exécution de la fonction f n'avait eu aucun effet, pourquoi ?

i est une variable globale, elle a été définie en dehors de toute fonction. La fonction f peut "utiliser" la variable i, mais ne peut pas la modifier.

Pour pouvoir modifier la valeur de i dans la fonction f, il faudra définir i comme global dans la fonction :


#!/usr/bin/env python
# -*- coding: utf-8 -*-
i=5
def f():
    global i
    i=6
f()
print("la valeur de i est : "+str(i))
		

Cela fonctionne, il est maintenant possible de modifier la valeur de i dans la fonction f.

Tout ceci est en fait un peu plus complexe, mais cette activité n'étant pas un cours sur la portée des variables, nous n'irons pas plus loin sur ce sujet, si vous voulez en savoir plus, je vous conseille de lire ce cours