Author: Victor E.

Projets

Jeu vidéo en Python à l’aide de la librairie…

Dans le cadre du projet libre de fin d’année en NSI, je vous présente mon premier jeux vidéo en python fait à l’aide de pygame, une librairie spécialisé pour la création de jeux vidéo.

Librairie Pygame

Pygame est une bibliothèque de jeu open-source pour Python, qui permet de créer des jeux et des applications multimédias. Elle fournit des outils pour gérer les graphismes, le son, les entrées utilisateur, le réseau et plus encore.

Pygame utilise la bibliothèque SDL (Simple DirectMedia Layer) pour accéder aux fonctions du système d’exploitation, ce qui signifie que les jeux créés avec Pygame peuvent fonctionner sur de nombreuses plateformes, notamment Windows, macOS et Linux.

Pygame est une excellente option pour les débutants qui cherchent à créer des jeux simples (des base en programmation sont cependant nécessaire), mais il peut également être utilisé pour créer des jeux professionnels et des applications multimédias complexes.

Le Projet

Mon objectif sur ce projet a été de faire mes premiers pas avec la bibliothèque Pygame en Python. Cela a été un véritable défi qui m’aura fait découvrir de nombreuses mécaniques en Python, telles que le système de classe ou la programmation orientée objet, qui ont représenté pour moi un pas dans l’inconnu. Mon défi a donc été de créer un jeu simple pour débuter. Le but est de contrôler un personnage avec sa souris et d’éviter des briques qui apparaissent aléatoirement sur le côté de l’écran, tout cela en ayant le choix entre trois niveaux de difficulté différents.

Structure du Script

Pour la réalisation de mon jeu, j’ai décidé de me lancer un défi supplémentaire : l’utilisation de la Programmation Orientée Objet. Mais qu’est-ce que la Programmation Orientée Objet ?

La Programmation Orientée Objet est un paradigme de programmation qui permet de structurer un programme en utilisant des objets, qui sont des entités possédant des caractéristiques et des comportements spécifiques. Cette approche permet de modéliser des concepts du monde réel de manière plus naturelle et intuitive, en regroupant des fonctionnalités liées dans des classes, et en instanciant ces classes pour créer des objets.

En résumé, cela consiste à organiser son code de manière à ce qu’il soit ordonné à l’aide de classes contenant des fonctions et des constantes générales, ce qui conduit à un code plus lisible, plus maintenable et plus ordonné. Cependant, cela peut être relativement perturbant au début.

Voici un simple scripte sans utilisation de Programmation Orienté Objet qui permet de faire bougé une image nommé « ball.png » à l’aide des flèches directionnelles :

import pygame

pygame.init()
screen = pygame.display.set_mode((400, 400))
running = True

image = pygame.image.load("ball.png")

x = 0
y = 0

clock = pygame.time.Clock()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_LEFT]:
        x -= 1
    if pressed[pygame.K_RIGHT]:
        x += 1
    if pressed[pygame.K_UP]:
        y -= 1
    if pressed[pygame.K_DOWN]:
        y += 1

    screen.fill((0, 0, 0))
    screen.blit(image, (x, y))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

code by TNtube

Le scripte est simple et efficace, pour autant si il venais à se complexifier cela deviendrait vite illisible.
voici maintenant le même scripte avec l’utilisation de la Programmation Orienté Objet :

player.py

import pygame

class Player:
    def __init__(self, x, y):
        self.image = pygame.image.load("player.png")
        self.image
        self.rect = self.image.get_rect(x=x, y=y)
        self.speed = 5
        self.velocity = [0, 0]

    def move(self):
        self.rect.move_ip(self.velocity[0] * self.speed, self.velocity[1] * self.speed)

    def draw(self, screen):
        screen.blit(self.image, self.rect)

Main.py

import pygame
from player import Player


class Game:
    def __init__(self, screen):
        self.screen = screen
        self.running = True
        self.clock = pygame.time.Clock()
        self.player = Player(0, 0)

    def handling_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.player.velocity[0] = -1
        elif keys[pygame.K_RIGHT]:
            self.player.velocity[0] = 1
        else:
            self.player.velocity[0] = 0

        if keys[pygame.K_UP]:
            self.player.velocity[1] = -1
        elif keys[pygame.K_DOWN]:
            self.player.velocity[1] = 1
        else:
            self.player.velocity[1] = 0

    def update(self):
        pass

    def display(self):
        self.screen.fill("white")
        pygame.display.flip()

    def run(self):
        while self.running:
            self.handling_events()
            self.update()
            self.display()
            self.clock.tick(60)


pygame.init()
screen = pygame.display.set_mode((1080, 720))
game = Game(screen)
game.run()

pygame.quit()

code by TNtube

La particularité ici réside dans la clarté de chaque fonction et de leur utilité respective : « display » pour l’affichage, « handling_event » pour les interactions claviers-souris, « move » pour les mouvements du joueur… De plus, le programme est divisé en deux fichiers distincts : l’un pour le programme principal et l’autre pour le joueur. Ainsi, il est possible d’ajouter aisément de nouvelles fonctions pour des améliorations futures. Par exemple, la fonction « Update », actuellement inactive, pourrait être employée pour effectuer des vérifications, telles que les collisions.

