265 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Example file showing a basic pygame "game loop"
 | 
						|
import pygame
 | 
						|
import math
 | 
						|
import csv
 | 
						|
import random
 | 
						|
 | 
						|
# pygame setup
 | 
						|
pygame.init()
 | 
						|
screen = pygame.display.set_mode((1080,720))
 | 
						|
clock = pygame.time.Clock()
 | 
						|
running = True
 | 
						|
dt = 0
 | 
						|
 | 
						|
player_sprite = pygame.Rect(100,100,50,50)
 | 
						|
mur = pygame.Rect(500,100,100,100)
 | 
						|
 | 
						|
class Waypoint:
 | 
						|
    def __init__(self, name: str) -> None:
 | 
						|
        self.name = name
 | 
						|
        match name.capitalize():
 | 
						|
            case "A":
 | 
						|
                self.x = 800
 | 
						|
                self.y = 900
 | 
						|
                self.connection = ("B", "H")
 | 
						|
            case "B":
 | 
						|
                self.x = 1575
 | 
						|
                self.y = 900
 | 
						|
                self.connection = ("A", "E", "C")
 | 
						|
            case "C":
 | 
						|
                self.x = 2500
 | 
						|
                self.y = 900
 | 
						|
                self.connection = ("B", "D")
 | 
						|
            case "D":
 | 
						|
                self.x = 2500
 | 
						|
                self.y = 1600
 | 
						|
                self.connection = ("C", "E", "F")
 | 
						|
            case "E":
 | 
						|
                self.x = 1575
 | 
						|
                self.y = 1600
 | 
						|
                self.connection = ("B", "D", "G")
 | 
						|
            case "F":
 | 
						|
                self.x = 2500
 | 
						|
                self.y = 2200
 | 
						|
                self.connection = ("D", "G")
 | 
						|
            case "G":
 | 
						|
                self.x = 1575
 | 
						|
                self.y = 2200
 | 
						|
                self.connection = ("H", "E", "F")
 | 
						|
            case "H":
 | 
						|
                self.x = 800
 | 
						|
                self.y = 2200
 | 
						|
                self.connection = ("A", "G")
 | 
						|
 | 
						|
    def get_new_connected(self)-> object:
 | 
						|
        letter = random.choice(self.connection)
 | 
						|
        return Waypoint(letter)
 | 
						|
    
 | 
						|
    def get_direction(self, pointA: object, pointB: object)-> str:
 | 
						|
        a = pointA.name
 | 
						|
        b = pointB.name
 | 
						|
        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"):
 | 
						|
            return "north"
 | 
						|
        elif (a == "A" and b == "H") or (a == "E" and b == "G") or (a == "B" and b == "E") or (a == "D" and b == "F") or (a == "C" and b == "D"):
 | 
						|
            return "south"
 | 
						|
        elif (a == "A" and b == "B") or (a == "B" and b == "C") or (a == "E" and b == "D") or (a == "H" and b == "G") or (a == "G" and b == "F"):
 | 
						|
            return "east"
 | 
						|
        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"):
 | 
						|
            return "west"
 | 
						|
        else:
 | 
						|
            raise Exception("crash: POINT A and B impossible")
 | 
						|
                
 | 
						|
