#The Maze : Projet ISN réalisé par Bryan A., Martin C. et Isak V., élèves de TS6.
import sys, os, time, pygame
import tkinter as tk
import time
from tkinter import filedialog
from random import randint
# -------- TKINTER --------
# Fenetre pour les sauvegardes/chargement de carte
root = tk.Tk()
root.withdraw()
# -------- PYGAME --------
# Fenetre pour le jeu et ses menus
pygame.init()
myfont = pygame.font.SysFont("monospace", 50)
creditfont = pygame.font.SysFont("monospace", 40, italic=True)
# -------- § Variables § --------
# Couleurs
BLACK = (0, 0, 0)
GRAY = (150, 150, 150)
WHITE = (255, 255, 255)
# Dossier = "C:/Users/Isak Viste/Documents/Programming/TheMaze/"
# Carte de jeu
mapSize = 100
Map = []
startPos = (0, 0)
# Joueur (position et rotation (statistiques de départ))
x, y = 0, 0
prevRotation = 0
morts = 0
start = 0
end = 0
duree = 0
# Taille et Nom de la fenetre
screen = pygame.display.set_mode((700, 700))
temps = 0
# Textures - Terrain
rawTextures = ["Ground", "Wall", "Wasteland", "Start", "Goal", "Trap", "Decor"]
finTextures = []
imageSize = (0, 0)
# Textures - Pieges et Decors
xTraps = 3
xDecors = 3
trapTextures = []
decorTextures = []
# Texture - Joueur
playerTexture = pygame.image.load(os.path.join("Player.gif")).convert_alpha()
playerTexture = pygame.transform.scale(playerTexture, (100, 100))
playerTextureDead = pygame.image.load(os.path.join("PlayerDead.gif")).convert_alpha()
playerTextureDead = pygame.transform.scale(playerTextureDead, (100, 100))
# Texture - Banners
winBannerTexture = pygame.image.load(os.path.join("WinBanner.jpg")).convert()
tryAgainBannerTexture = pygame.image.load(os.path.join("TryAgainBanner.jpg")).convert()
# Texture - Boutton
butTextures = []
for i in range(6):
texture = pygame.image.load(os.path.join('Button' + str(i) + '.gif')).convert_alpha()
butTextures.append(pygame.transform.scale(texture, (300, 50)))
texture = pygame.image.load(os.path.join('Button' + str(i) + 'i' + '.gif')).convert_alpha()
butTextures.append(pygame.transform.scale(texture, (300, 50)))
level01Button = pygame.image.load(os.path.join("Level01.gif")).convert_alpha()
level01Button = pygame.transform.scale(level01Button, (300, 50))
level01Buttoni = pygame.image.load(os.path.join("Level01i.gif")).convert_alpha()
level01Buttoni = pygame.transform.scale(level01Buttoni, (300, 50))
loadButton = pygame.image.load(os.path.join("Load.gif")).convert_alpha()
loadButton = pygame.transform.scale(loadButton, (300, 50))
loadButtoni = pygame.image.load(os.path.join("Loadi.gif")).convert_alpha()
loadButtoni = pygame.transform.scale(loadButtoni, (300, 50))
# Pygame - Conteur
clock = pygame.time.Clock()
# -------- MENU PRINCIPAL --------
def MainMenu():
# ------ § Variables § ------
global playerTexture
global temps
isInMainMenu = True
while isInMainMenu:
# Nom de la fenetre
if(pygame.display.get_caption() != "The Maze | Main Menu"):
pygame.display.set_caption("The Maze | Main Menu")
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
if (event.type == pygame.QUIT):
isInMainMenu = False
if (event.type == pygame.MOUSEBUTTONUP):
# Position de la souris ([0] = x et [1] = y)
mp = pygame.mouse.get_pos()
if(200 < mp[0] < 500 and 250 < mp[1] < 300):
LevelMenu()
if(200 < mp[0] < 500 and 350 < mp[1] < 400):
if(len(Map) == 0):
BlankWorld()
LevelEditor()
if(200 < mp[0] < 500 and 450 < mp[1] < 500):
InstructionsMenu()
if(200 < mp[0] < 500 and 550 < mp[1] < 600):
isInMainMenu = False
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
Background = pygame.image.load(os.path.join("Background.jpg")).convert_alpha()
Background = pygame.transform.scale(Background, (700, 700))
screen.blit(Background,(0,0))
Title = pygame.image.load(os.path.join("Title.gif")).convert_alpha()
Title = pygame.transform.scale(Title, (700, 135))
screen.blit(Title,(0,75))
# -- DESSINER SUR L'ECRAN --
# Buttons
Button(0, 200, 250, 300, 50)
Button(1, 200, 350, 300, 50)
Button(4, 200, 450, 300, 50)
Button(2, 200, 550, 300, 50)
# Credits
label = myfont.render("Created by Bryan ARTHAUD, Martin CORSON et Isak VISTE", 1, (200,200,67))
if (700 - temps > -label.get_rect().width):
screen.blit(label, (700 - temps, 620))
temps += 10
else:
temps = 0
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
def Button(id, x, y, length, height):
# § Variables §
mouse = pygame.mouse.get_pos()
if(x+length > mouse[0] > x and y+height > mouse[1] > y):
screen.blit(butTextures[id*2+1],(x,y))
else:
screen.blit(butTextures[id*2],(x,y))
# -------- MENU NIVEAUX --------
def LevelMenu():
# ------ § Variables § ------
global playerTexture
global morts
global start
level01 = os.path.join("Mazes/Level01.maze")
isInLevelMenu = True
while isInLevelMenu:
# Nom de la fenetre
if(pygame.display.get_caption() != "The Maze | Level Menu"):
pygame.display.set_caption("The Maze | Level Menu")
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
if (event.type == pygame.QUIT):
isInLevelMenu = False
if (event.type == pygame.MOUSEBUTTONUP):
# Position de la souris ([0] = x et [1] = y)
mp = pygame.mouse.get_pos()
if(200 < mp[0] < 500 and 300 < mp[1] < 350):
if(len(Map) == 0):
BlankWorld()
LoadLevel(level01)
playerTexture = pygame.transform.rotate(playerTexture, 0)
morts = 0
start = pygame.time.get_ticks()
PlayGame()
isInLevelMenu = False
if(200 < mp[0] < 500 and 400 < mp[1] < 450):
if(len(Map) == 0):
BlankWorld()
LoadWorld()
playerTexture = pygame.transform.rotate(playerTexture, 0)
morts = 0
start = pygame.time.get_ticks()
PlayGame()
isInLevelMenu = False
if(200 < mp[0] < 500 and 500 < mp[1] < 550):
isInLevelMenu = False
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
Background = pygame.image.load(os.path.join("Background.jpg")).convert_alpha()
Background = pygame.transform.scale(Background, (700, 700))
screen.blit(Background,(0,0))
Title = pygame.image.load(os.path.join("Title.gif")).convert_alpha()
Title = pygame.transform.scale(Title, (700, 135))
screen.blit(Title,(0,125))
# -- DESSINER SUR L'ECRAN --
# Buttons
mp = pygame.mouse.get_pos()
if(200+300 > mp[0] > 200 and 300+50 > mp[1] > 300):
screen.blit(level01Buttoni, (200,300))
else:
screen.blit(level01Button, (200,300))
if(200+300 > mp[0] > 200 and 400+50 > mp[1] > 400):
screen.blit(loadButtoni, (200,400))
else:
screen.blit(loadButton, (200,400))
Button(2, 200, 500, 300, 50)
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
#Menu d'instructions
def InstructionsMenu():
isInInstructionsMenu = True
page = 1
while isInInstructionsMenu:
# Nom de la fenetre
if(pygame.display.get_caption() != "The Maze | Instructions"):
pygame.display.set_caption("The Maze | Instructions")
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
if (event.type == pygame.QUIT):
isInInstructionsMenu = False
if (event.type == pygame.MOUSEBUTTONUP):
# Position de la souris ([0] = x et [1] = y)
mp = pygame.mouse.get_pos()
if(50 < mp[0] < 350 and 625 < mp[1] < 675):
isInInstructionsMenu = False
#Pour changer de page d'instructions si on clique sur le bouton placé aux coordonnées suivantes.
if(350 < mp[0] < 650 and 625 < mp[1] < 675):
if page == 1:
page = 2
else:
page = 1
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
Background = pygame.image.load(os.path.join("Background.jpg")).convert_alpha()
Background = pygame.transform.scale(Background, (700, 700))
screen.blit(Background,(0,0))
Title = pygame.image.load(os.path.join("Title.gif")).convert_alpha()
Title = pygame.transform.scale(Title, (700, 135))
screen.blit(Title,(0,35))
#Pour afficher une page d'instructions ou l'autre
if page == 2:
ParchemInstructions = pygame.image.load(os.path.join("ParchemInstructions2.gif")).convert_alpha()
ParchemInstructions = pygame.transform.scale(ParchemInstructions, (700, 413))
screen.blit(ParchemInstructions,(0,200))
else:
ParchemInstructions = pygame.image.load(os.path.join("ParchemInstructions1.gif")).convert_alpha()
ParchemInstructions = pygame.transform.scale(ParchemInstructions, (700, 413))
screen.blit(ParchemInstructions,(0,200))
# -- DESSINER SUR L'ECRAN --
# Buttons
Button(2, 50, 625, 300, 50)
Button(5, 350, 625, 300, 50)
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
# -------- GENERATION DE LA CARTE --------
def BlankWorld():
# ------ § Variables § ------
global Map
Map = []
for i in range (mapSize):
Map.append([])
for j in range (mapSize):
Map[i].append(0)
# -------- IMPORTER LES TEXTURES --------
def ImportTextures(imgS):
global imageSize
imageSize = (imgS, imgS)
for val in rawTextures:
ImportImage(finTextures, val, "jpg", imageSize, rawTextures.index(val))
for i in range (xTraps):
ImportImage(trapTextures, "Trap" + str(i), "jpg", imageSize, i)
for i in range (xDecors):
ImportImage(decorTextures, "Decor" + str(i), "jpg", imageSize, i)
# -------- IMPORTER DES IMAGES --------
def ImportImage(liste, image, ext, size, pos):
texture = pygame.image.load(os.path.join(image + '.' + ext)).convert()
try:
liste[pos] = pygame.transform.scale(texture, size)
except:
liste.append(pygame.transform.scale(texture, size))
# -------- JEU PRINCIPAL --------
def PlayGame():
pygame.display.set_caption("The Maze | Play")
# ------ § Variables § ------
global x, y
global prevRotation
global playerTexture
global morts
global imageSize
global start
global duree
global end
x, y = startPos
# Importer des images
ImportTextures(100)
# Diversifier les Pieges
for i in range (mapSize):
for j in range (mapSize):
if (Map[i][j] == 5):
Map[i][j] = 10 + randint(0, xTraps-1)
elif (Map[i][j] == 6):
Map[i][j] = 50 + randint(0, xDecors-1)
timerActive = True
isDead = False
gameOver = False
isGameOver = True
isRunning = True
playerMoved = True
# ------ BOUCLE PRINCIPAL ------
while isRunning:
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
if (event.type == pygame.QUIT):
isRunning = False
if (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_UP and playerMoved == False):
y = MovePlayer(90, 0, -1, y, -1)
playerMoved = True
if (event.key == pygame.K_DOWN and playerMoved == False):
y = MovePlayer(270, 0, 1, y, 1)
playerMoved = True
if (event.key == pygame.K_RIGHT and playerMoved == False):
x = MovePlayer(0, 1, 0, x, 1)
playerMoved = True
if (event.key == pygame.K_LEFT and playerMoved == False):
x = MovePlayer(180, -1, 0, x, -1)
playerMoved = True
# ---- LOGIQUE DU JEU ----
# Si le joueur a bougé
if (playerMoved == True):
# Si le joueur est sur la case de fin
if (Map[x][y] == 4):
gameOver = True
isRunning = False
if (Map[x][y] >= 10 and Map[x][y] < 50):
isDead = True
gameOver = True
isRunning = False
morts += 1
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
# -- DESSINER SUR L'ECRAN --
DrawScreen(imageSize, 3, 4)
screen.blit(playerTexture, (300, 300))
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
playerMoved = False
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
if (gameOver == True):
# ------ BOUCLE PRINCIPAL ------
while isGameOver:
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
if (event.type == pygame.QUIT):
isGameOver = False
if (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_SPACE):
isGameOver = False
if (isDead == False):
morts = 0
start = pygame.time.get_ticks()
PlayGame()
if (event.type == pygame.MOUSEBUTTONUP):
mp = pygame.mouse.get_pos()
if(200 < mp[0] < 500 and 500 < mp[1] < 550):
isGameOver = False
if (isDead == False):
morts = 0
start = pygame.time.get_ticks()
PlayGame()
if(200 < mp[0] < 500 and 600 < mp[1] < 650):
isGameOver = False
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
# -- DESSINER SUR L'ECRAN --
DrawScreen(imageSize, 3, 4)
if (isDead == True):
screen.blit(playerTextureDead, (300, 300))
screen.blit(winBannerTexture, ((700 / 2 - 310, 40)))
label = myfont.render("YOU LOSE", 1, (255, 255, 255))
screen.blit(label, (700 / 2 - label.get_rect().width / 2, 50))
end = pygame.time.get_ticks()
else:
Finishline = pygame.image.load(os.path.join("Finishline.gif")).convert_alpha()
screen.blit(Finishline,(0,0))
screen.blit(winBannerTexture, ((700 / 2 - 310, 40)))
label = myfont.render("YOU WIN", 1, (255,255,255))
screen.blit(label, (700/2-label.get_rect().width/2, 50))
#Pour arrêter le chronomètre si le joueur a fini le niveau
while timerActive:
end = pygame.time.get_ticks()
timerActive = False
duree = int((end - start)/1000)
label = myfont.render("Nombre de Morts : " + str(morts), 1, (255,0,0))
screen.blit(label, (700/2-label.get_rect().width/2, 90))
label = myfont.render("Temps : " + str(duree) + " secondes", 1, (255,0,0))
screen.blit(label, (700/2-label.get_rect().width/2, 130))
screen.blit(tryAgainBannerTexture, ((700/2-170, 484)))
Button(3, 200, 500, 300, 50)
Button(2, 200, 600, 300, 50)
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
# -------- FAIRE BOUGER LE JOUEUR --------
def MovePlayer(rot, tempX, tempY, move, moveDir):
# ------ § Variables § ------
global x, y
global prevRotation
global playerTexture
playerTexture = pygame.transform.rotate(playerTexture, rot-prevRotation)
prevRotation = rot
if (0 <= x+tempX < mapSize and 0 <= y+tempY < mapSize):
if(Map[x+tempX][y+tempY] != 1):
return(move + moveDir)
else:
return(move)
else:
return(move)
# -------- EDITEUR DE CARTE --------
def LevelEditor():
pygame.display.set_caption("The Maze | Level Editor")
# ------ § Variables § ------
global x, y
global startPos
global imageSize
# Importer des images
ImportTextures(50)
# Uniformiser les Pieges
for i in range (mapSize):
for j in range (mapSize):
if (Map[i][j] >= 10 and Map[i][j] < 50):
Map[i][j] = 5
elif (Map[i][j] >= 50 and Map[i][j] < 90):
Map[i][j] = 6
isRunning = True
actionExectued = True
# ------ BOUCLE PRINCIPAL ------
while isRunning:
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
# Coordonee du click
mousePosition = pygame.mouse.get_pos()
pressed = pygame.mouse.get_pressed()
mpx, mpy = int(mousePosition[0]/50), int(mousePosition[1]/50)
if (event.type == pygame.QUIT):
isRunning = False
if (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_UP):
y -= 1
actionExectued = True
if (event.key == pygame.K_DOWN):
y += 1
actionExectued = True
if (event.key == pygame.K_RIGHT):
x += 1
actionExectued = True
if (event.key == pygame.K_LEFT):
x -= 1
actionExectued = True
if (event.key == pygame.K_s):
SaveWorld()
if (event.key == pygame.K_l):
LoadWorld()
actionExecuted = True
if (event.key == pygame.K_n):
BlankWorld()
actionExecuted = True
if (event.key == pygame.K_m):
ShowMap()
ImportTextures(50)
if (event.key == pygame.K_p):
PlayGame()
ImportTextures(50)
# Uniformiser les Pieges
for i in range (mapSize):
for j in range (mapSize):
if (Map[i][j] >= 10 and Map[i][j] < 50):
Map[i][j] = 5
elif (Map[i][j] >= 50 and Map[i][j] < 90):
Map[i][j] = 6
actionExecuted = True
if (event.key == pygame.K_g):
if(startPos != (0, 0)):
Map[startPos[0]][startPos[1]] = 0
Map[x-7+mpx][y-7+mpy] = 3
startPos = (x-7+mpx, y-7+mpy)
if (event.key == pygame.K_h):
Map[x-7+mpx][y-7+mpy] = 4
if (event.type == pygame.MOUSEBUTTONUP):
if(0 <= x-7+mpx < mapSize and 0 <= y-7+mpy < mapSize):
if(event.button == 1):
if(Map[x-7+mpx][y-7+mpy] == 1):
Map[x-7+mpx][y-7+mpy] = 0
else:
Map[x-7+mpx][y-7+mpy] = 1
if(event.button == 3):
if(Map[x-7+mpx][y-7+mpy] == 5):
Map[x-7+mpx][y-7+mpy] = 6
elif(Map[x-7+mpx][y-7+mpy] == 6):
Map[x-7+mpx][y-7+mpy] = 0
else:
Map[x-7+mpx][y-7+mpy] = 5
actionExecuted = True
# ---- LOGIQUE DU JEU ----
# Si une action a ete executer
if (actionExectued == True):
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
DrawScreen(imageSize, 7, 7)
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
actionExecuted = False
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
def ShowMap():
pygame.display.set_caption("The Maze | Map")
# ------ § Variables § ------
global x, y
global imageSize
x = mapSize//2
y = mapSize//2
# Importer des images
ImportTextures(700//mapSize)
isShowingMap = True
# ------ BOUCLE PRINCIPAL ------
while isShowingMap:
# ---- BOUCLE D'EVENEMENT ----
for event in pygame.event.get():
if (event.type == pygame.QUIT):
isShowingMap = False
if (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_m):
isShowingMap = False
# ---- LOGIQUE DU JEU ----
# -- EFFACER L'ECRAN --
# Ne pas mettre de commande pour dessiner au dessus!
screen.fill(BLACK)
DrawScreen(imageSize, mapSize//2, mapSize//2)
# -- METTRE A JOUR LA FENETRE --
pygame.display.flip()
# ---- LIMITER A 60 IMAGES PAR SECONDE ----
clock.tick(60)
# -------- DESSINER LE TERRAIN --------
def DrawScreen(imgS, tempM, tempP):
# ------ § Variables § ------
k = 0
l = 0
for i in range (y-tempM, y+tempP):
for j in range (x-tempM, x+tempP):
if (0 <= i < mapSize and 0 <= j < mapSize):
texture = finTextures[0] #GROUND
if(Map[j][i] == 1):
texture = finTextures[1] #WALL
elif(Map[j][i] == 3):
texture = finTextures[3] #START
elif(Map[j][i] == 4):
texture = finTextures[4] #GOAL
elif(Map[j][i] == 5):
texture = finTextures[5] #TRAP
elif(Map[j][i] == 6):
texture = finTextures[6] #DECOR
# TRAPS
elif(Map[j][i] == 10):
texture = trapTextures[0]
elif(Map[j][i] == 11):
texture = trapTextures[1]
elif(Map[j][i] == 12):
texture = trapTextures[2]
#DECORS
elif(Map[j][i] == 50):
texture = decorTextures[0]
elif(Map[j][i] == 51):
texture = decorTextures[1]
elif(Map[j][i] == 52):
texture = decorTextures[2]
else:
texture = finTextures[2] #WASTELAND
screen.blit(texture, (l*imgS[0], k*imgS[1]))
l += 1
l = 0
k += 1
# -------- SAUVEGARDE DE LA CARTE --------
def SaveWorld():
print("SAVE START")
try:
file_path = filedialog.asksaveasfilename(defaultextension=".maze", filetypes=(("Text Files", "*.maze"),("All Files", "*.*")))
levelText = open(file_path, "w+") #Write and Overwrite
for i in range (mapSize):
for j in range (mapSize):
levelText.write(str(Map[i][j]))
levelText.write("\n")
levelText.close()
print("(Y) SAVE COMPLETE", end="\n\n")
except Exception as e:
print("(N)SAVE FAILURE:\n -->", e, end="\n\n")
pass
# -------- CHARGEMENT DE LA CARTE --------
def LoadWorld():
# ------ § Variables § ------
global startPos
print("LOAD START")
try:
file_path = filedialog.askopenfilename(defaultextension=".maze", filetypes=(("Text Files", "*.maze"),("All Files", "*.*")))
levelText = open(file_path, "r") #Read Only
for i in range(mapSize):
read = levelText.read(mapSize)
for j in range(mapSize):
Map[i][j] = int(read[j])
if(int(read[j]) == 3):
startPos = (i, j)
levelText.read(1)
print("(Y) LOAD COMPLETE", end="\n\n")
except Exception as e:
print("(N) LOAD FAILURE:\n -->", e, end="\n\n")
# -------- CHARGEMENT D'UN LEVEL --------
def LoadLevel(level):
# ------ § Variables § ------
global startPos
print("LEVEL LOAD START")
try:
file_path = level
levelText = open(file_path, "r") #Read Only
for i in range(mapSize):
read = levelText.read(mapSize)
for j in range(mapSize):
Map[i][j] = int(read[j])
if(int(read[j]) == 3):
startPos = (i, j)
levelText.read(1)
print("(Y) LOAD COMPLETE", end="\n\n")
except Exception as e:
print("(N) LOAD FAILURE:\n -->", e, end="\n\n")
MainMenu()
pygame.quit()
Comments
0 B
|👍
/👎