Analyse du script

Passons maintenant à l’analyse du code.

Commençons par mon fichier « player.py », avec l’appel du module Pygame, la création de la classe et la fonction d’initialisation.

import pygame #On importe le module Pygame

class Player: #On crée la classe Player
    
# La fonction init est une fonction d'initialisation qui permet de déclarer toutes nos variables.
# Elle prend comme arguments self, qui est pris dans chaque fonction de la classe, x et y qui servent à définir la position initiale du joueur sur l'écran.
def init(self, x, y):
self.image = pygame.image.load("asset/Player.png")# On charge l'image du joueur
#Pour que vous puissiez être familiarisé avec le concept de rect, ce sont des rectangles que l'on ne voit pas, qui ont une taille que l'on leur définit et c'est grâce à ces rect, que l'on pourrait appeler hitbox, que l'on peut détecter des collisions.
self.rect = self.image.get_rect(center=(x, y))# On récupère le rectangle de l'image et on le centre en (x,y)
self.velocity = [0, 0]# On initialise la vitesse à 0 dans les deux directions

Une fois la mise en place de notre classe et de la fonction d’initialisation effectuée, nous créons la fonction de mouvement du joueur appelée « move », ainsi qu’une fonction « draw » qui permettra d’afficher notre personnage avec son rectangle.

def move(self, mouse_pos):# La fonction move permet de déplacer le joueur en fonction de la position de la souris, l'argument mouse_pos représente la position de la souris sur l'écran. Cette position est utilisée pour calculer la vitesse de déplacement du joueur, en soustrayant la position de la souris à la position actuelle du joueur.
    # On calcule la différence entre la position de la souris et la position actuelle du joueur
    self.velocity[0] = (mouse_pos[0] - self.rect.centerx)
    self.velocity[1] = (mouse_pos[1] - self.rect.centery)
    self.rect.move_ip(self.velocity)# On déplace le rectangle du joueur en fonction de la vitesse calculée

def draw(self, screen):# La fonction draw permet d'afficher le joueur sur l'écran
    screen.blit(self.image, self.rect)# On blitte (st utilisée pour dessiner une surface sur une autre surface.) l'image du joueur sur le rectangle de celui-ci

Maintenait que je vous ai introduis mon fichier joueur passons au fichier jeu.

import pygame
import random
from player import Player

On importe les modules nécessaires au fonctionnement du jeu : Pygame pour gérer l’affichage graphique et l’interaction avec l’utilisateur, random pour générer des nombres aléatoires, et Player qui est une classe définie dans un fichier séparé et qui représente le joueur.

class Game:
    def __init__(self, screen):
        self.screen = screen
        self.running = True
        self.clock = pygame.time.Clock()
        self.player = Player(60, 60)
        self.background = pygame.image.load("asset/background.jpg")
        self.brique = pygame.image.load("asset/brique.jpg")
        self.brique_rects = []
        self.brique_positions = []
        self.brique_speed = 3
        self.brique_spawn_rate = 120
        self.brique_spawn_counter = 0
        self.brique_spawn_augmentation = 15
        self.brique_spawn_increase_counter = 0
        self.total_time = 0
        self.total_time_max = 0
        self.difficulté = 20
        pygame.mouse.set_visible(False)
        
        choix = input("_____________________________________________________________________________ \n choisissez votre difficulté : \n 1- Facile \n 2- Normal \n 3- Difficile \n _____________________________________________________________________________ \n Votre choix : ")
        choix = int(choix)
        if choix == 1:
            self.difficulté = 1
        elif choix == 2:
            self.difficulté = 5
        elif choix == 3:
            self.difficulté = 10
        else:
            print("Error : s'il vous plait entré un entier positif entre 1 et 3")
            self.running = False

On définit la classe Game, qui représente le jeu en lui-même. Son constructeur prend en paramètre l’objet screen qui représente la surface sur laquelle le jeu sera affiché.

On initialise différentes variables, comme self.running qui permet de savoir si le jeu est en cours d’exécution ou non, self.player qui représente le joueur, self.background qui est l’image de fond, self.brique qui est l’image représentant les obstacles à éviter, et plusieurs variables liées à ces obstacles (self.brique_positions, self.brique_speed, self.brique_spawn_rate, self.brique_spawn_counter, self.brique_spawn_augmentation, self.brique_spawn_increase_counter).

On définit également self.total_time et self.total_time_max pour gérer le temps de jeu, et self.difficulté qui est utilisé pour régler la difficulté du jeu en fonction de la réponse de l’utilisateur à une question posée par input.

Enfin, on masque le curseur de la souris avec pygame.mouse.set_visible(False).

    def gestion_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

        self.player.move(pygame.mouse.get_pos())

La méthode gestion_events permet de gérer les événements liés à l’interaction de l’utilisateur avec la fenêtre Pygame.

