Last active
August 12, 2023 18:37
-
-
Save bilhox/d9a781e56c8986e8aed54d9fb3504b1f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import pygame | |
def collide(rects : list[pygame.Rect] , rect : pygame.Rect) -> list[pygame.Rect]: | |
""" | |
Cette fonction sert à lister les rectangles qui touche la hitbox du joueur | |
""" | |
collided = [] | |
for collider in rects: | |
if collider.colliderect(rect): | |
collided.append(collider) | |
return collided | |
def collisions(rects : list[pygame.Rect] , rect : pygame.Rect , movement : list[float , float]) -> None: | |
""" | |
Résolution des collisions | |
Nous séparons le mouvement x et y , car cela peut engendrer des problèmes | |
""" | |
rect.x += movement[0] | |
colliders = collide(rects , rect) | |
for collider in colliders: | |
if(movement[0] < 0): | |
rect.left = collider.right | |
elif(movement[0] > 0): | |
rect.right = collider.left | |
rect.y += movement[1] | |
colliders = collide(rects , rect) | |
for collider in colliders: | |
if(movement[1] < 0): | |
rect.top = collider.bottom | |
elif(movement[1] > 0): | |
rect.bottom = collider.top | |
# Définition des variables en lien avec la fenêtre | |
SCREEN_SIZE = [800 , 600] | |
screen = pygame.display.set_mode(SCREEN_SIZE) | |
# Définition des variables en lien avec le système de framerate independance | |
clock = pygame.time.Clock() | |
dt = 0 | |
MAX_FPS = 120 | |
colliders = [] | |
collider_surfaces = [] | |
# Simple programme pour initialiser une simple map , ce n'est pas le plus important | |
# Cependant , il vous faut une liste de collider à la fin (pygame.Rect représente un collider) | |
tilemap = [ | |
[1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 0], | |
[1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 1], | |
[1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1], | |
[1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 1], | |
[0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1], | |
[1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1], | |
[1 , 0 , 1 , 1 , 1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1], | |
[1 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 1], | |
[1 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 1 , 1], | |
[1 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0], | |
[1 , 1 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0], | |
] | |
for y , line in enumerate(tilemap): | |
surf_line = [] | |
for x , column in enumerate(line): | |
cSurf = pygame.Surface([64 , 64]) | |
if column: | |
colliders.append(pygame.Rect([x*64 , y*64],[64 , 64])) | |
cSurf.fill([40,30,215]) | |
else: | |
cSurf.fill([100,130,215]) | |
surf_line.append(cSurf) | |
collider_surfaces.append(surf_line) | |
#Variables en lien avec le player | |
player_rect = pygame.Rect([512 , 192] , [32 , 32]) | |
player_surf = pygame.Surface([32 , 32]) | |
player_surf.fill([255,0,0]) | |
controls = {"left":False,"right":False,"up":False,"down":False} | |
# ---- Camera ---------------------- | |
# Il est plus facile d'utiliser pygame.Vector2 dans notre cas , | |
# car nous pouvons directement aditionner deux vecteurs | |
scroll = pygame.Vector2(0,0) | |
# ---- Extra ----------------------- | |
pygame.font.init() | |
font = pygame.font.Font(None , 20) | |
running = True | |
while running: | |
# 1 - Effacement de ce qu'on a dessiné à la dernière frame | |
screen.fill([100,130,215]) | |
# Calcul du deltatime , ici clock.tick(FPS) renvoie le dt | |
# en milliseconde , j'ai divisé par 1000 pour avoir | |
# le deltatime en seconde | |
dt = clock.tick(MAX_FPS) / 1000 | |
# 2 - Réinitialisation du mouvement du joueur | |
movement = [0,0] | |
# 3 - Gérance des évenements | |
for event in pygame.event.get(): | |
if event.type == pygame.QUIT: | |
running = False | |
elif event.type == pygame.KEYDOWN: | |
if event.key == pygame.K_LEFT: | |
controls["left"] = True | |
elif event.key == pygame.K_RIGHT: | |
controls["right"] = True | |
elif event.key == pygame.K_UP: | |
controls["up"] = True | |
elif event.key == pygame.K_DOWN: | |
controls["down"] = True | |
elif event.type == pygame.KEYUP: | |
if event.key == pygame.K_LEFT: | |
controls["left"] = False | |
elif event.key == pygame.K_RIGHT: | |
controls["right"] = False | |
elif event.key == pygame.K_UP: | |
controls["up"] = False | |
elif event.key == pygame.K_DOWN: | |
controls["down"] = False | |
# 4 - player mouvements | |
if(controls["left"]): | |
movement[0] -= round(2 * dt * MAX_FPS) | |
elif(controls["right"]): | |
movement[0] += round(2 * dt * MAX_FPS) | |
elif(controls["up"]): | |
movement[1] -= round(2 * dt * MAX_FPS) | |
elif(controls["down"]): | |
movement[1] += round(2 * dt * MAX_FPS) | |
# 5 - résolution des collisions | |
collisions(colliders , player_rect , movement) | |
# caméra offset (player centré au milieu de l'écran) | |
scroll.x = player_rect.x - (SCREEN_SIZE[0] / 2) | |
scroll.y = player_rect.y - (SCREEN_SIZE[1] / 2) | |
# 6 - Affichage des éléments | |
for y , line in enumerate(collider_surfaces): | |
for x , surf in enumerate(line): | |
screen.blit(surf , pygame.Vector2(x , y)*64-scroll) | |
screen.blit(player_surf , pygame.Vector2(player_rect.x , player_rect.y)-scroll) | |
screen.blit(font.render(f"FPS : {round(clock.get_fps(),2)}" , True , [255 , 0 , 0]) , [0,0]) | |
# Update de la fenêtre | |
pygame.display.flip() | |
pygame.quit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment