]> git.ayabusa.dev Git - jeu-gtc.git/commitdiff
added a ton of comments main
authorayabusa <lebgpub@gmail.com>
Sat, 26 Oct 2024 06:23:07 +0000 (08:23 +0200)
committerayabusa <lebgpub@gmail.com>
Sat, 26 Oct 2024 06:23:07 +0000 (08:23 +0200)
assets/gameover.png
game.py

index 4624aaa161417e625d0746748a566e5e2dd23f72..89e02fb1e87eb20b8e4951c9d6f24608c91ef6ae 100644 (file)
Binary files a/assets/gameover.png and b/assets/gameover.png differ
diff --git a/game.py b/game.py
index 9827214f74a71487c0d0f07defaf44248a13df19..c237791330c57a716ebb5f08b7adba56b28cd586 100644 (file)
--- a/game.py
+++ b/game.py
@@ -1,9 +1,8 @@
-# Example file showing a basic pygame "game loop"\r
+# Here we import everything we need\r
 import pygame\r
 import math\r
 import csv\r
 import random\r
-import datetime\r
 \r
 # pygame setup\r
 pygame.init()\r
@@ -12,11 +11,9 @@ clock = pygame.time.Clock()
 running = True\r
 dt = 0\r
 \r
-player_sprite = pygame.Rect(100,100,50,50)\r
-mur = pygame.Rect(500,100,100,100)\r
-\r
 class Waypoint:\r
     def __init__(self, name: str) -> None:\r
+        """Create the corresponding waypoint according to the letter specified in name: str"""\r
         self.name = name\r
         match name.capitalize():\r
             case "A":\r
@@ -53,10 +50,12 @@ class Waypoint:
                 self.connection = ("A", "G")\r
 \r
     def get_new_connected(self)-> object:\r
+        """Return a new waypoint connected to the current one"""\r
         letter = random.choice(self.connection)\r
         return Waypoint(letter)\r
     \r
     def get_direction(self, pointA: object, pointB: object)-> str:\r
+        """Helper that returns the direction: str from pointA: Waypoint, to pointB: Waypoint"""\r
         a = pointA.name\r
         b = pointB.name\r
         if (a == "H" and b == "A") or (a == "G" and b == "E") or (a == "E" and b == "B") or (a == "F" and b == "D") or (a == "D" and b == "C"):\r
@@ -68,10 +67,18 @@ class Waypoint:
         elif (a == "B" and b == "A") or (a == "C" and b == "B") or (a == "D" and b == "E") or (a == "G" and b == "H") or (a == "F" and b == "G"):\r
             return "west"\r
         else:\r
+            # If the direction is impossible\r
             raise Exception("crash: POINT A and B impossible")\r
                 \r
 class Pnj:\r
     def __init__(self, x: int, y: int, sprite_path: str, direction: str, objectif: Waypoint, speed: int) -> None:\r
+        """Create a single pnj with the following attributes:\r
+         - x: int, x coordinate\r
+         - y: int, y coordinate\r
+         - sprite_path: str, the path to the sprite of the pnj\r
+         - direction: str, the direction can be "north", "south", "east", or "west"\r
+         - objectif: Waypoint, the goal of the pnj\r
+         - speed: int, the desired speed of the pnj"""\r
         self.x = x\r
         self.y = y\r
         self.sprite = pygame.transform.scale_by(pygame.image.load(sprite_path), 3.0)\r
@@ -103,7 +110,7 @@ class Pnj:
     \r
     def check_objectif(self):\r
         """\r
-        Vérifie que l'objectif n'est pas atteint et renvoie true si un l'est, s'occupe aussi de réassigner un nouvel objectig\r
+        Vérifie que l'objectif n'est pas atteint et renvoie true si un l'est, s'occupe aussi de réassigner un nouvel objectif\r
         """\r
         match self.direction:\r
             case "north":\r
@@ -133,6 +140,7 @@ class Pnj:
         return False\r
     \r
     def kill(self):\r
+        """Kill the PNJ by replacing it with a blood splatter"""\r
         self.sprite = pygame.transform.scale_by(pygame.image.load("assets/blood.png"), 3.0)\r
         self.alive = False\r
         player.killcounter += 1\r
@@ -146,32 +154,36 @@ class Pnj:
 \r
 class Village:\r
     def __init__(self, nb_pnj: int) -> None:\r
+        """This class defines the village of pnj in it's globality and nb_pnj (int) determines how many pnj should be generated"""\r
         self.liste_pnj = []\r