Le code utilise une boucle for pour récupérer chaque événement dans la liste des événements de Pygame. Si l’un des événements est de type QUIT, cela signifie que l’utilisateur a cliqué sur le bouton de fermeture de la fenêtre. Dans ce cas, la variable self.running est définie sur False, ce qui interrompt la boucle de jeu.

La méthode appelle également la méthode move de l’objet Player pour mettre à jour sa position en fonction de la position de la souris de l’utilisateur.

   def adaptative_brique_rects(self):
        self.brique_rects = []

        for pos in self.brique_positions:
            rect = pygame.Rect(pos[0], pos[1], self.brique.get_width(), self.brique.get_height())
            self.brique_rects.append(rect)

La méthode adaptative_brique_rects est appelée pour mettre à jour les rects de collision des briques en fonction de leurs nouvelles positions.

 def spawn_brique(self):
        y = random.randint(0, self.screen.get_height() - self.brique.get_height())
        self.brique_positions.append((-self.brique.get_width(), y))

La méthode spawn_brique est appelée pour générer une nouvelle brique à une position aléatoire sur l’axe y et avec une position initiale en dehors de la fenêtre sur l’axe x.

    def move_briques(self):
        for i in range(len(self.brique_positions)):
            pos = list(self.brique_positions[i])
            pos[0] += self.brique_speed
            self.brique_positions[i] = tuple(pos)

        self.adaptative_brique_rects()

La méthode move_briques met à jour la position des briques en ajoutant la valeur de self.brique_speed à la coordonnée x de chaque position dans self.brique_positions.

def update(self):
    # Incrémenter le compteur de temps de spawn des briques par la difficulté du jeu
    self.brique_spawn_counter += self.difficulté

    # Augmenter la vitesse des briques si le compteur de spawn des briques est un multiple de 120
    if self.brique_spawn_counter % 120 == 0:
        self.brique_speed += 0.2

    # Vérifier si le compteur d'augmentation de spawn des briques a atteint sa limite
    self.brique_spawn_increase_counter += 1
    if self.brique_spawn_increase_counter >= self.brique_spawn_augmentation * 60:
        self.brique_spawn_increase_counter = 0
        self.brique_spawn_rate -= 10

    # Ajouter une nouvelle brique à la liste des positions de briques si le compteur de spawn des briques a atteint le taux de spawn des briques
    if self.brique_spawn_counter >= self.brique_spawn_rate:
        self.brique_spawn_counter = 0
        self.spawn_brique()

    # Déplacer toutes les briques dans la direction de la vitesse actuelle des briques
    self.move_briques()

    # Incrémenter le temps total de jeu de 1
    self.total_time += 1  

    # Vérifier si le joueur a perdu en entrant en collision avec une brique
    for rect in self.brique_rects:
        if rect.colliderect(self.player.rect):
            print("_____________________________________________________________________________\n")
            print("    Vous avez perdu, Votre temps est de", self.total_time/100, "secondes, bien joué à vous ;)")
            print("_____________________________________________________________________________\n")
            self.running = False
            break
        else:
            pass

La méthode update est appelée à chaque boucle de jeu pour mettre à jour les positions des briques, vérifier si le joueur a perdu en entrant en collision avec une brique et pour augmenter la difficulté du jeu.

Elle commence par incrémenter le compteur de temps de spawn des briques par la difficulté du jeu, pour que les briques apparaissent plus rapidement avec des niveaux de difficulté plus élevés.

Ensuite, si le compteur de spawn des briques est un multiple de 120, la vitesse de déplacement des briques est augmentée de 0,2.

La méthode vérifie également si le compteur d’augmentation de spawn des briques a atteint sa limite, qui est définie par self.brique_spawn_augmentation * 60. Si c’est le cas, le compteur est réinitialisé et le taux de spawn des briques est diminué de 10.

Si le compteur de spawn des briques atteint le taux de spawn des briques défini par self.brique_spawn_rate, la méthode spawn_brique est appelée pour ajouter une nouvelle brique à la liste des positions de briques.

La méthode move_briques est ensuite appelée pour déplacer toutes les briques dans la direction de la vitesse actuelle des briques.

Le temps total de jeu est ensuite incrémenté de 1.

Enfin, pour chaque rect de brique dans la liste self.brique_rects, la méthode vérifie s’il y a une collision avec le rectangle de la zone de collision du joueur. Si c’est le cas, la méthode affiche le message de fin de jeu et met la variable self.running à False pour arrêter la boucle de jeu.

def display(self):
    # Afficher le fond d'écran
    self.screen.blit(self.background, (-200, -350))

    # Parcourir toutes les positions des briques et les afficher
    for pos in self.brique_positions:
        self.screen.blit(self.brique, pos)

    # Afficher le joueur
    self.player.draw(self.screen)

    # Mettre à jour l'affichage
    pygame.display.flip()

La méthode display(self) affiche les éléments du jeu sur l’écran. Elle utilise la méthode blit pour afficher le fond d’écran, chaque brique de la liste brique_positions et le joueur (player) sur l’écran. Ensuite, elle appelle la méthode flip de la classe pygame.display pour mettre à jour l’affichage.

