Je me suis lancé dans un mini projet: un space invaders avec Pygame. Mon jeu fonctionne assez bien, mais parfois, et sans raison apparente, les "monstres venus de l'espace", au lieu de se déplacer verticalement de droite à gauche et une fois arrivés en fin de ligne descendre puis continuer de gauche à droite, se mettent à partir en diagonale!
De plus, quand le vaisseau défenseur se prend 3 tirs de la part des "invaders", on est sensé avoir perdu... et là, non: Ca semble être un problème avec mon "break" dans ma boucle infinie... Pourtant je ne vois rien d'anormal!
Voici le corps principal de mon programme:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from pygame import *
from pygame.locals import *
from time import sleep
from random import randrange
init()
fe=display.set_mode((400,400))
vaisseau=image.load("sprites/vaisseau.png").convert_alpha()
fond=image.load("sprites/fond.png").convert_alpha()
ennemi_1_1=image.load("sprites/ennemi_1_1.png").convert_alpha()
ennemi_1_2=image.load("sprites/ennemi_1_2.png").convert_alpha()
balle_1=image.load("sprites/balle_1.png").convert_alpha()
balle_enm_1=image.load("sprites/balle_ennemi_1.png").convert_alpha()
def affiche_perso(perso,monstre,change_forme):
fe.blit(fond,(0,0))
fe.blit(vaisseau,(perso["perso"][0],perso["perso"][1]))
for i in perso["balles"][0]:
if len(perso["balles"][0])!=0:
fe.blit(perso["balles"][1+change_forme],([i][0][0],[i][0][1]))
for i in monstre:
for j in monstre[i][0]:
fe.blit(monstre[i][1+change_forme],([j][0][0],[j][0][1]))
display.flip()
level=0
life=3
vitesse_monstre=1
vitesse_descente_monstre=6
vitesse_balles_perso=10
vitesse_balles_monstre=5
nombre_max_balles_ennemi=5
nombre_max_balles_perso=5
chance_tir_ennemi=10
key.set_repeat(1, 30) #Constante
while 1:
if life==0:
fife=3
level+=1
if level==1:
from niveaux.AA_level_1 import *
if level==2:
from niveaux.AA_level_2 import *
if level==3:
from niveaux.AA_level_3 import *
if level==4:
from niveaux.AA_level_4 import *
if level==5:
from niveaux.AA_level_5 import *
if level==6:
from niveaux.AA_level_6 import *
if level==7:
from niveaux.AA_level_7 import *
if level==8:
from niveaux.AA_level_8 import *
if level==9:
from niveaux.AA_level_9 import *
if level==10:
from niveaux.AA_level_10 import *
change_forme=0
compte_forme=0
change_ligne=0
sens=0
while 1:
sleep(0.05)
affiche_perso(perso,monstre,change_forme)
compte_forme+=1
if compte_forme==5:
compte_forme=0
change_forme+=1
if change_forme==2:change_forme=0
for i in event.get():
if i.type==QUIT:
exit()
if i.type==KEYDOWN:
if i.key==K_ESCAPE:
exit()
if i.key==K_UP:
if len(perso["balles"][0])<=nombre_max_balles_perso-1:
perso["balles"][0].append([perso["perso"][0]+13,perso["perso"][1]+14])
if i.key==K_RIGHT:
if perso["perso"][0]<364:
perso["perso"][0]+=5
if i.key==K_LEFT:
if perso["perso"][0]>10:
perso["perso"][0]-=5
for i in perso["balles"][0]:
for j in monstre:
if "monstre" in j:
for k in monstre[j][0]:
if i[0]>=k[0] and i[0]<=k[0]+16 and i[1]>=k[1] and i[1]<=k[1]+15:
perso["balles"][0].remove(i)
monstre[j][0].remove(k)
for i in monstre["balles"][0]:
if i[0]>=perso["perso"][0] and i[0]<=perso["perso"][0]+26 and i[1]>=perso["perso"][1] and i[1]<=perso["perso"][1]+26:
life-=1
monstre["balles"][0].remove(i)
for i in monstre:
if "monstre" in i:
for j in monstre[i][0]:
if j[0]>=375 or j[0]<=9:
change_ligne=1
if sens==0:
sens=1
else:
sens=0
for i in monstre:
if "monstre" in i:
for j in monstre[i][0]:
if change_ligne==1:
j[1]+=vitesse_descente_monstre
if sens==0:
j[0]+=vitesse_monstre
else:
j[0]-=vitesse_monstre
else:
if sens==0:
j[0]+=vitesse_monstre
else:
j[0]-=vitesse_monstre
change_ligne=0
for i in perso["balles"][0]:
i[1]-=vitesse_balles_perso
if i[1]<=0:
perso["balles"][0].remove(i)
for i in monstre["balles"][0]:
i[1]+=vitesse_balles_monstre
if i[1]>=400:
monstre["balles"][0].remove(i)
for i in monstre:
if "monstre" in i:
for j in monstre[i][0]:
rnd=randrange(chance_tir_ennemi)
if rnd==0 and len(monstre["balles"][0])<=nombre_max_balles_ennemi-1:
monstre["balles"][0].append([int(j[0]),int(j[1])])
a=0
for i in monstre:
if "monstre" in i:
for j in monstre[i][0]:
a+=1
if a==0 or life==0:
if life==0:
level-=1
break
j'ai une idée du pourquoi à tes questions, cependant je pense que tu devrais le laisser en standby pour t'attaquer à la POO, et tout sera plus limpide.
c'est assez dommage de n'utiliser pygame que pour faire du blit.
Merci d'avoir pris le temps de chercher les erreurs que j'ai commises, tu as raison, je devrais m'y mettre.Mais sincèrement, je n'arrive pas trop à voir l’intérêt de la POO.
Je ne prétend pas qu'il n'y en a pas, je sais qu'il y en a. Mais comme je n'ai jamais réussis à comprendre où appliquer la POO dans ce genre de script, je ne peu pas l'utiliser et donc comprendre son utilité.
Si tu pouvais me dire à quels endroits je peux l'appliquer dans mon code, ça me serait certainement d'une grande aide pour simplifier et résoudre les problèmes que j'ai rencontré.
Bon, voilà, j'ai essayé d'utiliser les classes, et j'ai fais une refonte total du programme, mais j'ai toujours des problèmes...
Dès les premiers 10em de secondes, l'un des "invader" tombe, au même moment où il tire. C'est toujours le même (le 2nd en partant de la gauche). De plus, ma gestion des impactes ne fonctionne plus (ça, en cherchant un peu, je devrais trouver seul), mais surtout, les ennemis ne tirent plus du tout après que le premier ait tiré, tout le reste fonctionne pourtant parfaitement, je n'ai pas d'erreur de python, et je n'arrive vraiment pas à trouver où ça cloche, mais il me semble que c'est le même problème que pour mon précédent code.
mes codes sources:
programme principale:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from classe import *
from cst import *
from pygame import *
from pygame.locals import *
from time import sleep
init()
fenetre=display.set_mode((largeur_fenetre,hauteur_fenetre))
display.set_caption(titre_fenetre)
icon=image.load(image_icon).convert()
accueil=image.load(image_accueil).convert()
fond=image.load(image_fond).convert()
display.set_icon(icon)
continuer=1
niveau=0
key.set_repeat(1, 30) #Constante
while 1:
while continuer:
fenetre.blit(accueil,((int((largeur_fenetre-largeur_accueil)/2),int((hauteur_fenetre-hauteur_accueil)/2))))
display.flip()
sleep(0.5)
for evnt in event.get():
if evnt.type==QUIT:
exit()
if evnt.type==KEYDOWN:
if evnt.key==K_RETURN:
continuer=0
ennemi=Ennemi()
balles=Balles()
perso=Perso()
niveau+=1
if niveau==1:
ennemi.genere_niveau("niveaux/niveau_1.txt")
while 1:
time.Clock().tick(30)
for evnt in event.get():
if evnt.type==QUIT:
exit()
if evnt.type==KEYDOWN:
if evnt.key==K_RIGHT:
perso.deplacer("droite")
if evnt.key==K_LEFT:
perso.deplacer("gauche")
if evnt.key==K_UP:
balles.tir_perso([perso.pos_perso[0]+int(largeur_perso/2),perso.pos_perso[1]])
display.flip()
fenetre.blit(fond,(0,0))
ennemi.afficher(fenetre)
balles.afficher(fenetre)
perso.afficher(fenetre)
ennemi.deplacement()
balles.deplace()
#colisions
for element in balles.balles_ennemi:
if element[0]>=perso.pos_perso[0] and element[0]<=perso.pos_perso[0]+largeur_perso and element[1]>=perso.pos_perso[1] and element[1]<=perso.pos_perso[1]+hauteur_perso:
perso.perd_vie(-1)
balles.supprime_balles("ennemi",element)
for element_1 in balles.balles_perso:
for element in ennemi.positionnements:
if element_1[0]>=element[1][0] and element_1[0]<=element[1][0]+largeur_sprite and element_1[1]>=element[1][1] and element_1[1]<=element[1][1]+hauteur_sprite:
ennemi.supprime_invader(element)
#tir ennemi aléatoire
balles.tir_ennemi(ennemi.positionnements[randrange(len(ennemi.positionnements)-1)][1])
les classes:
#!/usr/bin/python
# -*- coding: utf-8 -*-
from pygame import *
from pygame.locals import *
from cst import *
from random import randrange
class Ennemi:
"""classe qui créée un niveau, affiche, fait tirer et
fait se déplacer les invaders"""
def __init__(self):
self.positionnements=0
self.sens="droite"
self.vitesse=vitesse_ennemi
self.direction="horizontale"
def supprime_invader(self,invader):
self.positionnements.remove(invader)
def genere_niveau(self,fichier):
#cree un niveau en fonction du fichier niveau_X
with open(fichier,"r") as fichier:
structure=[]
nombre_ligne=0
for ligne in fichier:
nombre_colonne=0
ligne_niveau=[]
for sprite in ligne:
if sprite!="\n":
if sprite!="x":
ligne_niveau.append([sprite,[nombre_colonne*(largeur_sprite+bordure),nombre_ligne*(hauteur_sprite+bordure)]])
nombre_colonne+=1
if len(ligne_niveau)!=0:
structure.append(ligne_niveau)
nombre_ligne+=1
self.positionnements=structure
def afficher(self,fenetre):
#affiche les invaders
invader_1_1=image.load(image_invadre_1_1).convert_alpha()
invader_1_2=image.load(image_invadre_1_2).convert_alpha()
invader_2=image.load(image_invadre_2).convert_alpha()
invader_3=image.load(image_invadre_3).convert_alpha()
invader_4=image.load(image_invadre_4).convert_alpha()
invader_5=image.load(image_invadre_5).convert_alpha()
invader_6=image.load(image_invadre_6).convert_alpha()
for element in self.positionnements:
for element_2 in element:
if element_2[0]=="a":
fenetre.blit(invader_1_1,(element_2[1][0],element_2[1][1]))
elif element[0]=="b":#plus tard, il y aura plus de sortes d'invaders et ils changeront de forme. il n'y a que les "a" pour le moment
fenetre.blit(invader_2,(element_2[1][0],element_2[1][1]))
elif element[0]=="c":
fenetre.blit(invader_3,(element_2[1][0],element_2[1][1]))
elif element[0]=="d":
fenetre.blit(invader_4,(element_2[1][0],element_2[1][1]))
elif element[0]=="e":
fenetre.blit(invader_5,(element_2[1][0],element_2[1][1]))
elif element[0]=="f":
fenetre.blit(invader_6,(element_2[1][0],element_2[1][1]))
def deplacement(self):
#déplace les invaders de gauche à droite, en bas
if self.sens=="droite" and self.direction=="horizontale":
for invader in self.positionnements:
for element in invader:
element[1][0]+=self.vitesse
if element[1][0]>=(largeur_fenetre-largeur_sprite)-bordure:
self.sens="bas"
self.direction="droite"
elif self.sens=="gauche" and self.direction=="horizontale":
for invader in self.positionnements:
for element in invader:
element[1][0]-=self.vitesse
if element[1][0]<=bordure:
self.sens="bas"
self.direction="gauche"
elif self.sens=="bas":
if self.direction=="droite":
self.sens="gauche"
if self.direction=="gauche":
self.sens="droite"
self.direction="horizontale"
for invader in self.positionnements:
for element in invader:
element[1][1]+=self.vitesse
class Balles:
"""créé les balles, limite leur nombre, les déplace,
les supprimes et les affiches"""
def __init__(self):
self.balles_ennemi=[]
self.balles_perso=[]
self.nombre_max_ennemi=nombre_balle_ennemi_max
self.nombre_max_perso=nombre_balle_perso_max
self.vitesse_balles_ennemi=vitesse_balles_ennemi
self.vitesse_balles_perso=vitesse_balles_perso
def tir_ennemi(self,pos_ennemi):
#créé une balle ennemi en fonction de la pos de l'ennemi qui tire
if len(self.balles_ennemi)<self.nombre_max_ennemi+1:
self.balles_ennemi.append([pos_ennemi[0],pos_ennemi[1]])
def tir_perso(self,pos_perso):
#créé une balle perso en fonction de la pos du perso
if len(self.balles_perso)<self.nombre_max_perso+1:
self.balles_perso.append(pos_perso)
def afficher(self,fenetre):
#affiche toutes les balles
balle_1=image.load(image_balle_1).convert()
for i in self.balles_ennemi:
fenetre.blit(balle_1,(i[1][0],i[1][1]))
for i in self.balles_perso:
fenetre.blit(balle_1,(i[0],i[1]))
def deplace(self):
#déplace les balles ennemi, perso en fonction de leur vitesse respective,
#les envoi à la suppression quand elles sortent de l'ecran
for balles in self.balles_ennemi:
balles[1][1]+=self.vitesse_balles_ennemi
if balles[1][1]>=400:
self.supprime_balle("ennemi",balles)
for balles in self.balles_perso:
balles[1]-=self.vitesse_balles_perso
if balles[1]<=0:
self.supprime_balle("perso",balles)
def supprime_balle(self,camp,position):
#supprime une balle du camp ennemi ou perso, en fonction de sa position
if camp=="ennemi":
self.balles_ennemi.remove(position)
if camp=="perso":
self.balles_perso.remove(position)
class Perso:
"""créé un perso en fonction de ses pdv, vitesse de déplacement,
le positionne au milieu en bas de la fenetre"""
def __init__(self):
self.pos_perso=[int(largeur_fenetre/2)-bordure,int(hauteur_fenetre-hauteur_perso)]
self.vitesse=vitesse_perso
self.vies=vies_perso
def deplacer(self, sens):
#change la position du perso en fonction de sa vitesse, et du sens de déplacement
if sens=="droite" and self.pos_perso[0]<=largeur_fenetre-largeur_perso-bordure:
self.pos_perso[0]+=self.vitesse
elif sens=="gauche" and self.pos_perso[0]>=bordure:
self.pos_perso[0]-=self.vitesse
def afficher(self, fenetre):
#charge l'image à son emplacement
perso_1=image.load(image_perso_1).convert_alpha()
fenetre.blit(perso_1,(self.pos_perso[0],self.pos_perso[1]))
def perd_vie(self,valeur):
#fait perdre ou gagner une vie au perso
self.vies+=valeur
et monn fichier de constantes (cst.py):
"""constantes du jeu space invaders"""
largeur_fenetre=400
hauteur_fenetre=400
largeur_accueil=331
hauteur_accueil=31
titre_fenetre="Space Invaders"
image_icon="sprites/ennemi_1_1.png"
image_accueil="sprites/accueil.png"
image_fond="sprites/fond.png"
bordure=10
largeur_perso=26
hauteur_perso=16
hauteur_sprite=16
largeur_sprite=16
largeur_balle=1
hauteur_balle=2
vies_perso=5
vitesse_perso=5
vitesse_ennemi=0.1 #vitesse de deplacement des invaders
nombre_balle_ennemi_max=5 #nombre de balles ennemi maximum presentes dans la fenetre
nombre_balle_perso_max=5 #nombre de balles du perso maximum presentes dans la fenetre
vitesse_balles_ennemi=10 #vitesse des balles ennemi en pxl
vitesse_balles_perso=10 #vitesse des balles du perso en pxl
image_balle_1="sprites/balle_1.png"
image_perso_1="sprites/vaisseau.png"
image_invadre_1_1="sprites/ennemi_1_1.png"
image_invadre_1_2="sprites/ennemi_1_2.png"
image_invadre_2="sprites/ennemi_1_1.png"
image_invadre_3="sprites/ennemi_1_1.png"
image_invadre_4="sprites/ennemi_1_1.png"
image_invadre_5="sprites/ennemi_1_1.png"
image_invadre_6="sprites/ennemi_1_1.png"
Voilà, j'espère que toi, ou quelqu'un d’autre qui passerait par ici pourrait m'aider!
Heu... bah j'avoue que je ne sais pa du tout comment on fait... c'est la première fois que je poste sur un forum... Tu pourrais me donner quelques conseils sur comment héberger le fichier, si tu as le temps (je suis sous linux, donc c'est un fichier tar gz, j'espère que ca ne te dérange pas...)?
Bon! Finalement, j'ai trouvé mon erreur! C'était un problème avec la liste des balles: des listes dans des listes dans des listes, c'est pas une super idée pour être organisé!
En tous cas, je te remercie de m'avoir aidé dans la résolution de mon problème!
Grâce à toi, je me suis forcé à utiliser les classes, et maintenant, j'en vois l'utilité: un code certes plus long, mais beaucoup plus clair et ordonné!
Pour ce qui est dans la gestion des impactes, comme dit initialement, je devrais trouver tout en cherchant un peu...
Donc je vais passer le sujet en "résolu"!
Encore merci!!
quelques problème avec Pygame (ou python?)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.