+        # here we generate each pnj randomly and store it in liste_pnj\r
         for i in range(nb_pnj):\r
             start_waypoint = Waypoint(random.choice(("A", "B", "C", "D", "E", "F", "G", "H")))\r
             objective_waypoint = start_waypoint.get_new_connected()\r
             self.liste_pnj.append(Pnj(start_waypoint.x, start_waypoint.y, "assets/pnj/pnj"+str(random.randint(1,8))+".png", start_waypoint.get_direction(start_waypoint, objective_waypoint), objective_waypoint, random.randint(1, 4)))\r
-\r
-    def ajouter_pnj_random(self)-> None:\r
-        pass\r
-\r
+    \r
     def update_pnj(self)-> None:\r
+        """Make each pnj move a little bit"""\r
         for p in self.liste_pnj:\r
             p.avance()\r
 \r
     def get_village_sprites(self)->list:\r
+        """Method that returns a list of tuple containing the coordinates and sprite of a pnj\r
+        The tuple is in this shape: (x, y, sprite)"""\r
         village_sprites = []\r
-        for p in self.liste_pnj:\r
+        for p in self.liste_pnj: \r
             village_sprites.append((p.x, p.y, p.sprite))\r
         return village_sprites\r
     \r
     def check_kill(self)->None:\r
+        """Check for each pnj if he is being killed by the player"""\r
         player_rect = pygame.Rect(player.x-50, player.y-50, 100, 100)\r
         for p in self.liste_pnj:\r
             if p.alive and player_rect.collidepoint(p.x, p.y):\r
                 p.kill()\r
     \r
     def final_boss(self)->None:\r
+        """Called when all original pnj where killed, it create an army of really fast knight"""\r
         for i in ("A", "B", "C", "D", "E", "F", "G", "H"):\r
             start_waypoint = Waypoint(i)\r
             objective_waypoint = start_waypoint.get_new_connected()\r
@@ -179,6 +191,8 @@ class Village:
             \r
 class Player:\r
     def __init__(self)-> None:\r
+        """This class defines how the player can behave, \r
+        it should be created as soon as possible and only once in the game"""\r
         self.x = 800\r
         self.y = 900\r
         self.mov_speed = 8\r
@@ -187,9 +201,11 @@ class Player:
         self.killcounter = 0\r
 \r
     def rotate(self, angle: math.degrees)-> None:\r
+        """Rotate the player to the desired angle"""\r
         self.angle += angle*self.rotate_speed\r
     \r
     def move(self, mov: int)-> None:\r
+        """Move the player in the direction he is looking or backward if mov is negative"""\r
         new_x = self.x + self.mov_speed*mov*math.cos(math.radians(self.angle))\r
         new_y = self.y + self.mov_speed*mov*math.sin(math.radians(self.angle))\r
         if(game.test_collision(pygame.Rect(new_x-50, new_y-50, 100, 100), game.collisions) == False):\r
@@ -203,6 +219,8 @@ class Player:
 \r
 class Game:\r
     def __init__(self):\r
+        """The main class that defines the game and it's behaviour, \r
+        it should be created only once during the game, as soon as possible"""\r
         self.is_paused = False\r
         self.pnj_number = 20\r
         pygame.font.init()\r
@@ -211,23 +229,30 @@ class Game:
         self.load_collisions()\r
     \r
     def load_sprites(self):\r
+        """Useful to load sprites in memory, should be called as soon as possible to avoid errors"""\r
         self.perso_sprite = pygame.image.load("assets/Horse2.png")\r
         self.map_sprite = pygame.image.load("assets/map3.png")\r
     \r
     def load_collisions(self):\r
+        """Load all collisions stored in the sheets located in assets/collisions.csv, \r
+        should be called as soon as possible to avoid errors"""\r
         self.collisions = []\r
         with open('assets/collisions.csv', 'r', newline='') as file:\r
             reader = csv.DictReader(file)\r
             for row in reader:\r
                 self.collisions.append(pygame.Rect(float(row["starting_point_x"]), float(row["starting_point_y"]), float(row["len_x"]), float(row["len_y"])))\r
 \r
-    def test_collision(self, objet: pygame.Rect, l_collisions) -> bool:\r
+    def test_collision(self, objet: pygame.Rect, l_collisions: list) -> bool:\r
+        """This is an helper to check if there is collision between an object (pygame.Rect) and a list\r
+        of collisions containing pygame.Rect"""\r
         for col in l_collisions:\r
             if objet.colliderect(col):\r
                 return True\r
         return False\r
 \r
     def display_debug_text(self):\r