def run(self):
    # Boucle principale du jeu
    while self.running:
        # Gérer les événements (ex: appuyer sur une touche, quitter le jeu)
        self.gestion_events()

        # Mettre à jour le jeu (ex: déplacer les briques, vérifier les collisions)
        self.update()

        # Afficher le jeu
        self.display()

        # Limiter le nombre de frames par seconde à 60
        self.clock.tick(60)

    # Réafficher la souris et quitter Pygame
    pygame.mouse.set_visible(True)
    pygame.quit()

La méthode run(self) contient la boucle principale du jeu. Elle s’exécute tant que l’attribut running est vrai. À chaque itération de la boucle, elle gère les événements (appel à gestion_events()), met à jour les éléments du jeu (appel à update()), affiche le contenu du jeu sur l’écran (appel à display()) et attend un certain temps défini par la méthode tick de pygame.time.Clock. Enfin, elle quitte le jeu (pygame.quit()) lorsque la boucle est terminée.

# Initialiser Pygame
pygame.init()

# Créer une fenêtre de jeu
screen = pygame.display.set_mode((1080, 720))

# Créer une instance de la classe Game en lui passant la fenêtre de jeu en argument
game = Game(screen)

# Lancer le jeu
game.run()

# Quitter Pygame
pygame.quit()

La partie en dehors de la classe initialise la bibliothèque Pygame (pygame.init()) et crée une fenêtre de jeu (pygame.display.set_mode((1080, 720))). Ensuite, elle crée une instance de la classe Game avec l’écran en tant qu’argument et appelle la méthode run de l’instance pour démarrer le jeu. Enfin, elle quitte la bibliothèque Pygame (pygame.quit()) après la fin du jeu.

Sources :

Conclusion

En conclusion, ce projet est un petit jeu simple mais amusant, il est sur l’univers de Mario. Si vous voulez essayer ce jeu par vous-même, vous pouvez le télécharger en cliquant sur le lien ci-dessous. Pour lancer le jeu, assurez-vous d’écrire le niveau de difficulté souhaité (1, 2 ou 3) dans la console Python. Si vous ne le faites pas, la fenêtre restera noire et le jeu ne se lancera pas. On commande le personnage avec sa souris.

Amusez-vous bien !

Tutoriels

Comment installer Linux Ubuntu sur son ordinateur, tout en…

Dans le cadre du projet « Ecrire un tutoriel en NSI« , je vous propose ce tutoriel pour apprendre simplement et efficacement comment installer correctement Linux Ubuntu sur son ordinateur tout en gardant Windows. Un tutoriel pas à pas qui aidera les plus débutants d’entre vous.

Pourquoi Installer Ubuntu ?

Premièrement, Linux est un OS/environnement de travail plus propice à une utilisation informatique poussée. Il enlève toutes les contraintes de sécurité que l’on pourrait retrouver sur Windows. Linux est bien moins gourmand en puissance de calcul que Windows, vous pourriez donc donner une seconde vie à un vieil ordinateur qui n’arrive plus à faire tourner Windows, ou bien rendre plus performant le votre. Pourquoi Ubuntu? Je conseille Ubuntu comme première version de Linux car c’est, pour moi, la distribution de Linux la plus convenable pour les premiers pas d’un(e) nouvel(le) utilisateur(trice) de Linux. Certaines distributions, comme Kali, sont compliquées à prendre en main et peuvent déstabiliser un(e) nouvel(le) utilisateur(trice).

Matérielle nécessaire :

  • Une clé vierge USB 4G minimum (possibilité de gravé un cd pour l’inhalation (fichier en .iso))
  • Disque dur / ssd avec minimum 25G de libre
  • Une connexion internet

Conseille avant de commencer :

Pour ne pas faire de mauvais manipulation ou endommagé vos appareille, je vous conseille de tester ce tuto sur un veille ordinateur, ou de faire une Back-up de votre ordinateur avant de commencé quoi que ce soit, ce maitre mon de ce tuto sera de prendre son temp.

Créer une clé USB bootable :

Télécharger Ubuntu :

Pour commencer allez sur le site officiel de Ubuntu pour téléchargé la dernier version :

Le fichier fait 3,6 Go dans sa version actuelle, il est donc normal que cela prenne un certain temps à s’installer (vous remarquerez que le fichier est en .iso, ce qui fait qu’il est possible de graver un disque pour en faire le support d’installation).

Téléchargement Rufus et son utilisation :

Rufus permet de formater et de rendre bootable n’importe quel support amovible de stockage tel que les clés USB ou les disques durs externes, et c’est cet outil que nous allons utiliser.

Commençons par téléchargé la dernier version de Rufus (ici la 3.21):

Puis lancé le .exe, accepté la demande de droit d’administrateur. La fenêtre de Rufus devrai alors souvrire et devrais ressemblé à cela :

On choisi son périphérique :

On appuie sur le bouton Sélectionner pour aller chercher le fichier de Ubuntu que l’on vient de télécharger, puis sur le bouton Démarrer. Cela va ouvrir une fenêtre où l’on laisse les paramètres par défauts et où l’on accepte avec Ok et l’on accepte encore une fois le deuxième avertissement qui nous indique que la clé USB va être formatée. Une fois cela fait, cela risque de prendre un peu de temps en fonction de votre ordinateur. Il suffit juste d’attendre la fin du chargement.

Une fois la conversion réaliser cliquez simplement sur Fermer, et c’est finit, vous venez de réalisé une clé USB bootable fonctionnelle !!!

Créer une partition dans son disque pour installer Ubuntu :

Avant de commencé quoi que ce soit sachez que cette étape peux être optionnelle si vous possédée deux disque dans votre ordinateur et que vous décidé d’utilisé l’entièreté de l’un de ces deux disque pour installer Ubuntu.

Premièrement regardez si il vous reste de l’espace disponible dans votre disque et si cette espace restant n’est essentielle. Puis allez dans la barre de recherche Windows et tapez « Partitions » et cliqué sur l’outil l’outils « Créer et formaté des partitions de disque dur« , une fois ouvert une nouvel fenêtre devrais s’ouvrir vous permettant de voir vo(s) disque(s) :

Fait clic droit sur le disque ou vous souhaitez installer Ubuntu et cliquer sur Réduire le volume ... cela vas alors calculé l’espace de stockage que Windows peut vous libéré pour faire votre installation.

Ici on me propose un espace de 69 Go mais je n’aurais besoin que de 40 Go soit 40.000 Mo, j’indique donc la valeur dans « Quantité d’espace à réduire » et j’appuis sur réduire :

On vois bien qu’est espace  à 40 Go à été libéré.

Installation et configuration de Ubuntu :

Démarre son ordinateur sur la clé USB bootable :

Premièrement braché votre clés USB à votre ordinateur. Nous arrivons maintenant sur une étape délicate ou je ne vais pas pouvoir vous guider plus que cela. l’idée pour démarré sur la clé USB est d’allé dans le Bios pour ouvrir la clé USB dans le Boots menu, il vas donc falloir ouvrir la Bios, l’ouverture du Bios est spécifique au modèle de carte mère de chaque ordinateur, pour savoir exactement comment faire, je vous conseille de regarder le guide de votre carte mère pour voir, ou bien celui de la référence de votre ordinateur pour l’ouvrir. la plus part du temp il surfil simplement de matraqua les touches F2, ou DEL l’ors de l’allumage du l’ordinateur, mais cela ne marche pas forcément est surtout ut les les ordinateur portables (fast boute empêche les raccourcis habituelle pour ceux qui connaissent), je vous propose donc cette petit vidéo pour tout les personnes qui pourrais avoir du mal.

Une fois le Bios ouvert la aussi tout vas dépendre de votre ordinateur et de ça carte mère, il y a des bios avec des interface plus ou moins graphique , pour autant le but va être d’accédé au Boot menu, puis de choisir votre clé USB qui contiens Ubuntu pour démarré dessue pour que l’installation commence, je vous met si dessous quelques screen shot d’a quoi à ressemblé mon installation :

Ouverture du Bios
ici j’ai échanger USB DISK 3.0 et Windows Boot manager ce qui fait que l’ordinateur démarrera sur la clé USB
Fermeture en enregistrement des modifications

Une fois les étapes présidentes réalisé, le Grub devrais s’ouvrir vous laissant le choix entre plusieurs lancement, vous allez choisir Try or Install Ubuntu.

Une fois cela fait un écran de chargement devrais ce lancé vous laissant apparaitre le logo de Ubuntu

Installation et Paramétrage de Ubuntu :

Bravo ! Si vous êtes à cette étapes c’est que vous avez passé la premier parti difficile de cette installation. Nous allons donc maintenant installé définitivement Ubuntu et le configure correctement.

Premièrement choisissez votre langue puis cliqué sur Install Ubuntu, ensuite choisissez quel types de configuration de clavier vous voulez (Frenche-French(legacy, alt.)), n’hésitez pas à testé toutes vos touches et tout les symboles pour vérifier que tout fonctionne correctement, puis connecté vous à votre Wi-Fi.

Nous arrivons au premier écran « important », cela vas concerné la case à cocher « Installer un logiciel pour le matériel graphique et Wi-Fi et des formats de média supplémentaire« , cela vas permettre à Ubuntu d’accepté d’installé des logicielle auquel il n’a pas acquêt, comme les pilot de carte graphique (les pilots de NVidia, qui sont des pilots propriétaires ) ou des pilots de cartes Wi-Fi. Une fois cette case cocher configure le mot de passe pour le sécure Boot ( vous n’y aurais pas recours fréquemment, voir jamais, je vous conseille de mettre le même mot de passe que celui de votre ordinateur), une fois cela fait cliqué sur « continuer »

Et nous arrivons sur l’écran LE PLUS IMPORTANT :

Ici l’on vas choisir entre une installation manuel ou automatique de Ubuntu, pour terminé rapidement, mais je ne conseille pas cette solution, pour continuer cliqué sur « Autre chose » puis continuer pour arrive à l’écran de paramétrage finale:

