class Sprite: """Un objet du monde""" id = None #Un identifiant (si possible unique) qui représente le sprite nom = None #Un nom pour le fun position = None #La position dans l'espace de cet objet modele = None #Le modèle 3D de l'objet fichierModele = None #Le nom du fichier du modèle 3D (utilisé pour la sauvegarde) fichierSymbole = None #Symbole remplaçant le modèle quand on dézoome icone = None #Icone sur la minimap altCarre = None #L'altitude de cet objet rac = None #Ce qui fait que le sprite garde les pieds en bas racine = None #Ce qui fait que le sprite garde la tête en haut zoneSurbrillance = None #Le disque au pied des personnages qui indique s'il est sélectionné ou non iconeAction = None #Une icone qui indique ce que le sprite est en train de faire barreDeVie = None #La barre de vie barreDeVieRacine = None #La barre de vie est proportionnée par rapport à cette racine majTempsOrientation = None #La boucle qui s'assure qu'un sprite est bien orienté (les pieds par terre) majTempsOrientationMax = None #Le temps minimal à attendre entre 2 recalculs de l'orientation du sprite distanceSymbole = None #Distance à partir de laquelle on tranforme l'objet en symbole (ou fait disparaitre l'objet si symbole==None) symbole=None #L'icône qui remplace le modèle quand on dézoome vitesse = None #La vitesse maximale du sprite en unité/s joueur = None #Le joueur qui possède cet objet stock = None #Le sprite est un contenant à ressource contenu = None #Ce qui se trouve dans l'objet taillePoches = None #Les seuils maximaux de ce que peut promener un sprite vie = None #L'état dans lequel se trouve l'objet tempsDeVie = None #Temps depuis lequel ce sprite existe dureeDeVie = None #Temps maximal durant lequel ce sprite existera typeMort = None #La façon dont le sprite est mort bouge = None #Si True, alors l'objet peut bouger (personnage, véhicule, ...) sinon il est statique (arbre, bâtiment, ...) aquatique = None #Si True, alors l'objet peut aller dans l'eau, sinon il est détruit nocturne = None #S'il est nocturne, la nuit ne le tue pas zoneContact = None #Les coordonnées de la zone de contact inertie = None #L'inertie physique de l'objet terminalVelocity = None #L'inertie maximale que l'objet peut atteindre distanceProche = None #La distance à partir de laquelle un point (objet, checkpoint, ...) est considéré comme atteint pileTempsAppliqueGraviteObjetsFixes = None #Les objets fixes (arbre) n'ont la physique que moulinettée une fois de temps en temps pour les garder sur le sol sans bouffer trop de puissance seuilRecalculPhysique = None #La durée à attendre avant de recalculer la physique d'un objet physique angleSolMax = None #L'angle maximal que le sol peut faire pour que ce sprite puisse marcher dessus seuilToucheSol = None #Delta dans lequel on considère qu'on est sur le sol et pas au-dessus constanteGravitationelle = None #force de gravitation de la planète sur cet objet (prends en compte la résistance à l'air et tout ça) blipid = None #L'id du blip sur la carte ai = None #Le point sur le comportement qui contrôle ce sprite (ne pas partager sous risque d'avoir des IA qui font n'importe quoi) inertieSteering = None #Le vecteur inertiel calculé par le steering (IA) masse = None #La masse de l'objet (utilisé pour les calculs d'accélération) vitesseDePillage = None #La vitesse à laquelle un sprite chope des ressources faciliteDePillage = None #Facteur de facilité à choper des ressources sur ce sprite echelle = None #Facteur d'échelle de l'objet en ce moment echelleOriginelle = None #Facteur d'échelle de l'objet lors de sa création == self.echelle à la sortie de __init__ def __init__(self, id, position, fichierDefinition, joueur): """ Fabrique un nouvel objet position : là où l'objet se trouve modele : le nom du fichier 3D à charger planete : la planète de laquelle cet objet dépend """ general.TODO("Ajouter la gestion des boulots") general.TODO("Ajouter la gestion des animations de sprite") general.TODO("Support des objets non ponctuels") general.TODO("Faire dépendre la vitesse du sprite selon l'angle du sol sur lequel il se déplace") if joueur !=None: self.joueur = proxy(joueur) else: self.joueur = None self.id = id self.miseAJourPosition(position) self.modele = None self.tempsDeVie = 0.0 self.inertie = Vec3(0.0,0.0,0.0) self.inertieSteering = Vec3(0.0,0.0,0.0) self.rac = NodePath("racine-sprite") self.rac.reparentTo(general.planete.geoide.racine) self.racine = NodePath("racine-sprite") self.racine.reparentTo(self.rac) #Tourne le modèle pour que sa tête soit en "haut" (Y pointant vers l'extérieur de la planète) self.racine.setP(90) self.racine.setScale(0.01) #On met en temps débile pour forcer un calcul dès le premier ping self.pileTempsAppliqueGraviteObjetsFixes = 1000.0 self.majTempsOrientation = 1000000000 self.majTempsOrientationMax = 0.1 self.contenu={} self.taillePoches={} self.fichierDefinition = fichierDefinition #Charge les propriétés de l'objet depuis le fichier de définition du sprite if fichierDefinition!=None: definition = general.configuration.parseSprite(fichierDefinition) self.definition = definition self.fichierModele = definition["modele"] self.fichierSymbole = definition["symbole"] self.icone = definition["icone"] self.vie=definition["vie"] self.nocturne = definition["nocturne"] self.terminalVelocity = definition["terminalvelocity"] self.angleSolMax = general.configuration.getConfiguration("ai", "navigation", "angleSolMax", "70.0", float) self.distanceProche = definition["distanceProche"] self.seuilToucheSol = definition["seuilToucheSol"] self.constanteGravitationelle = definition["constanteGravitationelle"] self.vitesse = definition["vitesse"] self.distanceSymbole = definition["distancesymbole"] self.bouge = definition["bouge"] self.aquatique = definition["aquatique"] self.seuilRecalculPhysique = definition["seuilrecalculphysique"] self.masse = definition["masse"] self.echelle = definition["echelle"] self.echelleOriginelle = definition["echelle"] self.contenu["nourriture"] = definition["nourr"] self.contenu["construction"] = definition["constr"] self.stock = definition["stock"] self.taillePoches["nourriture"] = 50.0 self.taillePoches["construction"] = 30.0 self.vitesseDePillage = definition["vitesseDePillage"] self.faciliteDePillage = definition["faciliteDePillage"] self.dureeDeVie = definition["dureeDeVie"] #Si un sprite ne bouge pas, alors il n'a pas besoin d'AI (mais un sprite immobile (tour de guet) peut en avoir besoin, dans ce cas faire bouge=True, vitesse = 0.0) if definition["ai"] != "none" and self.bouge: self.ai = AI(self) #Charge un comportement tout fait self.ai.choisitComportement(definition["ai"]) def stop(self): """Stoppe toutes les activités du sprite""" if self.ai: self.ai.stop() @general.chrono def pointeRacineSol(self): """Tourne la racine des éléments graphiques pour maintenir les "pieds" du sprite par terre""" #Positionne le modèle et le fait pointer vers le centre de la planète (Z pointant sur la planète) self.rac.setPos(*self.position) self.rac.lookAt(general.planete.geoide.racine,0,0,0) @general.chrono def pingSprite(self, temps): """ Appelé à chaque image, met à jour l'état de l'objet temps : le nombre de secondes depuis la dernière mise à jour """ #On se casse pas la tête si le sprite est mort if self.vie<=0: return False #On vieillit le sprite self.tempsDeVie += temps if self.dureeDeVie < self.tempsDeVie and self.dureeDeVie > 0: self.tue("vieillesse", silence=False) return #On charge le modèle 3D si le sprite n'en a pas if self.modele==None: self.fabriqueModel() #On détruit le sprite si on a pas réussit à charger un modèle if self.modele==None: self.tue("Impossible de charger le modele") #Fait tomber self.appliqueGravite(temps) #On mouline l'AI if self.ai != None: self.ai.pingAI(temps) #Deplace self.appliqueInertie(temps) #On met à jour l'orientation du sprite self.majTempsOrientation+=temps if self.majTempsOrientation>self.majTempsOrientationMax: #Recalcule la verticale du modèle self.MAJSymbole() self.blip() self.majTempsOrientation = 0.0 return True @general.chrono def majEchelle(self): """Recalcul le facteur d'échelle du sprite suivant son contenu""" facteur = 0.0 #On regarde le %age de ressources restantes dans les poches du sprite for clef in self.contenu.keys(): if self.taillePoches[clef]!=0.0: facteur = facteur + (self.contenu[clef]/self.taillePoches[clef]) if facteur == 0.0: self.tue("Ressources épuisées") #Racine vaut none si l'objet a été détruit if self.racine==None or self.vie<=0: return #On change l'échelle self.echelle = self.echelleOriginelle*facteur self.modele.setScale(self.echelle) def piller(self, sprite, temps): """Prends des ressources dans les poches de 'sprite' pour les mettre dans les siennes""" #On regarde si on a atteint la cible à pic poquetter if (self.position - sprite.position).length()<=self.distanceProche: miam = {} peutContinuer=False print "Pillage :" for type in sprite.contenu.keys(): stop=False #Le temps passer * la vitesse de récupération * le facteur de facilité de récupérage donne le volume récupéré pour le moment miam[type] = self.vitesseDePillage*sprite.faciliteDePillage*temps if sprite.contenu[type]<miam[type]: miam[type] = sprite.contenu[type] stop=True if self.taillePoches[type]<miam[type]+self.contenu[type]: miam[type] = self.taillePoches[type]-self.contenu[type] stop=True #Si on a pas totalement pillé tous les types de ressource, on continue à piller if not stop: peutContinuer=True sprite.contenu[type]-=miam[type] self.contenu[type]+=miam[type] sprite.majEchelle() print "pillé :",miam print "poches :",self.contenu print "restantes :",sprite.contenu if peutContinuer: return 1 else: return -1 else: return 0 def videPoches(self, sprite, temps): """Dépose ses ressources dans le sprite""" #On regarde si on a atteint la cible à pic poquetter if (self.position - sprite.position).length()<=self.distanceProche: depot = {} peutContinuer=False print "Dépot :" for type in self.contenu.keys(): stop=False #Le temps passer * la vitesse de récupération * le facteur de facilité de récupérage donne le volume récupéré pour le moment depot[type] = self.vitesseDePillage*sprite.faciliteDePillage*temps if self.contenu[type]<depot[type]: depot[type] = self.contenu[type] stop=True if sprite.taillePoches[type]<depot[type]+sprite.contenu[type]: depot[type] = sprite.taillePoches[type]-sprite.contenu[type] stop=True #Si on a pas totalement remplit le stock ou vidé ses poches if not stop: peutContinuer=True self.contenu[type]-=depot[type] sprite.contenu[type]+=depot[type] print "déposée :",depot print "poches :",self.contenu print "contenues :",sprite.contenu if peutContinuer: return 1 else: return -1 else: return 0 @general.chrono def blip(self): """Met à jour le point sur la carte""" if self.blipid!=None: try: #On a un point sur la carte, donc on le met à jour general.interface.menuCourant.miniMap.majBlip(self.blipid,self.position,self.icone,self.joueur.couleur) except AttributeError: self.blipid=None else: try: #On a pas de point sur la carte mais on a une icône, on fabrique un nouveau point if self.icone != None and self.icone != "none": self.blipid = general.interface.menuCourant.miniMap.ajoutePoint3D(self.position,self.icone,self.joueur.couleur) except AttributeError: pass def testeSol(self, temps): """Regarde l'angle entre la normale de la face et le sprite qui s'y tient""" general.TODO("Debugger le teste d'inclinaison de sol") return sp = Vec3(position) sp.normalize() fc = general.planete.geoide.trouveFace(self.position).calculNormale() angle = sp.angleDeg(fc) if angle > self.angleSolMax: self.inertie = Vec3(self.inertie[0]+fc.getX()*temps, self.inertie[1]+fc.getY()*temps, self.inertie[2]+fc.getZ()*temps) def appliqueGravite(self, temps): """Fait tomber les objets sur le sol""" general.TODO("Debugger la gestion de la gravité") return altitudeCible = general.planete.geoide.altitudeCarre(self.position) if abs(self.altCarre-altitudeCible)>0.001: if self.altCarre<altitudeCible or not self.bouge or True: print self.id, self.altCarre, altitudeCible,"(",abs(self.altCarre-altitudeCible),")","->", sp = Vec3(self.position) sp.normalize() self.miseAJourPosition(sp * math.sqrt(altitudeCible)) print self.altCarre, altitudeCible else: print self.id, self.altCarre, altitudeCible,"(",abs(self.altCarre-altitudeCible),")","-> VV", sp = Vec3(self.position) sp.normalize() haut = sp * (-self.constanteGravitationelle) alt = math.sqrt(self.altCarre) altci = math.sqrt(altitudeCible) if haut.length()>alt-altci: haut = Vec3(0.0,0.0,0.0) self.inertie+=haut print self.position, haut return self.testeSol(temps) #On est sur le sol, on teste si on peut se tenir debout dessus def appliqueGraviteObjetsFixes(self, temps): """Place les objets qui ne bougent pas sur le sol""" self.pileTempsAppliqueGraviteObjetsFixes+=temps if self.pileTempsAppliqueGraviteObjetsFixes<self.seuilRecalculPhysique+random.random(): return self.pileTempsAppliqueGraviteObjetsFixes = 0.0 altitudeCible = general.planete.geoide.altitudeCarre(self.position) if self.altCarre < altitudeCible or self.altCarre > altitudeCible + self.seuilToucheSol: #On place l'objet sur le sol d'un seul coup sp = Vec3(self.position) sp.normalize() self.miseAJourPosition(sp * math.sqrt(altitudeCible)) self.inertie = Vec3(0.0,0.0,0.0) def appliqueInertie(self, temps): """Déplace l'objet selon le vecteur inertiel""" if self.inertie.lengthSquared()>self.terminalVelocity*self.terminalVelocity: self.inertie.normalize() self.inertie = self.inertie * self.terminalVelocity self.regardeVers(self.position+(self.inertie*temps+self.inertieSteering)*2) self.miseAJourPosition(self.position+self.inertie*temps+self.inertieSteering) self.inertieSteering = Vec3(0.0,0.0,0.0) self.inertie=self.inertie*0.7 def versCoord(self, cible): """Si cible est une coordonnée, retourne cette dernière, sinon extrait les coordonnées""" try: cible = list(cible) except TypeError: cible=[cible, ] if len(cible)==1: cible = general.planete.geoide.sommets[cible[0]] return cible def deplace(self, cible, temps): """ Déplace un personnage entre 2 points """ cible = self.versCoord(cible) sp = cible - self.position sp.normalize() vecteurDeplacement = sp * self.vitesse*temps self.position = (self.position[0] + vecteurDeplacement[0], self.position[1] + vecteurDeplacement[1], self.position[2] + vecteurDeplacement[2]) self.miseAJourPosition(self.position) def miseAJourPosition(self, position): """Change la position de l'objet""" self.position = position self.altCarre = self.position.lengthSquared() if self.altCarre < general.planete.geoide.niveauEau*general.planete.geoide.niveauEau: if self.aquatique: #Nage pass else: #Se noie self.tue("noyade") if self.modele != None: self.pointeRacineSol() pass def tue(self, type, silence=False): """Gère la mort du sprite""" general.TODO("Gestion des types de destructions de sprite : fin de partie, joueur a perdu, noyade, incendie, ...") general.TODO("Ajouter les ruines et les cadavres") self.stop() if not silence: general.interface.afficheTexte("%(a)s est mort par %(b)s", parametres={"a": general.i18n.utf8ise(self.id), "b": general.i18n.utf8ise(type)}, type="mort") self.vie = 0 self.typeMort = type if self.rac!=None: self.rac.detachNode() self.rac.removeNode() self.rac = None if self.racine!=None: self.racine.detachNode() self.racine.removeNode() self.racine = None if self.modele!=None: self.modele.detachNode() self.modele.removeNode() self.modele = None self.symbole = None if self.blipid!=None: if general.interface.menuCourant!=None: if general.interface.menuCourant.miniMap!=None: general.interface.menuCourant.miniMap.enlevePoint(self.blipid) if self.ai != None: self.ai.clear() self.ai = None while self in general.planete.spritesNonJoueur: general.planete.spritesNonJoueur.remove(self) while self in general.planete.spritesJoueur: general.planete.spritesJoueur.remove(self) while self in general.io.selection: general.io.selection.remove(self) def sauvegarde(self): """Retoune une chaine qui représente l'objet""" nom = "none" if self.joueur != None: nom = self.joueur.nom out = "sprite:"+self.id+":"+nom+":"+self.fichierModele+":"+self.fichierSymbole out += ":"+str(self.position)+":"+str(self.vitesse)+":"+str(self.vie)+":"+str(self.bouge)+":"+str(self.aquatique)+":"+str(self.dureeDeVie)+":"+str(self.tempsDeVie)+":"+str(self.fichierDefinition)+":\r\n" if self.ai != None: out += self.ai.sauvegarde() if self.contenu != None: for element in self.contenu.keys(): out += "sprite-contenu:"+self.id+":"+element+":"+str(self.contenu[element])+":\r\n" return out def __repr__(self): """""" nom = "none" if self.joueur != None: nom = self.joueur.nom return "sprite:"+self.id+":"+nom+":"+self.fichierModele+":"+self.fichierSymbole+":"+str(self.position)+":"+str(self.vitesse)+":"+str(self.vie)+":"+str(self.bouge)+":"+str(self.aquatique) def _syncCheck(self): return self.sauvegarde() def regardeVers(self, cible): h,p,r = self.modele.getHpr() self.modele.lookAt(*self.versCoord(cible)) h=self.modele.getH() self.modele.setHpr(h,p,r) def marcheVers(self, cible): """Calcule la trajectoire pour aller du point actuel à la cible""" #Si y a pas d'ai, on a pas besoin de perdre son temps avec ^^ if self.ai==None: return self.ai.comportement.calculChemin(self.position, cible, 0.75) def suitChemin(self, chemin, fin): """Suit un chemin""" #Si y a pas d'ai, on a pas besoin de perdre son temps avec ^^ if self.ai==None: return self.ai.comportement.suitChemin(chemin, fin, 0.75) def fabriqueModel(self): """Produit le modèle ou le sprite""" if self.vie <=0: return None self.modele = NodePath(FadeLODNode('lod')) if self.fichierModele == None or self.fichierModele=="none": self.modele = None return fichierCarte = self.fichierModele[:-4]+"-card.txt" if os.path.exists(fichierCarte): general.TODO("Charger les images "+self.fichierModele[:-4]+"-1.png... pour faire un lod") if self.fichierModele.endswith(".png"): tmp = self.fabriqueSprite(self.fichierModele) else: tmp = loader.loadModel(self.fichierModele) if self.joueur!=None: self.ajouteZoneSurbrillance().reparentTo(self.racine) self.zoneSurbrillance.setScale(self.echelle) self.ajouteBarreVie().reparentTo(self.racine) self.barreDeVie.setScale(self.echelle) if self.ai: self.ajouteIcone().reparentTo(self.racine) self.iconeAction.setScale(self.echelle) tmp.reparentTo(self.modele) self.modele.setScale(self.echelle) self.modele.node().addSwitch(self.distanceSymbole, 0) symbole = self.fabriqueSymbole(self.fichierSymbole) symbole.reparentTo(self.modele) self.modele.node().addSwitch(9999999, self.distanceSymbole) self.modele.setPythonTag("type","sprite") self.modele.setPythonTag("id",self.id) self.modele.setPythonTag("instance",self) self.modele.reparentTo(self.racine) #Tourne le modèle pour que sa tête soit en "haut" (Y pointant vers l'extérieur de la planète) self.racine.setP(90) self.racine.setScale(0.01) self.pointeRacineSol() return self.modele def ajouteIcone(self): cardMaker = CardMaker('icone') cardMaker.setFrame(-0.2, 0.2, 0.0, 0.4) cardMaker.setHasNormals(True) #Construit une carte (un plan) racine = NodePath("icone") self.iconeAction = racine.attachNewNode(cardMaker.generate()) self.iconeAction.setTexture(loader.loadTexture("./theme/icones/quote.png")) self.iconeAction.hide() self.iconeAction.setBillboardAxis() self.iconeAction.setPos(0.0, 0.0, 1.6) self.iconeAction.setTransparency(TransparencyAttrib.MDual) return self.iconeAction def ajouteBarreVie(self): cardMaker = CardMaker('barreDeVie') cardMaker.setFrame(-0.5, 0.5, 0.0, 0.1) cardMaker.setHasNormals(True) #Construit une carte (un plan) self.barreDeVieRacine = NodePath("barreDeVie") self.barreDeVie = self.barreDeVieRacine.attachNewNode(cardMaker.generate()) self.barreDeVie.setTexture(loader.loadTexture("./theme/progress-top.png")) self.barreDeVie.hide() self.barreDeVie.setBillboardAxis() self.barreDeVie.setPos(0.0, 0.0, 1.0) self.barreDeVie.setTransparency(TransparencyAttrib.MDual) return self.barreDeVie def ajouteZoneSurbrillance(self): cardMaker = CardMaker('surbrillance') cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) cardMaker.setHasNormals(True) #Construit une carte (un plan) racine = NodePath("surbrillance") self.zoneSurbrillance = racine.attachNewNode(cardMaker.generate()) self.zoneSurbrillance.setTexture(loader.loadTexture("./data/textures/soleil.png")) self.zoneSurbrillance.hide() if self.joueur!=None: self.zoneSurbrillance.setColor(*self.joueur.couleur) self.zoneSurbrillance.setP(-90) self.zoneSurbrillance.setTwoSided(True) self.zoneSurbrillance.setTransparency(TransparencyAttrib.MDual) return self.zoneSurbrillance def fabriqueSymbole(self, fichierSymbole): """Affiche une icône dont la taille ne change pas avec la distance à la caméra""" if fichierSymbole=="none": self.symbole=NodePath("pas de symbole") return self.symbole #On calcule la distance à la caméra pour avoir le facteur de corection d'échelle if base.camera != None: taille = base.camera.getPos(self.modele).length() else: taille = 1.0 #On construit l'objet self.symbole = self.fabriqueSprite(fichierSprite = fichierSymbole, taille = taille) #On lui dit de ne pas être dérangé par les sources lumineuses self.symbole.setLightOff() #Permet de l'afficher devant toute géométrie #self.symbole.setBin('fixed', -1) #self.symbole.setDepthTest(False) #self.symbole.setDepthWrite(False) return self.symbole def MAJSymbole(self): """Change l'échelle du symbole pour le garder toujours à la même taille""" if self.symbole!=None and self.racine!=None and self.echelle!=0: #On calcule la distance à la caméra pour avoir le facteur de corection d'échelle taille = general.io.camera.getPos(self.racine).length() #On change l'échelle self.symbole.setScale(taille*0.005, taille*0.005, taille*0.005) def makeDot(self): """Dessine un carré 2D en utilisant directement la puissance de la carte graphique""" gvf = GeomVertexFormat.getV3cp() # Create the vetex data container. vertexData = GeomVertexData('SpriteVertices',gvf,Geom.UHStatic) # Create writers vtxWriter = GeomVertexWriter(vertexData,'vertex') clrWriter = GeomVertexWriter(vertexData,'color') vtxWriter.addData3f(0.0,0.0,0.0) clrWriter.addData3f(1,1,1) # Create a GeomPrimitive object and fill with the vertices. geom = Geom(vertexData) points = GeomPoints(Geom.UHStatic) points.setIndexType(Geom.NTUint32) points.addVertex(0) points.closePrimitive() geom.addPrimitive(points) geomNode = GeomNode('Sprites') geomNode.addGeom(geom) cloud = NodePath(geomNode) cloud.setRenderModePerspective(True) #cloud.setRenderModeThickness(1.0) TS = TextureStage.getDefault() cloud.setTexGen(TS, TexGenAttrib.MPointSprite) #cloud.setTexScale(TS,-1,1) return cloud def fabriqueSprite(self, fichierSprite, taille=1.0, type="carte"): """Construit un nouveau sprite""" racine = NodePath("sprite") if type=="carte": #Fabrique un carré cardMaker = CardMaker('sprite') cardMaker.setFrame(-0.5, 0.5, 0.0, 1.0) cardMaker.setHasNormals(True) #Construit une carte (un plan) card1 = racine.attachNewNode(cardMaker.generate()) #On fait tourner la carte pour quelle pointe toujours vers la caméra #Elle rotationne autour d'un axe uniquement (garde ses pieds vers le sol) card1.setBillboardAxis() elif type=="point": card1 = self.makeDot() card1.reparentTo(racine) else: print "SPRITE :: Erreur :: type de carte inconnu :", type return self.fabriqueSprite(fichierSprite=fichierSprite, taille=1.0, type="carte") tex = loader.loadTexture(fichierSprite) card1.setTexture(tex) #Active la transprence card1.setTransparency(TransparencyAttrib.MDual) #Fait une mise à l'échelle card1.setScale(taille, taille, taille) #Les lignes suivantes font dessiner le sprite au dessus de tout le reste #Utile pour débugger #card1.setBin('fixed', -1) #card1.setDepthTest(False) #card1.setDepthWrite(False) return racine def dessineLigne(self, couleur, depart, arrivee): """Dessine une ligne de depart vers arrivée et ne fait pas de doublons""" ls = LineSegs() ls.setColor(*couleur) ls.setThickness(1.0) ls.moveTo(*depart) ls.drawTo(*arrivee) return ls.create() def selectionne(self): #Le sprite est selectionné, afficher sa barre de vie if self.zoneSurbrillance: self.zoneSurbrillance.show() if self.barreDeVie: self.barreDeVie.show() #Donne la taille de la barre de bie self.barreDeVie.setScale(float(self.vie)/100, 1.0, 1.0) if self.vie>50: self.barreDeVie.setColor(0.0,1.0,0.0,0.75) else: self.barreDeVie.setColor(1.0,0.0,0.0,0.75) if self.iconeAction: self.iconeAction.setTexture(loader.loadTexture(self.ai.iconeAction)) self.iconeAction.show() def deselectionne(self): if self.zoneSurbrillance: self.zoneSurbrillance.hide() if self.barreDeVie: self.barreDeVie.hide() if self.iconeAction: self.iconeAction.hide()