Skip to content

Instantly share code, notes, and snippets.

@bilhox
Last active August 12, 2023 18:37
Show Gist options
  • Save bilhox/d9a781e56c8986e8aed54d9fb3504b1f to your computer and use it in GitHub Desktop.
Save bilhox/d9a781e56c8986e8aed54d9fb3504b1f to your computer and use it in GitHub Desktop.
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