Premièrement regardons en fonction de l’espace disponible quelle espace faut-il alloué à chaque partie, pour cela regarde cette feuille de calcule pour comparé.

Dans l’espace libre, il vas falloir crée trois partition distincte, le Root (/), le Swap, et la Home (/home), pour cela faite un clic droit sur l’espace libre et cliqué sur « Ajouter… », une fois la fenêtre ouverte met dans point de montage un « / » et donne on fonction de l’espace souhaiter, puis refaire la même chose sauf que cette fois ici cliqué sur utilisé comme et allez chercher « espace d’échange (swap) » mettre l’espace nécessaire en fonction du tableur refaire encor une fois la manipulation, et mettre « /home » dans le point de montage.

C’est bon, vous venez de terminé la partie la plus compliqué » de l’installation de Ubuntu sur votre ordinateur, si tout c' »est bien passé vos partition devrai ressemblé à cela :

Et il ne vous reste plus continuer après les avertissement, choisir son fuseaux horaire, complété sont profile, et attendre la fin de l’installation de Ubuntu, une fois terminé, il est demander redémarré l’ordinateur et l’ors du redémarrage, quand il l’ai demander, retiré la clé USB et appuyer sur ENTER.

Choisir si l’ont démarre sur Windows ou sur Ubuntu :

Maintenant que vous avec Ubuntu sur votre ordinateur, vous souhaiter certainement retourné sur Windows pour s’assuré que tout c’est bien passé, pour cela redémarré l’ordinateur, et attendez d’arriver sur le Grub, une fois dessus avec les flèches directionnelle sélectionner « *Windows Boot Manager (on/dev/sdb1) » pour démarré sur Windows.

Merci d’avoir suivit ce tutoriel, j’espère qu’il vous aura aidez et qu’il vous aura permit de vous introduire un monde de Linux. Sur ceux que vous souhaite une bonne découverte !!!

Art

Perspective : un paysage Synthwave

Dans le cadre de la 5ème édition du dispositif “Regards de Géomètre”, nous avons décidé dans le thème « Perspective » de produire un paysage synthwave.

Vidéo du projet

Origines de la Synthwave

Avant tout la synthwave est un genre musical électronique ayant émergé dans les années 2000/2010 qui s’inspire d’éléments des années 80. Et c’est justement dans les clips de ces musiques que l’on va retrouver ce type d’image.

Pour en savoir plus nous vous conseillons cette vidéo qui explique brièvement les origines.

Le Projet

Revenons donc au projet. Pour ce projet nous avons donc décidé de produire une image d’un paysage synthwave. Pour cela nous utilisons le module turtle ainsi que le module random, le module turtle est utilisé pour produire l’image est le module random est utilisé pour les étoiles de l’image où la taille et leur position est générée aléatoirement nous avons également utilisé le script permettant d’exporter une image générée par turtle en .png que vous pouvez retrouver ici.

Structure du script

Pour la structure du script nous avons décidé de découper chaque partie de l’image (pavage, fond, étoiles, soleil, ville et montagnes) afin de créer des fonctions et à la fin nous les avons toutes appelées dans un ordre précis pour que les différentes parties de l’image soit dans leur plan respectif.

Analyse du script

Nous allons donc analyser le script.

Commençons par l’appel des modules et la mise en place de turtle.

from turtle import *
from random import randint
# vérification des modules importés
try:
    from PIL import Image
    pillow_installed = True
except:
    print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
    print("https://nsi.xyz/py2png")
    pillow_installed = False
titre = "Perspective - Un paysage Synthwave"
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")
setup(1280, 720) # définit la taille de la fenêtre
colormode(255) # permet l'utilisation de couleurs rgb
speed(0) #Remplaçable par tracer(2) (10x plus rapide) mais si il est utilisé des lignes du pavage peuvent manquer
hideturtle() #dissimule la tortue

On appelle les fonctions turtle, random avec pour random uniquement randint et on utilise une partie du script « exporter une image générée par turtle » pour vérifier que l’utilisateur a bien installé le module PIL et dans le cas contraire un message d’erreur s’affichera et lui donnera un lien pour installer le module et tout ça sans que le script ne s’arrête. Après la vérification on met en place le titre de la fenêtre qui va affiché le rendu ainsi que sa taille. Enfin on définit le type de couleurs utilisées (R,G,B), la vitesse de la tortue, et on dissimule la tortue (c’est plus joli).

Commençons par la première fonction : le fond