+        """This is only for debuging and should be called in display_all() if in debug mode,\r
+        but not on the final game"""\r
         angle_surface = self.font.render("angle: "+str(player.angle), False, (0, 0, 0))\r
         x_surface = self.font.render("x: "+str(player.x), False, (0, 0, 0))\r
         y_surface = self.font.render("y: "+str(player.y), False, (0, 0, 0))\r
@@ -239,7 +264,10 @@ class Game:
         #pygame.draw.rect(screen, "blue",pygame.Rect(player.x-50, player.y-50, 100, 100))\r
 \r
     def display_ui(self):\r
+        """Handle the display of the killcounter and time,\r
+        should be called at each frames"""\r
         color = "black"\r
+\r
         if player.killcounter < game.pnj_number:\r
             kill_surface = self.font.render("Kills: "+str(player.killcounter)+"\\"+str(game.pnj_number), False, color)\r
         else:\r
@@ -255,6 +283,7 @@ class Game:
         screen.blit(time_surface, (740,0))\r
 \r
     def check_input(self):\r
+        """Here we check all possible user input and execut and action acordingly"""\r
         keys = pygame.key.get_pressed()\r
         if keys[pygame.K_z]:\r
             _ = player.move(1)\r
@@ -266,31 +295,33 @@ class Game:
             player.rotate(1)\r
     \r
     def draw_player(self):\r
-        #pygame.draw.rect(screen, "red", pygame.Rect(player.x, player.y, 50, 50))\r
+        """Draw the player after applying a rotozoom in the center of the screen"""\r
         img = pygame.transform.rotozoom(self.perso_sprite, -player.angle-90, 1)\r
         screen.blit(img, (540-img.get_rect().centerx, 360-img.get_rect().centery))\r
 \r
     def draw_village(self):\r
+        """Draw each sprite of the village"""\r
         for s in village.get_village_sprites():\r
             screen.blit(s[2], (540-player.x + s[0] - s[2].get_rect().centerx, 360-player.y + s[1] - s[2].get_rect().centery))\r
 \r
     def display_all(self):\r
-        # fill the screen with a color to wipe away anything from last frame\r
+        """This is a helper that will render everything needed on the screen"""\r
+        # fill the screen with a color to wipe away anything from last frame and draw the map\r
         screen.fill("gray")\r
         screen.blit(self.map_sprite, (540-player.x, 360-player.y))\r
 \r
         self.draw_village()\r
         self.draw_player()\r
 \r
-        # We display it at the end so it's on top of all\r
-        # self.display_debug_text()\r
-\r
+        # We display them at the end so it's on top of all\r
+        #self.display_debug_text()\r
         self.display_ui()\r
 \r
-        # flip() the display to put your work on screen\r
+        # flip() the display to put our work on screen\r
         pygame.display.flip()\r
 \r
     def game_over(self)->None:\r
+        """Create a gameover loop displaying the scoreboard and an image"""\r
         screen.blit(pygame.image.load("assets/gameover.png"), (0,0))\r
         seconds = pygame.time.get_ticks()/1000\r
         seconds = seconds % (24 * 3600)\r
@@ -308,32 +339,34 @@ class Game:
                 if event.type == pygame.QUIT:\r
                     exit()\r
 \r
+# Here we create the principal objects that will always be used during the game\r
 player = Player()\r
 game = Game()\r
-#pnj = Pnj(800, 900, "assets/MiniPeasant.png", "south", Waypoint("H"), 3)\r
 village = Village(game.pnj_number)\r
 \r
-# start music\r
+# start music with -1 meaning infinite loop\r
 pygame.mixer.music.load("assets/music.mp3")\r
 pygame.mixer.music.play(-1)\r
 \r
-\r
+# Infinite game loop\r
 while running:\r
     # poll for events\r
-    # pygame.QUIT event means the user clicked X to close your window\r
+    # pygame.QUIT event means the user clicked X on the window\r
     for event in pygame.event.get():\r
         if event.type == pygame.QUIT:\r
             running = False\r
     # make all the pnj move and do their pnj stuff\r
     village.update_pnj()\r
 \r
+    # Here we check all inputs from the user and do what is requiered\r
     game.check_input()\r
     \r
+    # Here we display everything to the screen\r
     game.display_all()\r
 \r
     # limits FPS to 60\r
-    # dt is delta time in seconds since last frame, used for framerate-\r
-    # independent physics.\r
+    # dt is delta time in seconds since last frame\r
     dt = clock.tick(60) / 1000\r
 \r
+# cleanly quit the pygame instance\r
 pygame.quit()
\ No newline at end of file