fortwoone
-
26 nov. 2020 à 19:50
dachiasse
Messages postés1709Date d'inscriptionsamedi 12 septembre 2020StatutMembreDernière intervention13 mai 2021
-
27 janv. 2021 à 22:31
Bonjour,
Je rencontre un sérieux problème par rapport à l'affichage de mon jeu. N'ayant pas trouvé de moyen de changer les images assez lentement pour que ce soit visible à l'oeil nu. C'est pourquoi j'utilisais la fonction pygame.time.wait dans mon programme afin de le ralentir, mais je me suis aperçu que lorsque j'essayais par exemple de faire bouger mon joueur animé et un rayon qu'il avait lancé en même temps, les durées d'attente s'additionnaient et le programme tournait plus lentement...
Quelqu'un peut m'aider ?
Voici tous les fichiers comportant un pygame.time.wait :
Joueur :
import pygame
#Le fichier playerIMG contient toutes les images qui serviront pour l'animation#et la représentation du joueur.from playerIMG import*from playerSND import*from gear import*from tilesetLoader import*import random
import eventList #On utilisera la méthode d'importation classique afin de ne pas confondre les évènements créés avec les instances pygame.event.#La classe Shadow correspond à l'ombre de Link, que l'on peut apercevoir sous lui#notamment lorsqu'il saute, puisque le reste du temps elle est cachée par le#personnage en lui-même.
pygame.mixer.init()classShadow(pygame.sprite.Sprite):def__init__(self, game, link):super().__init__()
self.velocity=14
self.game=game
self.link=link
self.image=shadeIMG
self.rect=self.image.get_rect()
self.rect.x=306
self.rect.y=320#Les attributs mask présents dans chaque classe servent à déterminer la surface occupée par un sprite#par ses contours plutôt que par un rectangle.
self.mask=pygame.mask.from_surface(self.image)defsetPos(self):#Dans chaque fonction setPos les calculs sont effectués au pixel près.if self.link.action=="swordSlash":if self.link.frame==1:if self.link.direction=="NORTH":if self.link.rect.y!=self.link.playerY:
self.rect.y+=64else:
self.rect.y=self.link.rect.y+30
self.rect.x=self.link.rect.x+16elif self.link.direction=="SOUTH":
self.rect.x=self.link.rect.x+80
self.rect.y=self.link.rect.y+30elif self.link.direction=="WEST":if self.link.rect.x!=self.link.playerX:
self.rect.x+=64
self.rect.y=self.link.rect.y+500elif self.link.direction=="EAST":passelif self.link.frame==2:if self.link.direction=="NORTH":passelif self.link.direction=="SOUTH":passelif self.link.direction=="WEST":
self.rect.x=self.link.rect.x+80
self.rect.y=self.link.rect.y+94elif self.link.direction=="EAST":passelif self.link.frame==3:if self.link.direction=="NORTH":passelif self.link.direction=="SOUTH":passelif self.link.direction=="WEST":passelif self.link.direction=="EAST":passelif self.link.action!="swordSlash":
self.rect.x=self.link.rect.x+16
self.rect.y=self.link.rect.y+30defmove_right(self):ifnot self.game.check_colliding(self, self.game.enemies):
self.rect.x+=self.velocity
defmove_left(self):
self.rect.x-=self.velocity
defmove_up(self):
self.rect.y-=self.velocity
defmove_down(self):
self.rect.y+=self.velocity
#La classe PlayerChar définit toutes les méthodes que le joueur pourra utiliser.classPlayerChar(pygame.sprite.Sprite):def__init__(self, game):super().__init__()
self.default_max_health=12#La variable default_max_health détermine combien de coeurs le joueur#aura lors de la création d'un nouveau fichier de sauvegarde.
self.current_health=12
self.current_max_health=12
self.rupees=0
self.game=game
self.rupeesStr='000'
self.ore_OoS=0
self.velocity=14#L'image idleS1 a été importée via playerIMG
self.image=idleS1
self.rect=self.image.get_rect()
self.rect.x=290
self.rect.y=290
self.mask=pygame.mask.from_surface(self.image)#La variable ci-dessous détermine dans quelle direction regarde le joueur.#Par défaut (au début d'une partie ou à la sortie d'une maison),#le joueur regardera vers le bas de l'écran.
self.direction="SOUTH"
self.action="idle"#Là où image est le fichier à afficher à l'écran, frame est le numéro de#l'image à utiliser dans l'animation.
self.frame=1
self.playerX=self.rect.x
self.playerY=self.rect.y
self.swordLevel=1
self.sword_hitbox=pygame.sprite.Group()
self.swordshot=pygame.sprite.Group()defmove_right(self):ifnot self.game.check_colliding(self, self.game.enemies):
self.action="move"
self.direction ="EAST"
self.rect.x+=self.velocity
self.playerX+=self.velocity
else:passdefmove_left(self):ifnot self.game.check_colliding(self, self.game.enemies):
self.action="move"
self.direction="WEST"
self.rect.x-=self.velocity
self.playerX-=self.velocity
else:
self.action="idle"defmove_up(self):ifnot self.game.check_colliding(self, self.game.enemies):
self.action="move"
self.direction="NORTH"
self.rect.y-=self.velocity
self.playerY-=self.velocity
else:
self.action="idle"defmove_down(self):ifnot self.game.check_colliding(self, self.game.enemies):
self.action="move"
self.direction="SOUTH"
self.rect.y+=self.velocity
self.playerY+=self.velocity
else:
self.action="idle"defjump(self):passdefswordSlash(self):
self.action="swordSlash"if self.frame==1:
self.sword_hitbox.add(SwordHitbox(self, self.game))defsword_Shoot(self):if self.swordshot.sprites()==[]and self.current_health==self.current_max_health:
swordShoot.play()
self.swordshot.add(SwordShoot(self))defmakeSound(self):if self.action=="swordSlash"and self.frame==1:
sound=random.randint(1,3)if sound==1:
sword1.play()elif sound==2:
sword2.play()elif sound==3:
sword3.play()defsetImage(self):if self.action =="idle":if self.direction =="SOUTH":
self.image = idleS1
elif self.direction =="NORTH":
self.image = idleN1
elif self.direction =="WEST":
self.image = idleW
elif self.direction =="EAST":
self.image = idleE
self.frame=1elif self.action=="move":if self.frame==2:if self.direction=="SOUTH":
self.image=idleS2
elif self.direction=="NORTH":
self.image=idleN2
elif self.direction=="EAST":
self.image=walkE
elif self.direction=="WEST":
self.image=walkW
self.frame-=1elif self.frame==1:if self.direction=="SOUTH":
self.image=idleS1
elif self.direction=="NORTH":
self.image=idleN1
elif self.direction=="EAST":
self.image=idleE
elif self.direction=="WEST":
self.image=idleW
self.frame+=1ifnot self.game.tile_loader.screenTiles.__contains(HybridTile):
pygame.time.wait(75)elif self.action=="swordSlash":if self.frame==3:if self.direction=="SOUTH":
self.image=swordS3
elif self.direction=="NORTH":
self.image=swordN3
elif self.direction=="WEST":
self.image=swordW3
elif self.direction=="EAST":
self.image=swordE3
self.frame=1elif self.frame==2:if self.direction=="SOUTH":
self.image=swordS2
elif self.direction=="NORTH":
self.image=swordN2
elif self.direction=="WEST":
self.image=swordW2
elif self.direction=="EAST":
self.image=swordE2
self.frame+=1elif self.frame==1:if self.direction=="SOUTH":
self.image=swordS1
elif self.direction=="NORTH":
self.image=swordN1
elif self.direction=="WEST":
self.image=swordW1
elif self.direction=="EAST":
self.image=swordE1
self.frame+=1ifnot self.game.tile_loader.screenTiles.__contains(HybridTile):
pygame.time.wait(75)
self.mask=pygame.mask.from_surface(self.image)defsetPos(self):if self.action=="idle":if self.rect.x !=self.playerX:
self.rect.x=self.playerX
if self.rect.y !=self.playerY:
self.rect.y=self.playerY
elif self.action=="swordSlash":if self.frame==1:if self.direction=="SOUTH":
self.rect.x-=64elif self.direction=="NORTH":if self.rect.y!=self.playerY:
self.rect.y+=64elif self.direction=="WEST":if self.rect.x!=self.playerX:
self.rect.x+=64
self.rect.y-=64elif self.direction=="EAST":
self.rect.y-=64elif self.frame==2:if self.direction=="NORTH":
self.rect.y-=64elif self.direction=="WEST":
self.rect.x-=64elif self.direction=="EAST":passelse:passelif self.frame==3:if self.direction=="SOUTH":
self.rect.x+=64elif self.direction=="NORTH":passelif self.direction=="WEST":
self.rect.y+=64elif self.direction=="EAST":
self.rect.y+=64defcheckWallColliding(self):for tile in self.game.check_colliding(self, self.game.tl.screenTiles):iftype(tile)==Wall:pass
Ecran de jeu :
import pygame
import tsTileset
import os
import csv
from exceptionHandler import*
pot1=pygame.image.load('resource/img/common/tileset/pot.png')
pot=pygame.transform.scale(pot1,(64,64))classTile(pygame.sprite.Sprite):#Cette classe servira de base pour toutes les cases affichées à l'écran, même si elle ne sera pas utilisée directement. Elle joue le rôle de super-classe.def__init__(self, image=pygame.Surface((64,64)), tileX=1, tileY=1):super().__init__()
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.image=image
self.rect=self.image.get_rect()
self.rect.x=self.tileX*64
self.rect.y=self.tileY*64defmove(self, x, y):#Dans notre cas, si on veut aller à gauche ou vers le haut, alors on met un nombre négatif.
self.rect.x+=x
self.rect.y+=y
defsprite_rect(sprite, dim):if dim=="x":
sprite.rect.x=sprite.tileX*64return sprite.rect.x
elif dim=="y":
sprite.rect.y=sprite.tileY*64return sprite.rect.y
classGround(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.image=tsTileset.classicFloor
if self.context=="introRoom":if self.tileType=="1":
self.image=tsTileset.classicFloor
elif self.tileType=="2":
self.image=tsTileset.entranceFloor1_1
elif self.tileType=="3":
self.image=tsTileset.entranceFloor1_2
elif self.tileType=="4":
self.image=tsTileset.entranceFloor2_1
elif self.tileType=="5":
self.image=tsTileset.entranceFloor2_2
elif self.tileType=="6":
self.image=tsTileset.decoration
elif self.tileType=="7":
self.image=tsTileset.decorationStart
elif self.tileType=="8":
self.image=tsTileset.decorationEnd
else:
errorMessage="parameter tileType is not recognised"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classHybridTile(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.frame=1
self.image=tsTileset.torch1
if self.context=="introRoom":if self.tileType=="1":
self.image=tsTileset.wallAndStairs1
elif self.tileType=="2":
self.image=tsTileset.wallAndStairs2
elif self.tileType=="3":
self.image=tsTileset.torch1
elif self.tileType=="4":
self.image=tsTileset.torch2_1
else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)defsetImage(self):if self.context=="introRoom"and self.tileType=="4":if self.frame==4:
self.image=tsTileset.torch2_4
self.frame=1elif self.frame==3:
self.image=tsTileset.torch2_3
self.frame=4elif self.frame==2:
self.image=tsTileset.torch2_2
self.frame=3elif self.frame==1:
self.image=tsTileset.torch2_1
self.frame=2
pygame.time.wait(75)classWall(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.image=tsTileset.wall1
self.direction="SOUTH"if self.context=="introRoom":if self.tileType=="1":
self.image=tsTileset.wall1
self.direction="NORTH"elif self.tileType=="2":
self.image=tsTileset.wall2
self.direction="SOUTH"elif self.tileType=="3":
self.image=tsTileset.wall3
self.direction="EAST"elif self.tileType=="4":
self.image=tsTileset.wall4
self.direction="WEST"else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classStairs(Tile):def__init__(self, tileX, tileY, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.context=context
self.image=tsTileset.stairs
if self.context=="introRoom":
self.image=tsTileset.stairs
else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classAngledWall(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.image=tsTileset.angledWall1_1
if self.context=="introRoom":if self.tileType=="1":
self.image=tsTileset.angledWall1_1
elif self.tileType=="2":
self.image=tsTileset.angledWall1_2
elif self.tileType=="3":
self.image=tsTileset.angledWall1_3
elif self.tileType=="4":
self.image=tsTileset.angledWall1_4
elif self.tileType=="5":
self.image=tsTileset.angledWall2_1
elif self.tileType=="6":
self.image=tsTileset.angledWall2_2
elif self.tileType=="7":
self.image=tsTileset.angledWall2_3
elif self.tileType=="8":
self.image=tsTileset.angledWall2_4
else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classEntranceBorder(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.image=tsTileset.entranceBorder1_1
if context=="introRoom":if self.tileType=="1":
self.image=tsTileset.entranceBorder1_1
elif self.tileType=="2":
self.image=tsTileset.entranceBorder1_2
elif self.tileType=="3":
self.image=tsTileset.entranceBorder2_1
elif self.tileType=="4":
self.image=tsTileset.entranceBorder2_2
elif self.tileType=="5":
self.image=tsTileset.entranceBorder3_1
elif self.tileType=="6":
self.image=tsTileset.entranceBorder3_2
elif self.tileType=="7":
self.image=tsTileset.entranceBorder4_1
elif self.tileType=="8":
self.image=tsTileset.entranceBorder4_2
else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classTriforcePedestal(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.image=tsTileset.triforcePedestalL
if context=="introRoom":if self.tileType=="1":
self.image=tsTileset.triforcePedestalL
elif self.tileType=="2":
self.image=tsTileset.triforcePedestalR
else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classTriforcePedestalBorder(Tile):def__init__(self, tileX, tileY, tileType, context):
pygame.sprite.Sprite.__init__(self)
self.tileX=tileX
self.tileY=tileY
self.tileType=tileType
self.context=context
self.image=tsTileset.triforcePedestalAngledBorderL
if context=="introRoom":if self.tileType=="1":
self.image=tsTileset.triforcePedestalAngledBorderL
elif self.tileType=="2":
self.image=tsTileset.triforcePedestalAngledBorderR
elif self.tileType=="3":
self.image=tsTileset.triforcePedestalBorder
elif self.tileType=="4":
self.image=tsTileset.triforcePedestalBorderWithDecorationS
elif self.tileType=="5":
self.image=tsTileset.triforcePedestalBorderWithDecorationE
elif self.tileType=="6":
self.image=tsTileset.triforcePedestalSideBorderL
elif self.tileType=="7":
self.image=tsTileset.triforcePedestalSideBorderR
else:
errorMessage="given context is not valid"raiseTileError(errorMessage)
self.rect=self.image.get_rect()
self.rect.x=sprite_rect(self,"x")
self.rect.y=sprite_rect(self,"y")Tile().__init__(image=self.image, tileX=self.tileX, tileY=self.tileY)classHole(Tile):#Cette classe gèrera les trous sur l'écran dans lesquels pourrait tomber Link.def__init__(self):passclass TileLoader:#Cette classe s'occupera de lire le contenu d'un écran. La transition s'effectuera plus tard.def__init__(self):
self.maxTileX=0
self.maxTileY=0
self.screenTiles=pygame.sprite.Group()#Crée le groupe de sprites qui gèrera les collisions avec les cases.defemptyTiles(self):
self.maxTileX=0
self.maxTileY=0
self.screenTiles.empty()defreadScreen(self, directory):if os.path.splitext(directory)[1]=='.csv':
with open(directory) as file:
tileX=0
tileY=0
rowIndex=1
screenSettings=[]
tile=""
tType=""
reader=csv.reader(file, delimiter=",")for row in reader:if rowIndex==1:
screenSettings=row
self.maxTileX=screenSettings[0]
self.maxTileY=screenSettings[1]
context=screenSettings[2]if context=="introRoom":
tileY=0else:
tileY=1else:for cell in row:
tile=cell[0]try:
tType=cell[1]except IndexError:passif context=="introRoom":if tile=="A":
self.screenTiles.add(Ground(tileX, tileY, tType, context))elif tile=="B":
self.screenTiles.add(Wall(tileX, tileY, tType, context))elif tile=="C":
self.screenTiles.add(AngledWall(tileX, tileY, tType, context))elif tile=="D":
self.screenTiles.add(Stairs(tileX, tileY, context))elif tile=="E":
self.screenTiles.add(EntranceBorder(tileX, tileY, tType, context))elif tile=="H":
self.screenTiles.add(HybridTile(tileX, tileY, tType, context))elif tile=="T":
self.screenTiles.add(TriforcePedestal(tileX, tileY, tType, context))elif tile=="U":
self.screenTiles.add(TriforcePedestalBorder(tileX, tileY, tType, context))else:
errorMessage="no valid context has been given"raiseTileError(errorMessage)if tileX>=len(row)-1:
tileX=0else:
tileX+=1
tileY+=1
rowIndex+=1else:
errorMessage="can't read other files format than CSV in function readScreen"raiseMapFileExtensionError(errorMessage)defscrollableTiles(self, direction):#Utiliser cette fonction plus tard lors de l'ajout du scrollingif direction=="side":if self.maxTileX>10:return True
else:return False
elif direction=="vertical":if self.maxTileY>10:return True
else:return False
dachiasse
Messages postés1709Date d'inscriptionsamedi 12 septembre 2020StatutMembreDernière intervention13 mai 2021149 27 janv. 2021 à 22:31
Salut,
Sujet intéressant. Une chose que l'on peut faire avec un tel problème, c'est de minimiser le programme à l'essentiel. Si tu as appris les bonnes méthodes de programmation, tu sais faire de la programmation modulaire et tu peux minimiser le programme en 2 temps 3 mouvements. Si ce n'est pas le cas, tu t'es fourré dans un casse-tête.
Attention,
time.sleep(ms)
est une méthode dite bloquante. Le programme freezera pendant l'attente.