Pyxel Studio

Solar System simulation (PRIVATE/NSI VERSION)
Description
Ce programme python/pyxel est une simulation du système solaire.
Vous pouvez cliquer sur le soleil, chaque planète et chaque astéroide pour voir des informations et interagir avec ces objets (pour des raisons évidentes, le soleil n'est pas à taille réelle dans l'échelle sélectionnée).

Ajouts à faire :
IMPORTANT :
- Doublons d'astéroides
- Quand un tableau des coordonnées de planète est finit, il faut supprimer le tableau et le remplacer par un circb réduisant grandement les lags
- Jeu 1
- Jeu 2
- Jeu 3 : (déjà commencé)
- Jeu 4
MINEUR :
- Design des Planètes amélioré (+lunes autour)
- Design des astéroides amélioré
- Améliorer design de l'explosion du soleil (planètes/astéroides touchés=explosent, l'onde d'explosion du soleil moins ronde car dans la vraie vie, l'explosion ne fait pas un cercle parfait comme ce cas-ci, réelles couleurs : beaucoup violet/jaune/orange, peu de rouge/vert/marron.)
Documentation
import pyxel
import math
import random

# Definition des variables globales
COLOR_BLACK = 0
COLOR_DARKBLUE = 1
COLOR_PURPLE = 2
COLOR_GREEN = 3
COLOR_BROWN = 4
COLOR_BLUE = 5
COLOR_LIGHTBLUE = 6
COLOR_WHITE = 7
COLOR_RED = 8
COLOR_ORANGE = 9
COLOR_YELLOW = 10
COLOR_LIGHTGREEN = 11
COLOR_CYAN = 12
COLOR_GREY = 13
COLOR_LIGHTROSE = 14
COLOR_ROSE = 15
PYXEL_WIDTH = 250
PYXEL_HEIGHT = 250
CENTER_X = PYXEL_WIDTH//2
CENTER_Y = PYXEL_HEIGHT//2
return_button_x = 40
return_button_y = 220
action_return_width = 60
action_return_height = 15
action_button_x = 150
action_button_y = 220
action_button_width = 60
action_button_height = 15

########################################################
### SYSTEME SOLAIRE ###
########################################################

class Sun:
"""
Classe du soleil
"""
def __init__(self, name, x, y, information1, information2, radius):
self.name = name
self.x = x # Coordonnee x du centre du soleil
self.y = y # Coordonnee y du centre du soleil
self.radius = radius # radius du soleil
self.color = COLOR_ORANGE # Couleur de fond du soleil
self.second_color = COLOR_YELLOW # Couleur des dessins sur le soleil
self.sun_hovered = False
self.information1 = information1
self.information2 = information2

def check_hover_sun(self):
"""
Verifie si la souris survole le soleil
"""
distance_to_mouse = (self.x - pyxel.mouse_x) ** 2 + (self.y - pyxel.mouse_y) ** 2 # Calcul de la distance au carre
self.sun_hovered = distance_to_mouse <= (self.radius + 1) ** 2 # Verification de la survol

def update(self):
"""
Met a jour l'etat du soleil a chaque frame
"""
self.check_hover_sun()