def fond():
    penup()
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    goto(-642,-358)
    pendown()
    while hauteur != 360:
        pencolor(round(239 + rciel), round(41 + gciel), round(209 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (-29/180)
        gciel += (2/45)
        bciel += (7/720)

Pour le fond on aurait pu utiliser une fonction qui crée un rectangle et qui le remplit avec fill_rect, cependant la couleur dans ce cas est uni ce qui ne nous intéresse pas. Nous avons donc produit un script qui fait un fond dégradé qui fait avancer la tortue sur une ligne d’un pixel de large et à la fin de cette ligne la tortue est envoyé grâce à un goto à la ligne d’après et qui ajoute la différence de chaque couleur (rouge,vert et bleu) entre la couleur de début du dégradé et la couleur de fin. Tout ceci est arrondi car turtle n’est pas compatible avec des arguments à virgule (pour la fonction pencolor en tout cas).

Par la suite la fonction qui produit les étoiles a été codée :

def etoile():
    for i in range(90):
        penup()
        goto(randint(-720,720), randint(0,360))
        pendown()
        pencolor(255, 255, 255)
        lcercle = randint(1,3)
        fillcolor('white')
        begin_fill()
        circle(lcercle)
        end_fill()

Pour les étoiles on définit aléatoirement leur position sur la moitié haute de l’image, on les met en blanc, on définit aussi aléatoirement la taille de l’étoile et on créer l’étoile avec sa position, et sa taille en aléatoire puis on refait ce processus 90 fois pour avoir 90 étoiles.

Ensuite nous avons le soleil (Le script affiché n’est qu’une petite partie du script total du soleil car il est très long et qu’il se répète, il est donc inutile de commenter la suite) :

def soleil():
    penup()
    liste1 = [10,7,5,4,3,3,3,3,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,1,2,1,1,1]
    liste2 = [1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0]
    pliste1 = 0
    pliste2 = 0
    rsoleil = 0
    gsoleil = 0
    bsoleil = 0
    lsoleil = 8
    hauteur = 30
    goto(0,30)
    pendown()
    for i in range(15):
        pencolor(round(255 + rsoleil), round(23 + gsoleil), round(226 + bsoleil))
        forward(lsoleil)
        backward(2*lsoleil)
        hauteur += 1
        lsoleil += liste1[pliste1]
        pliste1 += 1
        goto(0, hauteur)
        rsoleil += (0)
        gsoleil += (114/101)
        bsoleil += (-203/202)
    forward(lsoleil)
    backward(2*lsoleil)
    penup()

Pour le soleil nous réutilisons le script du dégradé, cependant nous l’avons modifier pour que le point d’origine de la tortue soit au centre du rectangle et que la longueur de chaque ligne soit défini par une liste (ce qui permet de faire un cercle en prenant les longueur d’un cercle utilisable en pixel art). Pour ce qui est des endroits ou le soleil est coupé la tortue fait le tracé mais on a utilisé la fonction penup() qui fait que la tortue ne dessine plus.

Après nous avons la fonctions des montagnes (Encore une fois le script n’est pas complet car il se répète encore 3 fois après.) :

def montagne():
    #montagne derrière la première
    penup()
    goto(-480,0)
    fillcolor(110, 27, 188)
    begin_fill()
    for i in range(3):
        forward(250)
        left(120)
    end_fill()
    
    goto(-480,0)
    pencolor(51, 210, 246)
    ymontagne = 10
    for i in range(11):
        pendown()
        goto(-355,ymontagne)
        goto(-230,0)
        penup()
        goto(-480,0)
        ymontagne += 20

Pour le script des montagnes nous avons utilisé le script pour faire des triangles équilatéraux retrouvable ici. Et ensuite nous avons utilisé un ‘for i in range’ pour faire des goto enchaîné pour faire les lignes des montagnes.

Ensuite nous avons les fonctions de la ville. Pourquoi les fonctions car il y a une fonction pour chaque bâtiment différent ainsi qu’une fonction finale qui définit l’ordre des bâtiments.

def bat1():
    penup()
    rbat = 0
    gbat = 0 
    bbat = 0
    hauteur = 0
    pendown()
    xturtle, yturtle = pos()
    while hauteur != 72:
        pencolor(round(125 + rbat), round(35 + gbat), round(216 + bbat))
        forward(42)
        hauteur += 1
        goto(xturtle, hauteur)
        rbat += (-5/3)
        gbat += (-7/15)
        bbat += (-72/25)
    forward(42)
    penup()
    right(90)
    forward(72)
    left(90)

Pour le bâtiment 1 il y a un dégradé (toujours le même script) puis on fait que la tortue finisse le bâtiment en bas à droite de ce dernier pour pouvoir enchainer les bâtiments.

fun fact : Au début nous n’avions pas prévu les quelques lignes à la fin pour que la tortue puisse enchaîner les bâtiments sans que les fonctions des bâtiments aient besoin d’être modifiés ce qui nous a amené à avoir tous les bâtiments qui se chevauchaient.

def ville():
    penup()
    goto(-320,0)
    bat3(), bat2(), bat1(), bat4() ,bat3(), bat4(), bat3(), bat2(), bat1(), bat2(), bat1(), bat3(), bat1(), bat4(), bat2(), bat1(), bat3(), bat1(), bat4(), bat3()

Et à la fin on a fait la fonction ville qui appelle dans l’ordre choisi les bâtiments. Le goto permet de définir où commence le premier bâtiment, les autres se mettent juste après le premier sans se chevaucher ni laisser un espace.

Par la suite nous avons le pavage (très long aussi, il sera donc coupé) :

def pavage():
    colormode(255)
    pensize(5)
    speed(0)
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    penup()
    goto(-640,-360)
    pendown()
    while hauteur != 0:
        pencolor(round(15 + rciel), round(4 + gciel), round(76 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (91/180)
        gciel += (1/36)
        bciel += (7/18)

Pour le début du pavage on retrouve encore le script du dégradé mais avec les couleurs modifiées.

pencolor(229, 123, 240)
    #Lignes au dessus du pavage
    pensize(4),penup(),goto(-640,0),pendown(),goto(640,0),pensize(2),penup(),goto(-640, 0),pendown()
    #lignes gauche
    penup(),goto(-20.00,0),pendown(),goto(-60.00,-360.00),penup(),goto(-60.00,0),pendown(),goto(-180.00,-360.00),penup(),goto(-100.00,0),pendown(),goto(-300.00,-360.00),penup(),goto(-140.00,0),pendown(),goto(-420.00,-360.00),penup(),goto(-180.00,0),pendown(),goto(-540.00,-360.00),penup(),goto(-220.00,0),pendown(),goto(-660.00,-360.00),penup(),goto(-260.00,0),pendown(),goto(-780.00,-360.00),penup(),goto(-300.00,0),pendown(),goto(-900.00,-360.00),penup(),goto(-340.00,0),pendown(),goto(-1020.00,-360.00),penup(),goto(-380.00,0),pendown(),goto(-1140.00,-360.00),penup(),goto(-420.00,0),pendown(),goto(-1260.00,-360.00),penup(),goto(-460.00,0),pendown(),goto(-1380.00,-360.00),penup(),goto(-500.00,0),pendown(),goto(-1500.00,-360.00),penup(),goto(-540.00,0),pendown(),goto(-1620.00,-360.00),penup(),goto(-580.00,0),pendown(),goto(-1740.00,-360.00),penup(),goto(-620.00,0),pendown(),goto(-1760.00,-360.00)
    #lignes droites
    penup(),goto(20,0),pendown(),goto(60.00,-360.00),penup(),goto(60.00,0),pendown(),goto(180.00,-360.00),penup(),goto(100.00,0),pendown(),goto(300.00,-360.00),penup(),goto(140.00,0),pendown(),goto(420.00,-360.00),penup(),goto(180.00,0),pendown(),goto(540.00,-360.00),penup(),goto(220.00,0),pendown(),goto(660.00,-360.00),penup(),goto(260.00,0),pendown(),goto(780.00,-360.00),penup(),goto(300.00,0),pendown(),goto(900.00,-360.00),penup(),goto(340.00,0),pendown(),goto(1020.00,-360.00),penup(),goto(380.00,0),pendown(),goto(1140.00,-360.00),penup(),goto(420.00,0),pendown(),goto(1260.00,-360.00),penup(),goto(460.00,0),pendown(),goto(1380.00,-360.00),penup(),goto(500.00,0),pendown(),goto(1500.00,-360.00),penup(),goto(540.00,0),pendown(),goto(1620.00,-360.00),penup(),goto(580.00,0),pendown(),goto(1740.00,-360.00),penup(),goto(620.00,0),pendown(),goto(1760.00,-360.00)
    #Lignes horizontales
    penup(),goto(-640, -300),pendown(),goto(640, -300),penup(),goto(-640, -240),pendown(),goto(640, -240),penup(),goto(-640, -190),pendown(),goto(640, -190),penup(),goto(-640, -140),pendown(),goto(640, -140),penup(),goto(-640, -100),pendown(),goto(640, -100),penup(),goto(-640, -70),pendown(),goto(640, -70),penup(),goto(-640, -40),pendown(),goto(640, -40),penup(),goto(-640, -15),pendown(),goto(640, -15),

On a par la suite énormément de goto afin de faire le quadrillage du pavage.

Pour produire l’image finale nous avons les appels des différents fonctions à la fin :

#appel de toutes les fonctions
fond(), etoile(), soleil(), montagne(), ville(), pavage()

Et pour exporter l’image finale en .png il y a la suite du script pour exporter une image générée par turtle en .png utilisé au début du script.

#enregistrement de l'image finale avec vérification des modules importés
image = getcanvas()
nom_du_fichier_sans_extension=titre+"_"+hex(randint(2**30+2**25,2**30+2**25+2**24-1))[2:]
image.postscript(file=nom_du_fichier_sans_extension+".ps", colormode='color')
try:
    psimage = Image.open(nom_du_fichier_sans_extension+".ps")
    psimage.load(scale=2)
    psimage_resized = psimage.resize((1280, 720))
    psimage.save(nom_du_fichier_sans_extension+".png")
    print(nom_du_fichier_sans_extension+".png", psimage.size, "sauvegardé dans le dossier")    
except:
    if not pillow_installed:
        print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
        print("https://nsi.xyz/py2png")
    else:
        print("Oops! - 'ghostscript' not installed- RTFM :")
        print("https://nsi.xyz/py2png")
exitonclick()

Le script va donc générer une image en .ps et la convertir en .png avec un nom généré aléatoirement pour éviter que à chaque fois que vous générez une image l’image soit écrasée

Télécharger le .py

L’image finale