From 78f015a0826f3693cc9d6a33b24a9538b1b66e97 Mon Sep 17 00:00:00 2001 From: "theo@manjaro" Date: Fri, 2 Jul 2021 11:10:45 +0200 Subject: [PATCH] Import des collisions depuis un fichier de map --- gamedata/definitions.py | 2 +- gamedata/game.py | 49 +++- gamedata/maps/TulipFields/base.png | Bin 0 -> 4067 bytes gamedata/maps/TulipFields/map.json | 371 +++++++++++++++++++++++++++++ gamedata/objects/combat/player.py | 16 +- gamedata/objects/combat/tileset.py | 52 ++-- gamedata/scenes.py | 3 +- 7 files changed, 456 insertions(+), 37 deletions(-) create mode 100644 gamedata/maps/TulipFields/base.png create mode 100644 gamedata/maps/TulipFields/map.json diff --git a/gamedata/definitions.py b/gamedata/definitions.py index fa211d4..6b9be05 100644 --- a/gamedata/definitions.py +++ b/gamedata/definitions.py @@ -1,5 +1,5 @@ from random import * -import sys,os,math,shutil,traceback +import sys,os,math,shutil,json def ex_sql(db_name,request,replace=""): conn = sqlite3.connect(db_name) diff --git a/gamedata/game.py b/gamedata/game.py index 7334bef..c19fafe 100644 --- a/gamedata/game.py +++ b/gamedata/game.py @@ -19,6 +19,8 @@ class Game(): self.fontfilesmall = pygame.font.Font(font,18) self.fontfilebig = pygame.font.Font(font,60) + self.logs = [] + self.running = True self.init_inputs() self.gameloop = gameloop.GameLoop() # Je crée une boucle de jeu @@ -26,6 +28,37 @@ class Game(): pygame.display.set_icon(self.sprite_lib["icon.png"]) self.sound_lib = self.init_assets("gamedata/sounds/",pygame.mixer.Sound) # Pareil, mais pour les musiques / sons + # Chargement des niveaux + def loadlvldata(mapfolder): + mapdico = {} + mapdico["name"] = mapfolder.split(os.sep)[-1] + mapdico["cover"] = None + mapdico["data"] = None + mapdico["tilesets"] = {} + scanner = os.scandir(path=mapfolder) + for i in scanner: # Je check tout les fichiers du dossier + name = i.name + try: + if name.endswith(".png"): + if name=="cover.png": + mapdico["cover"] = pygame.image.load(i.path) + else: + mapdico["tilesets"][i.name] = pygame.image.load(i.path) + except: + self.log("Erreur",mapfolder,name,"Fichier invalide") + if name=="map.json": + try: + with open(i.path,"r") as jsonfile: + mapdico["data"] = lib.json.loads(jsonfile.read()) + except: + self.log("Erreur",mapfolder,name) + if mapdico["data"]: + return mapdico + return None + + self.levels_lib = self.init_assets("gamedata/maps/",loadlvldata,recursive=False) # Je charge le dossier de maps + + self.sound_volumes = {} for i in self.sound_lib.keys(): self.sound_volumes[i] = 1 @@ -57,6 +90,10 @@ class Game(): def set_camera(self,posx,posy): self.globals["camerax"], self.globals["cameray"] = posx,posy + def log(*args): + args[0].logs.append(" ".join(args[1:])) + print(" ".join(args[1:])) + def reinit_volumes(self): for i in self.sound_lib.keys(): # J'applique de base les volumes @@ -169,23 +206,23 @@ class Game(): else: self.inputs["mouse"]["click"] = 0 - def init_assets(self,path,function): + def init_assets(self,path,function,recursive=True): dico = {} - self.scan_dir(path,path,dico,function) + self.scan_dir(path,path,dico,function,recursive) return dico - def scan_dir(self,dirpath,origin,dico,function): + def scan_dir(self,dirpath,origin,dico,function,recursive=True): scanner = os.scandir(path=dirpath) for i in scanner: # Je passe à travers toutes les données d'un dossier, fichiers et sous dossiers compris # i.path est le chemin du fichier, par exemple # Si c'est une image, je l'importe et l'ajoute à la librairie finalpath = i.path.replace("\\","/") - if i.is_file(): + if i.is_file() or not recursive: finalpath = finalpath.replace(origin,'') # J'enleve l'origine (dans ce cas 'assets/' car c'est redontant, tout les sprites sont dedans dico[finalpath] = function(i.path) # Si c'est un dossier, je répete l'opération mais à l'intérieur de celui ci - if i.is_dir(): - self.scan_dir(i.path,origin,dico,function) + if i.is_dir() and recursive: + self.scan_dir(i.path,origin,dico,function,recursive) scanner.close() def getSpriteDir(self,directory,ext=".png",assetdir="sprite_lib"): diff --git a/gamedata/maps/TulipFields/base.png b/gamedata/maps/TulipFields/base.png new file mode 100644 index 0000000000000000000000000000000000000000..c4aef788b3139f70f1b241908a3199947c792652 GIT binary patch literal 4067 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: - result.append(self.game.pygame.Rect([x*self.tilew,y*self.tileh,self.tilew,self.tileh])) - return result - def move(self,movex,movey): hstoped = False hor = int(movex+self.hrest) diff --git a/gamedata/objects/combat/tileset.py b/gamedata/objects/combat/tileset.py index 09c6d02..e9ca229 100644 --- a/gamedata/objects/combat/tileset.py +++ b/gamedata/objects/combat/tileset.py @@ -2,30 +2,50 @@ from gamedata.objects.base import BaseObject class TilesetRenderer(BaseObject): - def __init__(self,x,y,game): + def __init__(self,x,y,game,mapfoldername): super().__init__(x,y,game) self.tilew = 64 self.tileh = 64 - self.solid = game.sprite_lib["solid.png"] - self.empty = game.sprite_lib["empty.png"] + self.level = game.levels_lib[mapfoldername] + self.reinit_rects(self.level) - self.collisiongrid = [ - [0,0,0,0,0,0,0], - [1,0,0,0,1,0,0], - [1,1,0,0,0,0,0], - [1,1,0,0,0,0,0], - [1,1,0,1,0,1,1], - [1,1,0,1,1,1,0], - ] def draw(self): + for i in self.rects: + self.game.pygame.draw.rect(self.game.window,[255,0,0],(i[0:4])) - for y in range(len(self.collisiongrid)): - for x in range(len(self.collisiongrid[y])): + def reinit_rects(self,level): + json = level["data"] + name = level["name"] + self.rects = [] + if "layers" in json.keys(): + solidlayer = False + for layer in json["layers"]: + try: + if layer["name"] == "Solids" and "entities" in layer.keys() : + solidlayer = layer + break + except: + self.game.log("Erreur",name,"Les layers sont invalides") + if solidlayer: + if "gridCellWidth" in solidlayer.keys() and "gridCellHeight" in solidlayer.keys(): + self.solidtilew = solidlayer["gridCellWidth"] + self.solidtileh = solidlayer["gridCellHeight"] + else: + self.solidtilew,self.solidtileh = 32,32 + self.game.log("Erreur",name,"Pas de taille de tiles précisée, défaut à 32x32") + for entity in solidlayer["entities"]: + try: + x,y = entity["x"],entity["y"] + w,h = entity["width"],entity["height"] + self.rects.append(self.game.pygame.Rect(x,y,w,h)) + except: + self.game.log("Erreur",name,"Propriétés invalides") + else: + self.game.log("Erreur",name,"Il manque les collisions, Entity Layer nommé Solids") - data = self.collisiongrid[y][x] - sprites = [self.empty,self.solid] - self.game.window.blit(sprites[data],(self.rect[0]+x*self.tilew,self.rect[1]+y*self.tileh)) + else: + self.game.log("Erreur",name,"Pas de layers") diff --git a/gamedata/scenes.py b/gamedata/scenes.py index ed8dbe5..1a764d8 100644 --- a/gamedata/scenes.py +++ b/gamedata/scenes.py @@ -16,7 +16,8 @@ def main(game): def fight(game): game.gameloop.reinit() - tileset = TilesetRenderer(0,0,game) + mapname = game.lib.choice(list(game.levels_lib.keys())) + tileset = TilesetRenderer(0,0,game,mapname) game.gameloop.summon(tileset) p1 = Player(70,50,game) game.gameloop.summon(p1)