def draw(self):
"""
Dessin du soleil
"""
# Dessiner le fond du soleil
pyxel.circ(self.x, self.y, self.radius, self.color)
# Dessiner les details du soleil
pyxel.circb(self.x, self.y, self.radius, self.second_color) # Contour du soleil
pyxel.pset(self.x + self.radius // 2, self.y + self.radius // 2, self.second_color) # Point 1
pyxel.pset(self.x + self.radius // 2 - 1, self.y + self.radius // 2, self.second_color) # Point 2
pyxel.pset(self.x + self.radius // 2, self.y + self.radius // 2 - 1, self.second_color) # Point 3
pyxel.pset(self.x + self.radius // 2 + 1, self.y + self.radius // 2 - 1, self.second_color) # Point 4
pyxel.pset(self.x + self.radius // 2 - 1, self.y + self.radius // 2 + 1, self.second_color) # Point 5
pyxel.pset(self.x + self.radius // 2 - 2, self.y + self.radius // 2 + 1, self.second_color) # Point 6
pyxel.circ(self.x - 2, self.y, 2, self.second_color) # Dessin 1
pyxel.circ(self.x - 1, self.y - 1, 2, self.second_color) # Dessin 2
if self.sun_hovered: # Si la souris survole le soleil
pyxel.text(self.x - len(self.name) * 2, self.y - self.radius - 10, self.name, COLOR_GREEN) # Afficher le nom du soleil
pyxel.circb(self.x, self.y, self.radius + 2, COLOR_GREEN) # Dessiner un contour autour du soleil

class Asteroid:
"""
Classe des asteroides
"""
def __init__(self, x, y, radius, color, name, information1, information2):
self.x = x # Coordonnee x de l'asteroïde
self.y = y # Coordonnee y de l'asteroïde
self.radius = radius+1 # Rayon de l'asteroïde
self.color = color # Couleur de l'asteroïde
self.vx = random.uniform(-0.5, 0.5) # Vitesse horizontale initiale de l'asteroïde
self.vy = random.uniform(-0.5, 0.5) # Vitesse verticale initiale de l'asteroïde
self.name = name # Nom de l'asteroïde
self.information1 = information1 # informationrmation supplementaire 1 sur l'asteroïde
self.information2 = information2 # informationrmation supplementaire 2 sur l'asteroïde
self.asteroid_hovered = False # Indicateur si la souris survole l'asteroïde
self.exploding = False # Indicateur si l'asteroïde est en train d'exploser
self.explosion_over = False # Indicateur que l'astéroide a finit d'exploser
self.explosion_frames = 0 # Nombre de frames ecoulees depuis le debut de l'explosion
self.explosion_duration = 60 # Duree totale de l'explosion en frames
self.pieces = [] # Liste des pieces resultant de l'explosion de l'asteroïde
self.particles = [] # Liste des particules d'explosion

def check_hover_asteroid(self):
"""
Verifie si la souris survole l'asteroïde
"""
distance_to_mouse = (self.x - pyxel.mouse_x) ** 2 + (self.y - pyxel.mouse_y) ** 2 # Calcul de la distance au carre
self.asteroid_hovered = distance_to_mouse <= (self.radius + 1) ** 2 # Verification de la survol

def start_explosion(self):
"""
Demarre l'animation d'explosion de l'asteroïde
"""
self.exploding = True # L'asteroïde commence a exploser
# Generer des pieces d'asteroïde
self.pieces = [] # Initialisation de la liste des morceaux
num_pieces = random.randint(2, 6) # Nombre aleatoire de morceaux
for _ in range(num_pieces):
piece_radius = random.uniform(self.radius * 0.2, self.radius * 0.5) # Taille proportionnelle des morceaux
angle = random.uniform(0, 2 * math.pi) # Angle de direction aleatoire
speed = random.uniform(1.25, 2.5) # Vitesse aleatoire des morceaux
life = random.randint(20, 40) # Durée de vie aléatoire
self.pieces.append([self.x, self.y, piece_radius, self.color, math.cos(angle) * speed, math.sin(angle) * speed, life]) # Ajout des morceaux a la liste
# Generer des petites particules d'explosion
for _ in range(100):
angle = random.uniform(0, 2 * math.pi) # Angle de direction aleatoire
speed = random.uniform(1.75, 3.5) # Vitesse aleatoire des particules
life = random.randint(20, 40) # Durée de vie aléatoire
color = random.choice([self.color, COLOR_ORANGE, COLOR_YELLOW]) # Couleur aleatoire des particules
self.particles.append([self.x, self.y, color, math.cos(angle) * speed, math.sin(angle) * speed, life]) # Ajout des particules a la liste

def update(self):
"""
Met a jour les asteroïdes
"""
if self.exploding:
# Si l'asteroïde est en train d'exploser
self.explosion_frames += 1 # Incrementation du compteur de frames d'explosion
for i in range(len(self.particles)):
self.particles[i][5] -= 1
for i in range(len(self.pieces)):
self.pieces[i][6] -= 1
if self.explosion_frames >= self.explosion_duration:
# Si l'explosion est terminee
self.explosion_over = True
else:
# Si l'asteroïde est en mouvement normal
self.x += self.vx # Mise a jour de la position horizontale de l'asteroïde
self.y += self.vy # Mise a jour de la position verticale de l'asteroïde
self.check_hover_asteroid() # Verification si la souris survole l'asteroïde

def draw(self):
"""
Dessine les asteroïde (et leurs explosions)
"""
if self.exploding:
# Si l'astéroïde est en train d'exploser
# Dessiner les morceaux d'astéroïdes
for i in range(len(self.pieces) - 1, -1, -1):
piece = self.pieces[i]
if piece[6] > 0:
pyxel.circ(piece[0], piece[1], piece[2], piece[3]) # Dessiner un morceau d'astéroïde
piece[0] += piece[4] # Mise à jour de la position horizontale du morceau
piece[1] += piece[5] # Mise à jour de la position verticale du morceau
else:
# Si la durée de vie est écoulée, supprimer l'élément de la liste
del self.pieces[i]

# Dessiner les petites particules d'explosion
for i in range(len(self.particles) - 1, -1, -1):
particle = self.particles[i]
if particle[5] > 0:
pyxel.pset(particle[0], particle[1], particle[2]) # Dessiner une particule d'explosion
particle[0] += particle[3] # Mise à jour de la position horizontale de la particule
particle[1] += particle[4] # Mise à jour de la position verticale de la particule
else:
# Si la durée de vie est écoulée, supprimer l'élément de la liste
del self.particles[i]
else:
# Si l'asteroïde n'est pas en train d'exploser
pyxel.circ(self.x, self.y, self.radius, self.color) # Dessiner l'asteroïde
if self.asteroid_hovered:
# Si la souris survole l'asteroïde
pyxel.text(self.x - len(self.name) * 2, self.y - self.radius - 10, self.name, COLOR_GREEN) # Afficher le name de l'asteroïde
pyxel.circb(self.x, self.y, self.radius + 2, COLOR_GREEN) # Dessiner un contour autour de l'asteroïde

class Planet:
"""
Classe des planètes
"""
def __init__(self, name, radius, distance, color, information1, information2, game, orbital_period, moons, sun_position, ring_size, ring_color):
# Initialisation des attributs de la planete
self.name = name # Nom de la planete
self.radius = radius # Rayon de la planete
self.distance = distance // 1.75 # Distance orbitale par rapport au soleil (divisee pour le rendu)
self.color = color # Couleur de la planete
self.information1 = information1 # Information supplementaire 1 sur la planete
self.information2 = information2 # Information supplementaire 2 sur la planete
self.game = game # Instance du jeu auquel la planete appartient
self.orbital_period = orbital_period # Periode orbitale de la planete
self.moons = moons # Nombre de lunes de la planete
self.sun_position = sun_position # Position du soleil dans le jeu
self.speed = 2 * math.pi / self.orbital_period # Vitesse orbitale de la planete (en radians par frame)
self.angle = 0 # Angle actuel de la planete sur son orbite
self.trace = [] # Liste des positions precedentes de la planete pour dessiner son orbite
self.planet_hovered = False # Indicateur si la souris survole la planete
self.ring_size = ring_size # Taille des anneaux de la planete (0: pas, 1: petit, 2: grand)
self.ring_color = ring_color # Couleur des anneaux de la planete

def data(self):
return [
self.name,
self.radius,
self.distance,
self.color,
self.information1,
self.information2,
self.game,
self.orbital_period,
self.moons,
self.sun_position,
self.ring_size,
self.ring_color
]

def check_hover_planet(self):
"""
Vérifie si la souris survole la planète
"""
distance_to_mouse = (self.x - pyxel.mouse_x) ** 2 + (self.y - pyxel.mouse_y) ** 2 # Calcul de la distance au carre
self.planet_hovered = distance_to_mouse <= (self.radius + 1) ** 2 # Verification de la survol

def update(self):
"""
Met à jours les planètes
"""
# Met a jour la position et l'etat de la planete a chaque frame
self.angle += self.speed # Mise a jour de l'angle orbital de la planete
self.x = self.sun_position[0] + self.distance * math.cos(self.angle) # Calcul de la position horizontale par rapport au soleil
self.y = self.sun_position[1] + self.distance * math.sin(self.angle) # Calcul de la position verticale par rapport au soleil
if self.angle < 2 * math.pi:
self.trace.append((self.x, self.y)) # Ajout de la position actuelle a la liste des positions precedentes
self.check_hover_planet() # Verification si la souris survole la planete

def draw(self):
"""
Dessine les planètes et leurs déplacements
"""
# Dessine la planete et ses elements associes
# Dessin des orbites
for i in range(1, len(self.trace)):
pyxel.line(self.trace[i-1][0], self.trace[i-1][1], self.trace[i][0], self.trace[i][1], 7) # Dessin de chaque segment de l'orbite
# Dessin de la planete
pyxel.circ(self.x, self.y, self.radius, self.color) # Dessin du corps de la planete
# Dessin des anneau de la planete
if self.ring_size == 1:
pyxel.line(self.x-self.radius, self.y-self.radius, self.x+self.radius, self.y+self.radius, self.ring_color) # Dessin d'anneaux de size petite
elif self.ring_size == 2:
pyxel.line(self.x-self.radius-1, self.y-self.radius-1, self.x+self.radius+1, self.y+self.radius+1, self.ring_color) # Dessin d'anneaux de size grande
# Affichage du nom de la planete au survol
if self.planet_hovered:
pyxel.text(self.x - len(self.name) * 2, self.y - self.radius - 10, self.name, COLOR_GREEN) # Affichage du nom
pyxel.circb(self.x, self.y, self.radius+2, COLOR_GREEN) # Dessin d'un contour autour de la planete

class SolarSystem:
"""
Classe du système solaire (regroupant toutes les autres fonctions)
"""
def __init__(self):
# Initialisation du systeme solaire avec le soleil, la position du soleil, les planetes et les asteroïdes
self.sun_position = (125, 125) # Position initiale du soleil
self.sun = [Sun("Soleil", self.sun_position[0], self.sun_position[1], "Il possède 214 lunes", "Vieux de 4,603 milliards d'années", 8)] # Creation de l'objet soleil
self.planets_data = [
{"name": "Mercure", "radius": 2, "distance": 30, "color": COLOR_GREY, "information1": "Mercure est la premiere planete du systeme solaire.", "information2": "La plus petite planete du systeme solaire.", "game": "game1", "orbital_period": 88, "moons": 0, "sun_position": self.sun_position, "ring_size": 0, "ring_color": None},
{"name": "Venus", "radius": 3, "distance": 45, "color": COLOR_YELLOW, "information1": "Venus est la deuxieme planete a partir du Soleil.", "information2": "Nommee d'apres la deesse romaine de l'amour et de la beaute.", "game": "game2", "orbital_period": 225, "moons": 0, "sun_position": self.sun_position, "ring_size": 0, "ring_color": None},
{"name": "Terre", "radius": 4, "distance": 60, "color": COLOR_BLUE, "information1": "La Terre est la troisieme planete a partir du Soleil.", "information2": "Le seul objet astronameique connu a abriter la vie.", "game": "game3", "orbital_period": 365, "moons": 1, "sun_position": self.sun_position, "ring_size": 0, "ring_color": None},
{"name": "Mars", "radius": 3, "distance": 80, "color": COLOR_RED, "information1": "Mars est la quatrieme planete a partir du Soleil.", "information2": "La deuxieme plus petite planete du systeme solaire.", "game": "game4", "orbital_period": 687, "moons": 2, "sun_position": self.sun_position, "ring_size": 0, "ring_color": None},
{"name": "Jupiter", "radius": 7, "distance": 110, "color": COLOR_LIGHTROSE, "information1": "Jupiter est la cinquieme planete a partir du Soleil.", "information2": "La plus grande planete du systeme solaire.", "game": "game5", "orbital_period": 4333, "moons": 79, "sun_position": self.sun_position, "ring_size": 0, "ring_color": None},
{"name": "Saturne", "radius": 6, "distance": 140, "color": COLOR_ROSE, "information1": "Saturne est la sixieme planete a partir du Soleil.", "information2": "La deuxieme plus grande du systeme solaire.", "game": "game6", "orbital_period": 10759, "moons": 82, "sun_position": self.sun_position, "ring_size": 2, "ring_color": COLOR_GREY},
{"name": "Uranus", "radius": 5, "distance": 170, "color": COLOR_CYAN, "information1": "Uranus est la septieme planete a partir du Soleil.", "information2": "L'atmosphere le plus froid du systeme solaire (−224°C).", "game": "game7", "orbital_period": 30688, "moons": 27, "sun_position": self.sun_position, "ring_size": 1, "ring_color": COLOR_GREY},
{"name": "Neptune", "radius": 4, "distance": 200, "color": COLOR_LIGHTBLUE, "information1": "Neptune est huitième planete, la plus eloignee du Soleil.", "information2": "Elle est nommee d'apres le dieu romain de la mer.", "game": "game8", "orbital_period": 60182, "moons": 14, "sun_position": self.sun_position, "ring_size": 0, "ring_color": None}
]
# Création de la liste des planètes
self.planets = []
for planet_data in self.planets_data:
planet = Planet(
planet_data["name"],
planet_data["radius"],
planet_data["distance"],
planet_data["color"],
planet_data["information1"],
planet_data["information2"],
planet_data["game"],
planet_data["orbital_period"],
planet_data["moons"],
planet_data["sun_position"],
planet_data["ring_size"],
planet_data["ring_color"]
)
self.planets.append(planet)
self.asteroids_data = [
{"name": "Ceres", "size": 940, "information1": "Asteroïde decouvert le : 1er janvier 1801", "information2": "Le plus grand asteroïde de la liste."},
{"name": "Pallas", "size": 544, "information1": "Asteroïde decouvert le : 28 mars 1802", "information2": "Le deuxieme plus grand asteroïde de la liste."},
{"name": "Vesta", "size": 525, "information1": "Asteroïde decouvert le : 29 mars 1807", "information2": "Le troisieme plus grand asteroïde de la liste."},
{"name": "Hygie", "size": 430, "information1": "Asteroïde decouvert le : 12 avril 1849", "information2": "Le quatrieme plus grand asteroïde de la liste."},
{"name": "Interamnia", "size": 350, "information1": "Asteroïde decouvert le : 2 octobre 1910", "information2": "Le cinquieme plus grand asteroïde de la liste."},
{"name": "Eunameia", "size": 268, "information1": "Asteroïde decouvert le : 29 juillet 1851", "information2": "Le sixieme plus grand asteroïde de la liste."},
{"name": "Sylvia", "size": 267, "information1": "Asteroïde decouvert le : 16 mai 1866", "information2": "Le septieme plus grand asteroïde de la liste."},
{"name": "Euphrosyne", "size": 260, "information1": "Asteroïde decouvert le : 1er septembre 1854", "information2": "Le huitieme plus grand asteroïde de la liste."},
{"name": "Davida", "size": 327, "information1": "Asteroïde decouvert le : 19 mai 1903", "information2": "Le neuvieme plus grand asteroïde de la liste."},
{"name": "Europe", "size": 315, "information1": "Asteroïde decouvert le : 4 fevrier 1857", "information2": "Le dixieme plus grand asteroïde de la liste."},
{"name": "Psyche", "size": 226, "information1": "Asteroïde decouvert le : 17 mars 1852", "information2": "Le onzieme plus grand asteroïde de la liste."},
{"name": "Herculine", "size": 225, "information1": "Asteroïde decouvert le : 20 avril 1880", "information2": "Le douzieme plus grand asteroïde de la liste."},
{"name": "Hestia", "size": 215, "information1": "Asteroïde decouvert le : 16 août 1880", "information2": "Le treizieme plus grand asteroïde de la liste."},
{"name": "Cybele", "size": 239, "information1": "Asteroïde decouvert le : 8 mars 1861", "information2": "Le quatorzieme plus grand asteroïde de la liste."},
{"name": "Themis", "size": 200, "information1": "Asteroïde decouvert le : 5 avril 1853", "information2": "Le quinzieme plus grand asteroïde de la liste."},
{"name": "Juno", "size": 233, "information1": "Asteroïde decouvert le : 1er septembre 1804", "information2": "Le seizieme plus grand asteroïde de la liste."},
{"name": "Hebe", "size": 186, "information1": "Asteroïde decouvert le : 1er juillet 1847", "information2": "Le dix-septieme plus grand asteroïde de la liste."},
{"name": "Doris", "size": 189, "information1": "Asteroïde decouvert le : 19 mai 1872", "information2": "Le dix-huitieme plus grand asteroïde de la liste."},
{"name": "Siwa", "size": 105, "information1": "Asteroïde decouvert le : 19 fevrier 1857", "information2": "Le dix-neuvieme plus grand asteroïde de la liste."},
{"name": "Iris", "size": 200, "information1": "Asteroïde decouvert le : 13 août 1847", "information2": "Le vingtieme plus grand asteroïde de la liste."},
{"name": "Florence", "size": 130, "information1": "Asteroïde decouvert le : 18 octobre 1847", "information2": "Le vingt et unieme plus grand asteroïde de la liste."},
{"name": "Metis", "size": 200, "information1": "Asteroïde decouvert le : 25 avril 1848", "information2": "Le vingt-deuxieme plus grand asteroïde de la liste."},
{"name": "Hera", "size": 210, "information1": "Asteroïde decouvert le : 7 septembre 1868", "information2": "Le vingt-troisieme plus grand asteroïde de la liste."},
{"name": "Victoria", "size": 112, "information1": "Asteroïde decouvert le : 13 septembre 1861", "information2": "Le vingt-quatrieme plus grand asteroïde de la liste."},
{"name": "Lutece", "size": 100, "information1": "Asteroïde decouvert le : 15 novembre 1852", "information2": "Le vingt-cinquieme plus grand asteroïde de la liste."},
{"name": "Ida", "size": 52, "information1": "Asteroïde decouvert le : 29 septembre 1884", "information2": "Le vingt-sixieme plus grand asteroïde de la liste."},
{"name": "Mathilde", "size": 52, "information1": "Asteroïde decouvert le : 17 novembre 1885", "information2": "Le vingt-septieme plus grand asteroïde de la liste."},
{"name": "Antiope", "size": 84, "information1": "Asteroïde decouvert le : 1er octobre 1866", "information2": "Le vingt-huitieme plus grand asteroïde de la liste."},
{"name": "Eugenie", "size": 214, "information1": "Asteroïde decouvert le : 27 juin 1857", "information2": "Le vingt-neuvieme plus grand asteroïde de la liste."},
{"name": "Hector", "size": 370, "information1": "Asteroïde decouvert le : 10 fevrier 1907", "information2": "Le trentieme plus grand asteroïde de la liste."},
{"name": "Cleopâtre", "size": 135, "information1": "Asteroïde decouvert le : 10 avril 1880", "information2": "Le trente et unieme plus grand asteroïde de la liste."},
{"name": "Antiope", "size": 84, "information1": "Asteroïde decouvert le : 1er octobre 1866", "information2": "Le trente-deuxieme plus grand asteroïde de la liste."},
{"name": "Éros", "size": 34.4, "information1": "Asteroïde decouvert le : 13 août 1898", "information2": "Le trente-troisieme plus grand asteroïde de la liste."},
{"name": "Gaspra", "size": 18, "information1": "Asteroïde decouvert le : 30 juillet 1991", "information2": "Le trente-quatrieme plus grand asteroïde de la liste."},
{"name": "Mathilde", "size": 52, "information1": "Asteroïde decouvert le : 17 novembre 1885", "information2": "Le trente-cinquieme plus grand asteroïde de la liste."},
{"name": "Gryphon", "size": 6, "information1": "Asteroïde decouvert le : 19 avril 1848", "information2": "Le trente-sixieme plus grand asteroïde de la liste."},
{"name": "Alinda", "size": 7, "information1": "Asteroïde decouvert le : 27 fevrier 1919", "information2": "Le trente-septieme plus grand asteroïde de la liste."}
] # Donnees sur les asteroïdes avec leurs noms, tailles et informations
self.asteroids = []
self.max_asteroids = 5
while len(self.asteroids) < self.max_asteroids:
self.create_asteroids() # Creation des asteroïdes
self.selected_planet = None # Planete selectionnee (initialisation a None)
self.year = 0 # Compteur d'annees initialise a zero
self.day = 0 # Compteur d'annees initialise a zero

def create_asteroids(self):
"""
Cree de nouveaux asteroïdes
"""
asteroid_data = random.choice(self.asteroids_data) # Selectionne aleatoirement les donnees d'un asteroïde
x = random.randint(0, pyxel.width) # Coordonnee x aleatoire
y = random.randint(0, pyxel.height) # Coordonnee y aleatoire
size = asteroid_data["size"] // 125 # Taille de l'asteroïde (normalisee)
color = random.choice([COLOR_GREY, COLOR_BROWN]) # Couleur de l'asteroïde
new_asteroid = Asteroid(x, y, size, color, asteroid_data["name"], asteroid_data["information1"], asteroid_data["information2"]) # Cree un nouvel objet Asteroïde
self.asteroids.append(new_asteroid) # Ajoute l'asteroïde a la liste des asteroïdes

def update(self):
"""
Met a jour le système solaire
"""
for planet in self.planets:
planet.update()
for asteroid in range(len(self.asteroids)):
self.asteroids[asteroid].update()
# Supprime les asteroïdes qui sortent de l'ecran
if self.asteroids[asteroid].x < 0 or self.asteroids[asteroid].x > pyxel.width or self.asteroids[asteroid].y > pyxel.height or self.asteroids[asteroid].y < 0 or self.asteroids[asteroid].explosion_over:
del(self.asteroids[asteroid])
# Genere de nouveaux asteroïdes s'il y en a moins que le maximum autorise
while len(self.asteroids) < self.max_asteroids:
self.create_asteroids()
for sun in self.sun:
sun.update()
# Incremente les compteurs
self.year += 1/365
self.day += 1

def draw(self):
"""
Dessine le système solaire
"""
# Efface l'ecran
pyxel.cls(0)
# Dessine des etoiles aleatoires
for _ in range((pyxel.width+pyxel.height)//15):
x = random.randint(0, pyxel.width)
y = random.randint(0, pyxel.height)
pyxel.pset(x, y, COLOR_WHITE)
# Dessine les asteroïdes
for asteroid in self.asteroids:
asteroid.draw()
# Dessine le soleil
for sun in self.sun:
sun.draw()
# Dessine les planetes
for planet in self.planets:
planet.draw()
# Affiche les compteurs
pyxel.text(5, 5, "JOURS : " + str(int(self.day)), COLOR_WHITE)
pyxel.text(5, 15, "ANNEES : " + str(int(self.year)), COLOR_WHITE)

class End:
"""
Classe de la fin de l'univers (soleil qui explose)
"""
def __init__(self):
self.explosion_size = 0
self.explosion_size_max = pyxel.width*1.5
self.particles = []
self.end_starting = False

def update(self):
"""
Met à jour l'explosion du soleil
"""
# L'explosion est lancée
self.end_starting = True
# Tant que le cercle d'explosion ne fait pas sa taille maximale
if self.explosion_size <= self.explosion_size_max:
self.explosion_size += 1
self.explosion_random_x = random.randint(0, pyxel.height)
self.explosion_random_y = random.randint(0, pyxel.width)
# Generer des petites particules d'explosion
for _ in range(250):
angle = random.uniform(0, 2 * math.pi) # Angle de direction aleatoire
speed = random.uniform(1.5, 3.5) # Vitesse aleatoire des particules
color = random.choice([COLOR_RED, COLOR_ORANGE, COLOR_YELLOW]) # Couleur aleatoire des particules
self.particles.append([CENTER_X, CENTER_Y, color, math.cos(angle) * speed, math.sin(angle) * speed]) # Ajout des particules a la liste

def draw(self):
"""
Dessine l'explosion du soleil
"""
# Efface l'écran
pyxel.cls(0)
# Explosion
if self.explosion_size <= self.explosion_size_max:
# Dessine l'explosion du soleil
for i in range(0, 10):
# Rayon d'explosion
pyxel.circb(CENTER_X, CENTER_Y, self.explosion_size+i, random.choice([COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREY]))
# Explosion pour simuler des "fausses collisions"
pyxel.circb(self.explosion_random_x, self.explosion_random_y, i, random.choice([COLOR_RED, COLOR_ORANGE, COLOR_YELLOW, COLOR_GREY]))
# Dessiner les petites particules d'explosion
for particle in self.particles:
pyxel.pset(particle[0], particle[1], particle[2]) # Dessiner une particule d'explosion
particle[0] += particle[3] # Mise a jour de la position horizontale de la particule
particle[1] += particle[4] # Mise a jour de la position verticale de la particule
# Efface tout ce qui a déjà explosé
pyxel.circ(CENTER_X, CENTER_Y, self.explosion_size, COLOR_PURPLE)
# Dessiner le cercle lumineux
radius = self.explosion_size // 10
pyxel.circ(CENTER_X, CENTER_Y, radius, COLOR_WHITE)
# Calculer le nombre de points en fonction du rayon du cercle
num_points = int(2 * math.pi * radius)
# Calculer l'écart entre le cercle et les points
gap_size = radius * 0.2
# Dessiner les points autour du cercle avec un espacement variable
for i in range(num_points):
angle = (i / num_points) * 2 * math.pi
# Ajouter un écart entre le cercle et certains points
if random.random() < 0.5: # ajustez ce seuil selon la proportion de points avec écart désirée
point_x = CENTER_X + (radius + gap_size) * math.cos(angle)
point_y = CENTER_Y + (radius + gap_size) * math.sin(angle)
else:
point_x = CENTER_X + radius * math.cos(angle)
point_y = CENTER_Y + radius * math.sin(angle)
pyxel.pset(int(point_x), int(point_y), COLOR_WHITE)
# Ecran final
else:
# Affiche les crédits
pyxel.text(5, 100, "C'est la fin, vous venez d'assister a l'explosion du soleil", COLOR_WHITE)
pyxel.text(55, 110, "Par les créateurs de", COLOR_WHITE)
pyxel.text(133, 110, "QUOICOUNEIGHBOR 1", random.randint(0, 15))
pyxel.text(90, 120, "Merci d'avoir joue !", COLOR_WHITE)


########################################################
### JEUX 1 : Balle sous gravité
########################################################

class Game1:
"""
Jeu de : Balle sous gravité
"""
def __init__(self, selectioned_planet):
self.selectionned_planet = selectioned_planet
self.game_over = False

def reset(self):
pass

def update(self):
pass

def draw(self):
pass

########################################################
### JEUX 2 : Esquiver obstacles (inspiré de Dino T-REX
########################################################

class Game2:
"""
Jeu de : Dinosaure
"""
def __init__(self, selectioned_planet):
self.selectionned_planet = selectioned_planet
self.game_over = False

def reset(self):
pass

def update(self):
pass

def draw(self):
pass

########################################################
### JEUX 3 : Saut de platformes (inspiré de Doodle Jump)
########################################################


class Player:
def __init__(self, x, y):
self.x = x
self.y = y
self.dy = 0
self.jump_power = -8

def update(self, platforms):
self.y += self.dy
self.dy += 1

# Check if the player is on a platform
on_platform = False
for platform in platforms:
if (
self.y <= platform.y
and self.y + 6 >= platform.y
and self.x + 6 >= platform.x
and self.x <= platform.x + platform.width
):
on_platform = True
self.y = platform.y - 6
self.dy = 0
break

# Player movement
if pyxel.btn(pyxel.KEY_UP) and on_platform:
self.dy = self.jump_power

def draw(self):
pyxel.rect(self.x, self.y, 6, 6, 9)

class Platform:
def __init__(self, x, y, width=30, height=4):
self.x = x
self.y = y
self.width = width
self.height = height
self.visible = True

def update(self):
pass

def draw(self):
if self.visible:
pyxel.rect(self.x, self.y, self.width, self.height, 3)

class Game3:
def __init__(self, planet):
self.player = Player(120, 200)
self.platforms = [Platform(random.randint(0, 220), i * 20) for i in range(19)]
self.platforms.append(Platform(110, 220))
self.score = 0
self.game_over = False
self.planet = planet

def update(self):
if pyxel.btn(pyxel.KEY_LEFT) and self.player.x > 0:
if not any(
self.player.y + 6 > platform.y
and self.player.y < platform.y + platform.height
and self.player.x - 1 <= platform.x + platform.width
and self.player.x >= platform.x + platform.width
for platform in self.platforms
):
self.player.x -= 1

if pyxel.btn(pyxel.KEY_RIGHT) and self.player.x < 244:
if not any(
self.player.y + 6 > platform.y
and self.player.y < platform.y + platform.height
and self.player.x + 7 >= platform.x
and self.player.x + 7 < platform.x
for platform in self.platforms
):
self.player.x += 1

self.player.update(self.platforms)

# Game over condition
if self.player.y > 250:
self.game_over = True

def draw(self):
pyxel.cls(0)
self.player.draw()

for platform in self.platforms:
platform.draw()

pyxel.text(5, 5, "Score: {}".format(self.score), 7)
pyxel.text(5, 15, "Planet: {}".format(self.planet), 7)

########################################################
### JEUX 4 :
########################################################

class Game4:
"""
Jeu de : ?
"""
def __init__(self, selected_planet):
self.selected_planet = selected_planet
self.game_over = False

def reset(self):
pass

def update(self):
pass

def draw(self):
pass

########################################################
### LANCEMENT PROGRAMME / CHANGEMENTS
########################################################

class App:
"""
Classe du lancement du programme
"""
def __init__(self):
pyxel.init(PYXEL_WIDTH, PYXEL_HEIGHT, fps=30)
# Initialisation du systeme solaire
self.solar_system = SolarSystem()
self.end = End()
self.game1 = None
self.game2 = None
self.game3 = None
self.game4 = None
# Initialisation de l'objet selectionne a None
self.selected_object = None
self.selected_planet = None
self.game_selection = None
self.game_selected = 0
# Definition des coordonnees et dimensions des boutons
self.game1_button_x = 10
self.game1_button_y = 10
self.game1_button_width = 110
self.game1_button_height = 110
self.game2_button_x = 130
self.game2_button_y = 10
self.game2_button_width = 110
self.game2_button_height = 110
self.game3_button_x = 10
self.game3_button_y = 130
self.game3_button_width = 110
self.game3_button_height = 110
self.game4_button_x = 130
self.game4_button_y = 130
self.game4_button_width = 110
self.game4_button_height = 110
pyxel.mouse(True)
pyxel.run(self.update, self.draw)

def update(self):
"""
Met à jour les interactions utilisateur et le jeu en fonction de celles-ci
"""
# Gestion des clics de souris
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT) and self.solar_system.year < 100:
# Si l'univers est encore "existant", verification des clics sur les boutons de retour et d'action
if self.selected_object:
# Clic sur le bouton de retour
if (return_button_x <= pyxel.mouse_x <= return_button_x + action_return_width and return_button_y <= pyxel.mouse_y <= return_button_y + action_return_height):
self.selected_object = None
# Clic sur le bouton d'action
if (action_button_x <= pyxel.mouse_x <= action_button_x + action_button_width and action_button_y <= pyxel.mouse_y <= action_button_y + action_button_height): # Vérification du type d'objet sélectionné
if isinstance(self.selected_object, Asteroid):
# Déclenchement de l'explosion de l'astéroïde
self.selected_object.start_explosion()
self.selected_object = None
elif isinstance(self.selected_object, Planet):
# Lance le sélectionneur de jeu
self.game_selection = True
self.selected_object = None
elif isinstance(self.selected_object, Sun):
# Démarre le grand déchirement
self.selected_object = None
self.solar_system.year = 100

elif self.game_selection:
if (self.game1_button_x <= pyxel.mouse_x <= self.game1_button_x + self.game1_button_width and self.game1_button_y <= pyxel.mouse_y <= self.game1_button_y + self.game1_button_height):
self.game_selected = 1
elif (self.game2_button_x <= pyxel.mouse_x <= self.game2_button_x + self.game2_button_width and self.game2_button_y <= pyxel.mouse_y <= self.game2_button_y + self.game2_button_height):
self.game_selected = 2
elif (self.game3_button_x <= pyxel.mouse_x <= self.game3_button_x + self.game3_button_width and self.game3_button_y <= pyxel.mouse_y <= self.game3_button_y + self.game3_button_height):
self.game_selected = 3
elif (self.game4_button_x <= pyxel.mouse_x <= self.game4_button_x + self.game4_button_width and self.game4_button_y <= pyxel.mouse_y <= self.game4_button_y + self.game4_button_height):
self.game_selected = 4

if self.game_selected != 0:
self.game1 = Game1(self.selected_planet)
self.game2 = Game2(self.selected_planet)
self.game3 = Game3(self.selected_planet)
self.game4 = Game4(self.selected_planet)
self.game_selection = False

else:
# Vérification des survols des planètes, soleil et des astéroïdes
for sun in self.solar_system.sun:
if sun.sun_hovered:
self.selected_object = sun
break
for planet in self.solar_system.planets:
if planet.planet_hovered:
self.selected_object = planet
self.selected_planet = planet.data()
break
for asteroid in self.solar_system.asteroids:
if asteroid.asteroid_hovered:
# Vérifie si l'astéroïde a déjà explosé
if not asteroid.exploding:
self.selected_object = asteroid
break

# Mise à jour du système solaire/jeux uniquement si aucun objet n'est sélectionné
if not self.selected_object:
if self.solar_system.year >= 100: # Dessine la fin de l'univers et les crédits si le jeu est fini
self.end.update()
elif self.game_selected == 1:
# Si le joueur a perdu
if self.game1.game_over:
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
# Clic sur le bouton de retour
if (return_button_x <= pyxel.mouse_x <= return_button_x + action_return_width and return_button_y <= pyxel.mouse_y <= return_button_y + action_return_height):
self.game_selected = 0
self.game1.reset()
# Clic sur le bouton d'action
elif (action_button_x <= pyxel.mouse_x <= action_button_x + action_button_width and action_button_y <= pyxel.mouse_y <= action_button_y + action_button_height): # Vérification du type d'objet sélectionné
self.game1.reset()
else:
self.game1.update()
elif self.game_selected == 2:
# Si le joueur a perdu
if self.game2.game_over:
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
# Clic sur le bouton de retour
if (return_button_x <= pyxel.mouse_x <= return_button_x + action_return_width and return_button_y <= pyxel.mouse_y <= return_button_y + action_return_height):
self.game_selected = 0
self.game2.reset()
# Clic sur le bouton d'action
elif (action_button_x <= pyxel.mouse_x <= action_button_x + action_button_width and action_button_y <= pyxel.mouse_y <= action_button_y + action_button_height): # Vérification du type d'objet sélectionné
self.game2.reset()
else:
self.game2.update()
elif self.game_selected == 3:
# Si le joueur a perdu
if self.game3.game_over:
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
# Clic sur le bouton de retour
if (return_button_x <= pyxel.mouse_x <= return_button_x + action_return_width and return_button_y <= pyxel.mouse_y <= return_button_y + action_return_height):
self.game_selected = 0
self.game3.reset()
# Clic sur le bouton d'action
elif (action_button_x <= pyxel.mouse_x <= action_button_x + action_button_width and action_button_y <= pyxel.mouse_y <= action_button_y + action_button_height): # Vérification du type d'objet sélectionné
self.game3.reset()
else:
self.game3.update()
elif self.game_selected == 4:
# Si le joueur a perdu
if self.game4.game_over:
if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
# Clic sur le bouton de retour
if (return_button_x <= pyxel.mouse_x <= return_button_x + action_return_width and return_button_y <= pyxel.mouse_y <= return_button_y + action_return_height):
self.game_selected = 0
self.game4.reset()
# Clic sur le bouton d'action
elif (action_button_x <= pyxel.mouse_x <= action_button_x + action_button_width and action_button_y <= pyxel.mouse_y <= action_button_y + action_button_height): # Vérification du type d'objet sélectionné
self.game4.reset()
else:
self.game4.update()
else: # Dessin du système solaire
self.solar_system.update()

def draw(self):
"""
Dessine chaque fonction possible en fonction des choix de l'utilisateur
"""
# Efface l'ecran
pyxel.cls(0)
# Dessine l'interface de l'objet selectionne ou le systeme solaire complet
if self.selected_object:
# Dessin des boutons de retour et d'action
pyxel.rectb(return_button_x, return_button_y, action_return_width, action_return_height, COLOR_WHITE)
pyxel.text(return_button_x + 5, return_button_y + 5, "Retour", COLOR_WHITE)
pyxel.rectb(action_button_x, action_button_y, action_button_width, action_button_height, COLOR_WHITE)
# Affichage de l'objet en grand
obj_radius = self.selected_object.radius * 6.5
# Dessin d'un cercle pour representer l'objet selectionne
pyxel.circ(125, 100, obj_radius, self.selected_object.color)
# Affichage du nom de l'objet
text_width = len(self.selected_object.name) * pyxel.FONT_WIDTH
pyxel.text(125 - text_width // 2, 10, self.selected_object.name, COLOR_WHITE)
# Affichage des informationrmations sur l'objet
pyxel.text(5, 165, self.selected_object.information1, COLOR_WHITE)
pyxel.text(5, 175, self.selected_object.information2, COLOR_WHITE)
# Dessin de l'écran de la planète
if isinstance(self.selected_object, Planet):
pyxel.text(action_button_x + 5, action_button_y + 5, "Jouer", COLOR_WHITE)
# Affichage des anneaux
if self.selected_object.ring_size >= 1:
ring_radius = obj_radius + self.selected_object.ring_size * 6
ring_x = 125
ring_y = 100
for i in range(-6*self.selected_object.ring_size, 6*self.selected_object.ring_size):
pyxel.line(ring_x - ring_radius + i, ring_y - ring_radius, ring_x + ring_radius + i, ring_y + ring_radius, self.selected_object.ring_color)
# Affichage de la periode orbitale et du nombre de lunes pour les planetes
pyxel.text(5, 185, "Jours par orbite : " + str(self.selected_object.orbital_period), COLOR_WHITE)
pyxel.text(5, 195, "Nombre de lunes : " + str(self.selected_object.moons), COLOR_WHITE)
# Dessin de l'écran de l'astéroide
elif isinstance(self.selected_object, Asteroid):
pyxel.text(action_button_x + 5, action_button_y + 5, "Exploser", COLOR_WHITE)
# Dessin de l'écran du soleil
elif isinstance(self.selected_object, Sun):
pyxel.text(action_button_x + 5, action_button_y + 5, "End.", COLOR_WHITE)

elif self.game_selection:
# Jeu 1
pyxel.rectb(self.game1_button_x, self.game1_button_y, self.game1_button_width, self.game1_button_height, COLOR_WHITE)
pyxel.text(self.game1_button_x + 5, self.game1_button_y + 5, "JEU 1", COLOR_WHITE)
# Jeu 2
pyxel.rectb(self.game2_button_x, self.game2_button_y, self.game2_button_width, self.game2_button_height, COLOR_WHITE)
pyxel.text(self.game2_button_x + 5, self.game2_button_y + 5, "JEU 2", COLOR_WHITE)
# Jeu 3
pyxel.rectb(self.game3_button_x, self.game3_button_y, self.game3_button_width, self.game3_button_height, COLOR_WHITE)
pyxel.text(self.game3_button_x + 5, self.game3_button_y + 5, "JEU 3", COLOR_WHITE)
# Jeu 4
pyxel.rectb(self.game4_button_x, self.game4_button_y, self.game4_button_width, self.game4_button_height, COLOR_WHITE)
pyxel.text(self.game4_button_x + 5, self.game4_button_y + 5, "JEU 4", COLOR_WHITE)

else:
# Mise à jour du système solaire/jeux uniquement si aucun objet n'est sélectionné
if not self.selected_object:
if self.solar_system.year >= 100: # Dessine la fin de l'univers et les crédits si le jeu est fini
self.end.draw()
elif self.game_selected == 1:
if self.game1.game_over:
pyxel.cls(0)
pyxel.text(90, 120, "Game Over", COLOR_ROSE)
pyxel.rectb(return_button_x, return_button_y, action_return_width, action_return_height, COLOR_WHITE)
pyxel.text(return_button_x + 5, return_button_y + 5, "Retour", COLOR_WHITE)
pyxel.rectb(action_button_x, action_button_y, action_button_width, action_button_height, COLOR_WHITE)
pyxel.text(action_button_x + 5, action_button_y + 5, "Rejouer", COLOR_WHITE)
else:
self.game1.draw()
elif self.game_selected == 2:
if self.game2.game_over:
pyxel.cls(0)
pyxel.text(90, 120, "Game Over", COLOR_ROSE)
pyxel.rectb(return_button_x, return_button_y, action_return_width, action_return_height, COLOR_WHITE)
pyxel.text(return_button_x + 5, return_button_y + 5, "Retour", COLOR_WHITE)
pyxel.rectb(action_button_x, action_button_y, action_button_width, action_button_height, COLOR_WHITE)
pyxel.text(action_button_x + 5, action_button_y + 5, "Rejouer", COLOR_WHITE)
else:
self.game2.draw()
elif self.game_selected == 3:
if self.game3.game_over:
pyxel.cls(0)
pyxel.text(90, 120, "Game Over", COLOR_ROSE)
pyxel.text(90, 130, "SCORE : " + str(self.game3.score), COLOR_ROSE)
pyxel.rectb(return_button_x, return_button_y, action_return_width, action_return_height, COLOR_WHITE)
pyxel.text(return_button_x + 5, return_button_y + 5, "Retour", COLOR_WHITE)
pyxel.rectb(action_button_x, action_button_y, action_button_width, action_button_height, COLOR_WHITE)
pyxel.text(action_button_x + 5, action_button_y + 5, "Rejouer", COLOR_WHITE)
else:
self.game3.draw()
elif self.game_selected == 4:
if self.game4.game_over:
pyxel.cls(0)
pyxel.text(90, 120, "Game Over", COLOR_ROSE)
pyxel.rectb(return_button_x, return_button_y, action_return_width, action_return_height, COLOR_WHITE)
pyxel.text(return_button_x + 5, return_button_y + 5, "Retour", COLOR_WHITE)
pyxel.rectb(action_button_x, action_button_y, action_button_width, action_button_height, COLOR_WHITE)
pyxel.text(action_button_x + 5, action_button_y + 5, "Rejouer", COLOR_WHITE)
else:
self.game4.draw()
else: # Dessin du système solaire
self.solar_system.draw()

# Lancement de l'application
App()
  • app.py