def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.imageNonDim = self.imageDefautNonDim = self.sprites.sprite((0,12), (56, 56)) tailleimage = self.imageNonDim.get_size() self.image = self.imageDefaut = pygame.transform.scale(self.imageNonDim, (tailleimage[0]*2, tailleimage[1]*2)) super(ArmeBoss, self).__init__()
class FusilPompe(Arme) : delai = 700 def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.image = self.imageDefaut = self.sprites.sprite((0,12), (56, 56)) super(FusilPompe, self).__init__() def tirer(self, position, vecteur) : tirs = calculTirs(vecteur) if pygame.time.get_ticks() - self.dernierTir > self.delai : super(FusilPompe, self).tirer(position, vecteur) projectiles = [] for direction in tirs : projectiles.append(ProjectileDroitRouge((position[0]+30*((2*self.angle)/(1+self.angle*self.angle)), position[1]+20+30*((1-self.angle*self.angle)/(1+self.angle*self.angle))), direction)) #cf arme1 return projectiles else : return []
class ArmeSinus(Arme): delai = 500 def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.image = self.imageDefaut = self.sprites.sprite((0, 12), (56, 56)) super(ArmeSinus, self).__init__() def tirer(self, position, vecteur): if pygame.time.get_ticks() - self.dernierTir > self.delai: super(ArmeSinus, self).tirer(position, vecteur) return [ ProjectileSinusVert( (position[0] + 30 * ((2 * self.angle) / (1 + self.angle * self.angle)), position[1] + 20 + 30 * ((1 - self.angle * self.angle) / (1 + self.angle * self.angle))), vecteur) ] #cf arme1 else: return []
class Obstacle1(Obstacle): sprites = Sprites('img/tiles_spritesheet.png') imageVie = sprites.sprite((504, 144), (72, 72)) imageDegats = sprites.sprite((648, 144), (72, 72)) image = imageVie ''' update 2 images différentes selon le niveau de vie ''' def update(self, *args): if self.vie > 5: self.image = self.imageVie else: self.image = self.imageDegats
class ArmeSinus(Arme) : delai = 500 def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.image = self.imageDefaut = self.sprites.sprite((0,12), (56, 56)) super(ArmeSinus, self).__init__() def tirer(self, position, vecteur) : if pygame.time.get_ticks() - self.dernierTir > self.delai : super(ArmeSinus, self).tirer(position, vecteur) return [ProjectileSinusVert((position[0]+30*((2*self.angle)/(1+self.angle*self.angle)), position[1]+20+30*((1-self.angle*self.angle)/(1+self.angle*self.angle))), vecteur)] #cf arme1 else : return []
class Ennemi3(Ennemi): sprites = Sprites('img/p4_spritesheet.png') vie = 20 def __init__(self, position): self.arme = ArmeSinus() super(Ennemi3, self).__init__(position) ''' construireSprites ''' def contruireSprites(self): #images mouvement images = [ [(0, 0), (70, 94)], [(71, 0), (70, 94)], [(142, 0), (70, 94)], [(0, 95), (70, 94)], [(71, 95), (70, 94)], [(142, 95), (70, 94)], [(213, 0), (70, 94)], [(284, 0), (70, 94)], [(213, 95), (70, 94)], [(355, 0), (70, 94)], [(284, 95), (70, 94)], ] self.framesDroites = self.sprites.sprites(images) self.framesGauches = self.sprites.sprites(images, flipX=True) self.image = self.imageRepos = self.sprites.sprite((0, 190), (66, 92)) self.imageAccroupi = [ self.sprites.sprite((355, 95), (67, 72)), self.sprites.sprite((355, 95), (67, 72), flipX=True) ]
class Ennemi2(Ennemi): sprites = Sprites('img/p3_spritesheet.png') vie = 20 def __init__(self, position): self.arme = Arme1() super(Ennemi2, self).__init__(position) ''' construireSprites ''' def contruireSprites(self): #images mouvement images = [ [(0, 0), (72, 97)], [(73, 0), (72, 97)], [(146, 0), (72, 97)], [(0, 98), (72, 97)], [(73, 98), (72, 97)], [(146, 98), (72, 97)], [(219, 0), (72, 97)], [(292, 0), (72, 97)], [(219, 98), (72, 97)], [(365, 0), (72, 97)], [(292, 98), (72, 97)], ] self.framesDroites = self.sprites.sprites(images) self.framesGauches = self.sprites.sprites(images, flipX=True) self.image = self.imageRepos = self.sprites.sprite((0, 196), (66, 92)) self.imageAccroupi = [ self.sprites.sprite((365, 98), (69, 71)), self.sprites.sprite((365, 98), (69, 71), flipX=True) ]
class Mur(Entite): plateforme = False ''' __init__ Découpe de l'image ''' def __init__(self, position, image, rect) : self.sprites = Sprites(image) self.image = self.sprites.sprite(rect = rect) super(Mur, self).__init__(position) ''' blessure Un mur ne peut pas mourir ''' def blessure(self) : return 1
class Arme1(Arme) : delai = 1000 def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.image = self.imageDefaut = self.sprites.sprite((0,12), (56, 56)) super(Arme1, self).__init__() def tirer(self, position, vecteur) : if pygame.time.get_ticks() - self.dernierTir > self.delai : super(Arme1, self).tirer(position, vecteur) ''' On retourne un ou des projectiles Le tuple position est modifie afin de parametrer un cercle de rayon r=30px selon l'angle car on a besoin de faire sortir le projectile du canon de l'arme et non de la positionMain. Comme l'arme effectue une rotation sur elle meme et qu'elle est environ de rayon 30px, on a besoin d'utiliser l'expression d'un cercle ''' return [ProjectileDroitRouge( (position[0]+30*((2*self.angle)/(1+self.angle*self.angle)), position[1]+20+30*((1-self.angle*self.angle)/(1+self.angle*self.angle)) ), vecteur )] else : return []
class ArmeBoss(Arme) : delai = 1000 def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.imageNonDim = self.imageDefautNonDim = self.sprites.sprite((0,12), (56, 56)) tailleimage = self.imageNonDim.get_size() self.image = self.imageDefaut = pygame.transform.scale(self.imageNonDim, (tailleimage[0]*2, tailleimage[1]*2)) super(ArmeBoss, self).__init__() def tirer(self, position, vecteur) : if pygame.time.get_ticks() - self.dernierTir > self.delai : super(ArmeBoss, self).tirer(position, vecteur) return [ProjectileDroitRouge((position[0]+30*((2*self.angle)/(1+self.angle*self.angle)), position[1]+20+30*((1-self.angle*self.angle)/(1+self.angle*self.angle))), vecteur)] #cf arme1 else : return []
def __init__(self): self.sprites = Sprites('img/raygun.png') self.image = self.imageDefaut = self.sprites.sprite((0,12), (56, 56)) super(Arme2, self).__init__()
class Checkpoint(pygame.sprite.Sprite): check = False couleur = "red" #red | green | blue compteur = 0 sprite = Sprites("img/items_spritesheet.png") image = None imagesCheck = [] imageNonCheck = None def __init__(self, position, couleur='red'): pygame.sprite.Sprite.__init__(self) self.couleur = couleur #découpe du sprite en fonction de la couleur demandée if couleur == "blue": self.imagesCheck = self.sprite.sprites([((275, 72), (70, 70)), ((275, 0), (70, 70))]) self.image = self.imageNonCheck = self.sprite.sprite((216, 504), (70, 70)) elif couleur == "green": self.imagesCheck = self.sprite.sprites([((216, 432), (70, 70)), ((216, 360), (70, 70))]) self.image = self.imageNonCheck = self.sprite.sprite((216, 288), (70, 70)) elif couleur == "yellow": self.imagesCheck = self.sprite.sprites([((203, 0), (70, 70)), ((202, 144), (70, 70))]) self.image = self.imageNonCheck = self.sprite.sprite((144, 434), (70, 70)) else: #red self.couleur = "red" self.imagesCheck = self.sprite.sprites([((274, 144), (70, 70)), ((216, 216), (70, 70))]) self.image = self.imageNonCheck = self.sprite.sprite((203, 72), (70, 70)) self.rect = self.image.get_rect() self.rect.x, self.rect.y = position def position(self): return (self.rect.x, self.rect.y) def update(self, *args): if self.check: self.image = self.imagesCheck[1 if self.compteur % 60 > 29 else 0] self.compteur += 1 else: self.image = self.imageNonCheck
class Personnage(Entite): vitesse_x = 0 vitesse_y = 0 courir = False #True si le joueur cours accroupi = False multiCourse = 10 #vitesse de deplacementX (marcher/courir) contact_sol = False #utile pour savoir si on peut sauter ou pas vie = 100 sprites = Sprites('img/p1_spritesheet.png') framesGauches = [] framesDroites = [] arme = None def __init__(self, position): #Découpe des sprites self.contruireSprites() super(Personnage, self).__init__(position) ''' construireSprites ''' def contruireSprites(self): #images mouvement par défaut #(images du joueur) images = [ [(0, 0), (72, 97)], [(73, 0), (72, 97)], [(146, 0), (72, 97)], [(73, 98), (72, 97)], [(146, 93), (72, 97)], [(219, 0), (72, 97)], [(292, 0), (70, 97)], [(219, 98), (72, 97)], [(365, 0), (72, 97)], [(292, 98), (72, 97)], ] self.framesDroites = self.sprites.sprites(images) self.framesGauches = self.sprites.sprites(images, flipX=True) self.image = self.imageRepos = self.sprites.sprite((0, 196), (66, 92)) self.imageAccroupi = [ self.sprites.sprite((365, 98), (69, 71)), self.sprites.sprite((365, 98), (69, 71), flipX=True) ] ''' calculY Calcul de la position verticale Avec gestion des collisions bords, des collisions murs @param {dic} niveau L'état du niveau ''' def calcul_Y(self, niveau): #Calcul vitesse verticale due à la gravité if self.rect.bottom < niveau['height']: if self.vitesse_y == 0: self.vitesse_y = 1 else: self.vitesse_y += 0.35 #PFD #finalement, on ne stope pas le joueur au contact du bas de la fenêtre #if self.rect.bottom >= niveau['height']: # if self.vitesse_y > 0 : # on ne peut pas descendre plus bas # self.vitesse_y = 0 # #self.rect.y = niveau['height'] - self.rect.height #on force à ne pas dépasser le sol # self.rect.bottom = niveau['height'] # self.contact_sol = True #Si on touche le bas de la fenêtre if self.rect.bottom >= niveau['height']: self.vitesse_y = self.vitesse_y / 5 + 1 #on reduit pour faire comme si on coulait if self.rect.bottom >= (niveau['height'] + 100): self.blessure(1000) #l'entite meurt self.rect.y += self.vitesse_y #si on touche quelque chose en chemin for collision in collisions(self, niveau): if self.vitesse_y > 0: #si on se déplace en bas, on force le contact avec le haut #pour les elements qui ne sont pas des plateformes #ou les plateformes si on est au dessus (on peut monter par dessous) if (collision.plateforme == False or (collision.plateforme == True and self.rect.bottom <= collision.rect.bottom)): self.rect.bottom = collision.rect.top self.contact_sol = True self.vitesse_y = 0 #on prend en compte la vitesse 0 pour calcul gravité if self.vitesse_y < 0: #si on se déplace vers le haut, on force le contact avec le bas #si c'est une plateforme on passe a travers, ie on change rien if collision.plateforme == False: self.rect.top = collision.rect.bottom self.vitesse_y = 0 #on prend en compte la vitesse 0 pour calcul gravité self.contact_sol = False ''' calculX Calcul de la position horizontale Avec gestion des collisions bords, des collisions murs et de l'accroupissement Et calcul de l'image courante @param {dic} niveau L'état du niveau ''' def calcul_X(self, niveau): #si on touche un bord du niveau if (self.rect.x < 0 and self.vitesse_x < 0) \ or (self.rect.x + self.rect.width > niveau['width'] and self.vitesse_x > 0): self.vitesse_x = 0 #si on est accroupi, on ne peut plus bouger if not self.accroupi: self.rect.x += self.vitesse_x * self.multiCourse # * multi pour fluidité du jeu #si on touche quelque chose en chemin for collision in collisions(self, niveau): if self.vitesse_x > 0: #si on se déplace à droite, on force le contact avec le côté gauche if collision.plateforme == False: # pour les plateformes on ne le fait pas self.rect.right = collision.rect.left if self.vitesse_x < 0: #si on se déplace à gauche, on force le côté droit if collision.plateforme == False: # pour les plateformes on ne le fait pas self.rect.left = collision.rect.right #on ne force pas la vitesse_x à 0 si jamais l'obstacle disparaît de lui même #pas besoin de relancer le keydown clavier #Gestion de l'image #on prend soin de regarder dans la bonne direction if self.vitesse_x > 0: #image si déplacement vers la droite if self.accroupi: self.image = self.imageAccroupi[0] else: self.image = self.framesDroites[(self.rect.x // 30) % len(self.framesDroites)] elif self.vitesse_x < 0: #image si déplacement vers la gauche if self.accroupi: self.image = self.imageAccroupi[1] else: self.image = self.framesGauches[(self.rect.x // 30) % len(self.framesGauches)] else: #image si perso à l'arrêt if self.accroupi: self.image = self.imageAccroupi[0] else: self.image = self.imageRepos ''' positionMain @return {tup} La position de la main ''' def positionMain(self): position = self.position() main = [0, 0] main[0], main[1] = position[0], position[1] main[1] += 70 if not self.accroupi else 50 main[0] += 6 return main ''' update Calcul de la position du joueur @param {dic} niveau l'état du niveau ''' def update(self, niveau, *args): self.calcul_X(niveau) self.calcul_Y(niveau) self.arme.position(self.positionMain()) ''' deplacementX @param {int : 1 | -1} vitesse Vitesse de déplacement. 1 : déplacement vers la droite -1 : vers la gauche ''' def deplacementX(self, vitesse): self.vitesse_x = vitesse ''' vitesseCourse Switch entre marche/course @param {Boolean} courir True : on court ''' def vitesseCourse(self, courir): self.courir = courir self.multiCourse = 6 if not self.courir else 12 ''' seBaisser Le joueur s'accroupi, son rect retrécie en hauteur On ne peut plus bouger une fois accroupi @param {Boolean} accroupi True : joueur accroupi ''' def seBaisser(self, accroupi): self.accroupi = accroupi #le rect accroupi est plus petit en hauteur de 21 px if self.accroupi: self.rect.y += 21 self.rect.height -= 21 else: self.rect.y -= 21 self.rect.height += 21 ''' sauter ''' def sauter(self): if self.contact_sol: #on ne peut pas sauter que si on est en contact avec le sol self.vitesse_y = -10 self.contact_sol = False son.sonSaut() ''' blessure Supprimer l'arme des groupes auxquels elle appartient Jouer son Appeler super @param {int} vie ''' def blessure(self, vie): super(Personnage, self).blessure(vie) if self.vie <= 0: self.arme.kill() son.sonMort()
def __init__(self): self.sprites = Sprites('img/raygun.png') self.image = self.imageDefaut = self.sprites.sprite((0, 12), (56, 56)) super(Arme2, self).__init__()
def __init__(self): self.sprites = Sprites('img/raygunPurple.png') self.image = self.imageDefaut = self.sprites.sprite((0,12), (56, 56)) super(FusilPompe, self).__init__()
class Boss(Ennemi): sprites = Sprites('img/p2_spritesheet.png') arme = ArmeBoss() vie = 80 ''' construireSprites ''' def contruireSprites(self): #images mouvement images = [ [(0, 0), (70, 94)], [(71, 0), (70, 94)], [(142, 0), (70, 94)], [(0, 95), (70, 94)], [(71, 95), (70, 94)], [(142, 95), (70, 94)], [(213, 0), (70, 94)], [(284, 0), (70, 94)], [(213, 95), (70, 94)], [(355, 0), (70, 94)], [(284, 95), (70, 94)], ] #REDIMENSIONNEMENT DES FRAMES DU BOSS # Idee : recuperer taille et mult par ce qu'on veut, ici par 2 j = 0 self.framesDroitesNonDim = self.sprites.sprites(images) self.framesDroites = [] for i in self.framesDroitesNonDim: tailleFD = self.framesDroitesNonDim[j].get_size() redim = pygame.transform.scale(self.framesDroitesNonDim[j], (tailleFD[0] * 2, tailleFD[1] * 2)) self.framesDroites.append(redim) j = j + 1 j = 0 self.framesGauchesNonDim = self.sprites.sprites(images, flipX=True) self.framesGauches = [] for i in self.framesGauchesNonDim: tailleFG = self.framesGauchesNonDim[j].get_size() redim = pygame.transform.scale(self.framesGauchesNonDim[j], (tailleFG[0] * 2, tailleFG[1] * 2)) self.framesGauches.append(redim) j = j + 1 self.imageNonDim = self.imageReposNonDim = self.sprites.sprite( (0, 190), (66, 92)) tailleimage = self.imageNonDim.get_size() self.image = self.imageRepos = pygame.transform.scale( self.imageNonDim, (tailleimage[0] * 2, tailleimage[1] * 2)) self.imageAccroupiNonDim = [ self.sprites.sprite((355, 95), (67, 72)), self.sprites.sprite((355, 95), (67, 72), flipX=True) ] j = 0 self.imageAccroupi = [] for i in self.imageAccroupiNonDim: tailleA = self.imageAccroupiNonDim[j].get_size() redim = pygame.transform.scale(self.imageAccroupiNonDim[j], (tailleA[0] * 2, tailleA[1] * 2)) self.imageAccroupi.append(redim) j = j + 1 ''' positionMain Sur le boss, la main n'est pas au même endroit que pour les perso ''' def positionMain(self): position = self.position() main = [0, 0] main[0], main[1] = position[0], position[1] main[1] += 150 main[0] += 24 return main
def __init__(self, position, image, rect) : self.sprites = Sprites(image) self.image = self.sprites.sprite(rect = rect) super(Mur, self).__init__(position)