class Pnj:
 | 
						|
    def __init__(self, x: int, y: int, sprite_path: str, direction: str, objectif: Waypoint, speed: int) -> None:
 | 
						|
        self.x = x
 | 
						|
        self.y = y
 | 
						|
        self.sprite = pygame.transform.scale_by(pygame.image.load(sprite_path), 3.0)
 | 
						|
        self.direction = direction
 | 
						|
        self.objectif = objectif
 | 
						|
        self.speed = speed
 | 
						|
    
 | 
						|
    def avance(self):
 | 
						|
        '''
 | 
						|
        Vérifie que l'objectif n'est pas atteint et avance le pnj dans la direction
 | 
						|
        '''
 | 
						|
        if self.check_objectif():
 | 
						|
            return
 | 
						|
        else:
 | 
						|
            match self.direction:
 | 
						|
                case "north":
 | 
						|
                    self.y -= self.speed
 | 
						|
                case "south":
 | 
						|
                    self.y += self.speed
 | 
						|
                case "east":
 | 
						|
                    self.x += self.speed
 | 
						|
                case "west":
 | 
						|
                    self.x -= self.speed
 | 
						|
                case _:
 | 
						|
                    pass
 | 
						|
    
 | 
						|
    def check_objectif(self):
 | 
						|
        """
 | 
						|
        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
 | 
						|
        """
 | 
						|
        match self.direction:
 | 
						|
            case "north":
 | 
						|
                if self.y <= self.objectif.y: 
 | 
						|
                    new_objectif = self.objectif.get_new_connected()
 | 
						|
                    self.direction = self.objectif.get_direction(self.objectif, new_objectif)
 | 
						|
                    self.objectif = new_objectif
 | 
						|
                    return True
 | 
						|
            case "south":
 | 
						|
                if self.y >= self.objectif.y: 
 | 
						|
                    new_objectif = self.objectif.get_new_connected()
 | 
						|
                    self.direction = self.objectif.get_direction(self.objectif, new_objectif)
 | 
						|
                    self.objectif = new_objectif
 | 
						|
                    return True
 | 
						|
            case "east":
 | 
						|
                if self.x >= self.objectif.x: 
 | 
						|
                    new_objectif = self.objectif.get_new_connected()
 | 
						|
                    self.direction = self.objectif.get_direction(self.objectif, new_objectif)
 | 
						|
                    self.objectif = new_objectif
 | 
						|
                    return True
 | 
						|
            case "west":
 | 
						|
                if self.x <= self.objectif.x: 
 | 
						|
                    new_objectif = self.objectif.get_new_connected()
 | 
						|
                    self.direction = self.objectif.get_direction(self.objectif, new_objectif)
 | 
						|
                    self.objectif = new_objectif
 | 
						|
                    return True
 | 
						|
        return False
 | 
						|
 | 
						|
class Village:
 | 
						|
    def __init__(self, nb_pnj: int) -> None:
 | 
						|
        self.liste_pnj = []
 | 
						|
        for i in range(nb_pnj):
 | 
						|
            start_waypoint = Waypoint(random.choice(("A", "B", "C", "D", "E", "F", "G", "H")))
 | 
						|
            objective_waypoint = start_waypoint.get_new_connected()
 | 
						|
            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)))
 | 
						|
 | 
						|
    def ajouter_pnj_random(self)-> None:
 | 
						|
        pass
 | 
						|
 | 
						|
    def update_pnj(self)-> None:
 | 
						|
        for p in self.liste_pnj:
 | 
						|
            p.avance()
 | 
						|
 | 
						|
    def get_village_sprites(self)->list:
 | 
						|
        village_sprites = []
 | 
						|
        for p in self.liste_pnj:
 | 
						|
            village_sprites.append((p.x, p.y, p.sprite))
 | 
						|
        return village_sprites
 | 
						|
 | 
						|
class Player:
 | 
						|
    def __init__(self)-> None:
 | 
						|
        self.x = 800
 | 
						|
        self.y = 900
 | 
						|
        self.mov_speed = 8
 | 
						|
        self.rotate_speed = 5
 | 
						|
        self.angle = 90
 | 
						|
 | 
						|
    def rotate(self, angle: math.degrees)-> None:
 | 
						|
        self.angle += angle*self.rotate_speed
 | 
						|
    
 | 
						|
    def move(self, mov: int)-> None:
 | 
						|
        new_x = self.x + self.mov_speed*mov*math.cos(math.radians(self.angle))
 | 
						|
        new_y = self.y + self.mov_speed*mov*math.sin(math.radians(self.angle))
 | 
						|
        if(game.test_collision(pygame.Rect(new_x-50, new_y-50, 100, 100), game.collisions) == False):
 | 
						|
            self.x = new_x
 | 
						|
            self.y = new_y
 | 
						|
        elif(game.test_collision(pygame.Rect(self.x-50, new_y-50, 100, 100), game.collisions) == False):
 | 
						|
            self.y = new_y
 | 
						|
        elif(game.test_collision(pygame.Rect(new_x-50, self.y-50, 100, 100), game.collisions) == False):
 | 
						|
            self.x = new_x
 | 
						|
 | 
						|
class Game:
 | 
						|
    def __init__(self):
 | 
						|
        self.is_paused = False
 | 
						|
        pygame.font.init()
 | 
						|
        self.font = pygame.font.SysFont('Comic Sans MS', 30)
 | 
						|
        self.load_sprites()
 | 
						|
        self.load_collisions()
 | 
						|
    
 | 
						|
    def load_sprites(self):
 | 
						|
        self.perso_sprite = pygame.image.load("assets/perso_sprite.png")
 | 
						|
        self.map_sprite = pygame.image.load("assets/map3.png")
 | 
						|
    
 | 
						|
    def load_collisions(self):
 | 
						|
        self.collisions = []
 | 
						|
        with open('assets/collisions.csv', 'r', newline='') as file:
 | 
						|
            reader = csv.DictReader(file)
 | 
						|
            for row in reader:
 | 
						|
                self.collisions.append(pygame.Rect(float(row["starting_point_x"]), float(row["starting_point_y"]), float(row["len_x"]), float(row["len_y"])))
 | 
						|
 | 
						|
    def test_collision(self, objet: pygame.Rect, l_collisions) -> bool:
 | 
						|
        for col in l_collisions:
 | 
						|
            if objet.colliderect(col):
 | 
						|
                return True
 | 
						|
        return False
 | 
						|
 | 
						|
    def display_debug_text(self):
 | 
						|
        angle_surface = self.font.render("angle: "+str(player.angle), False, (0, 0, 0))
 | 
						|
        x_surface = self.font.render("x: "+str(player.x), False, (0, 0, 0))
 | 
						|
        y_surface = self.font.render("y: "+str(player.y), False, (0, 0, 0))
 | 
						|
        screen.blit(angle_surface, (0,0))
 | 
						|
        screen.blit(x_surface, (0,30))
 | 
						|
        screen.blit(y_surface, (0,60))
 | 
						|
        #pygame.draw.rect(screen, "blue",pygame.Rect(player.x-50, player.y-50, 100, 100))
 | 
						|
 | 
						|
    def check_input(self):
 | 
						|
        keys = pygame.key.get_pressed()
 | 
						|
        if keys[pygame.K_z]:
 | 
						|
            _ = player.move(1)
 | 
						|
        if keys[pygame.K_s]:
 | 
						|
            _ = player.move(-1)
 | 
						|
        if keys[pygame.K_q]:
 | 
						|
            player.rotate(-1)
 | 
						|
        if keys[pygame.K_d]:
 | 
						|
            player.rotate(1)
 | 
						|
    
 | 
						|
    def draw_player(self):
 | 
						|
        #pygame.draw.rect(screen, "red", pygame.Rect(player.x, player.y, 50, 50))
 | 
						|
        img = pygame.transform.rotozoom(self.perso_sprite, -player.angle-90, 0.2)
 | 
						|
        screen.blit(img, (540-img.get_rect().centerx, 360-img.get_rect().centery))
 | 
						|
 | 
						|
    def draw_village(self):
 | 
						|
        for s in village.get_village_sprites():
 | 
						|
            screen.blit(s[2], (540-player.x + s[0] - s[2].get_rect().centerx, 360-player.y + s[1] - s[2].get_rect().centery))
 | 
						|
 | 
						|
    def display_all(self):
 | 
						|
        # fill the screen with a color to wipe away anything from last frame
 | 
						|
        screen.fill("purple")
 | 
						|
        screen.blit(self.map_sprite, (540-player.x, 360-player.y))
 | 
						|
 | 
						|
        self.draw_village()
 | 
						|
        self.draw_player()
 | 
						|
 | 
						|
        # We display it at the end so it's on top of all
 | 
						|
        self.display_debug_text()
 | 
						|
 | 
						|
        # flip() the display to put your work on screen
 | 
						|
        pygame.display.flip()
 | 
						|
 | 
						|
player = Player()
 | 
						|
game = Game()
 | 
						|
#pnj = Pnj(800, 900, "assets/MiniPeasant.png", "south", Waypoint("H"), 3)
 | 
						|
village = Village(20)
 | 
						|
 | 
						|
while running:
 | 
						|
    # poll for events
 | 
						|
    # pygame.QUIT event means the user clicked X to close your window
 | 
						|
    for event in pygame.event.get():
 | 
						|
        if event.type == pygame.QUIT:
 | 
						|
            running = False
 | 
						|
    # make all the pnj move and do their pnj stuff
 | 
						|
    village.update_pnj()
 | 
						|
 | 
						|
    game.check_input()
 | 
						|
    
 | 
						|
    game.display_all()
 | 
						|
 | 
						|
    # limits FPS to 60
 | 
						|
    # dt is delta time in seconds since last frame, used for framerate-
 | 
						|
    # independent physics.
 | 
						|
    dt = clock.tick(60) / 1000
 | 
						|
 | 
						|
pygame.quit() |