Space invaders --------------- Url : http://codes-sources.commentcamarche.net/source/42599-space-invadersAuteur : Shakan972Date : 05/09/2013 Licence : ========= Ce document intitulé « Space invaders » issu de CommentCaMarche (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette source, dans les conditions fixées par la licence, tant que cette note apparaît clairement. Description : ============= C'est donc un jeu que je vous propose qui tente de vous faire redécouvrir un classique des jeux vidéos j'ai nommé :
==> Space inv aders

Bien entendu je n'ai pas repris toutes les idées de ce jeu et je n'ai réalisé ce programme que dans le but de m'entrai ner et non de
retranscrire une pale copie dans ses moindres détail s. ( Je parle pour les fans du jeu là )

Donc rien de nouve au dans ce shoot classique que j'ai réadapté à mon goû ;t, si ce n'est qu'il était très intéressant comme support de programmation.
Sinon vous m'excuserez d'avance pour le design des enne mis qui est je vous l'avoue très spécial :)

Bref po ur ceux qui aimeront amusez vous bien pour les autres, j'espère que vous prendrez plaisir à comprendre la structure de mon programme.

Sinon sachez justement que j'ai apporté un grand nombre de commentaire s afin que mon code soit compréhensible par tous.

LES COMM ANDES :

Tirer ==> Barre d'espacement
Diriger le canon m obile ==> Touches fléchées
Faire une pause ==> Touche P

Source / Exemple :


# -*- coding: cp1252 -*- ################# ################## # # # Programme : Space in vaders # # Auteur : Shakan972 # # Date de creation : 13/04/0 7 # # # ################################### ########################################## # # # Importations des fonctions nécessaires # # # ########################################## from Tkinter i mport * from random import * import time import pickle ################### ######### # # # Définition des fonctions # # # ############################ # Cette fonction affiche l' écran de présentation du jeu def EcranDePresentation(): global DebutJeu if DebutJeu!=1: AffichageScore.configure(text="",font=(' Fixedsys',16)) AffichageVie.configure(text="",font=('Fixedsys ',16)) can.delete(ALL) fen.after(1500,Titre) # On afficher le nom du jeu à l'écran def Titre(): global DebutJeu if DebutJeu!=1 : can.create_text(320,240,font=('Fixedsys',24),text="SPACE INVADER S",fill='blue') fen.after(2000,Titre2) # On affiche le nom de l 'auteur ( It's me !! :p ) def Titre2(): global DebutJeu if DebutJeu !=1: can.create_text(320,270,font=('Freshbot',18),text="By Shakan9 72",fill='red') fen.after(3000,LoadMeilleurScore) # Cette fonct ion va permettre d'enregistrer # le meilleur score def SaveMeilleurScore(res ultat): FichierScore=open('HighScore','r') lecture=pickle.load(Fichier Score) # Si le score réalisé à la fin de la partie # est supérieur à celui déjà enregistré dans le fichier # alors on remplace ce dernier par l e nouveau score record if resultat>lecture: FichierScore= open('HighScore','w') pickle.dump(resultat,FichierScore) Fichi erScore.close() fen.after(2000,MessageRecord) else: fen.a fter(15000,EcranDePresentation) FichierScore.close() # Cette fonction af fiche un message # lui indiquant qu'il a établit un # nouveau record :D def MessageRecord(): can.delete(ALL) can.create_text(320,240,font=('Georg ia',18),text="Vous avez établi un nouveau record !!",fill='red') fen.after(3000,LoadMeilleurScore) # Quant à cette fonction elle va pe rmettre # de lire le meilleur score afin de l'afficher def LoadMeilleurScore (): global DebutJeu if DebutJeu!=1: FichierScore=open('HighSc ore','r') lecture=pickle.load(FichierScore) can.delete(ALL) can.create_text(320,240,font=('Fixedsys',24),text="HIGH SCORE", fill='blue') can.create_text(320,270,font=('Fixedsys',24),text=str(lect ure),fill='blue') FichierScore.close() fen.after(3000,EcranDeP resentation) # Cette fonction permet de vérifier # l'existence d'un fichier def existe(fname): try: f=open(fname,'r') f.close() return 1 except: return 0 # Cette fonction permet de réi nitialiser le jeu # selon la volonté du joueur de recommencer une partie def new_game(): global xe,ye,xe2,ye2,xe3,ye3,LimiteAvancement,dx,ListeCoordEnn emis,ListeEnnemis,ObusEnnemi,flag,photo,NbreEnnemis,Score,ViesJoueur global ListeAbri,CoordonneesBriques,projectile,feu,feuEnnemi,PasAvancement global dyobus,dyobusEnnemi,DebutJeu,BonusActif,dxeb,EnnemiBonus,Mort,photo,PasMax,Nbre EnRangees DebutJeu=1 # On remet l'image d'origine photo =PhotoImage(file='earth.gif') can.create_image(320,240,image=photo) Mort=0 # On efface tout à l'écran can.delete(ALL) can.cre ate_image(320,240,image=photo) # Coordonnées de départ des ennemis # pour chaque catégorie xe,ye=20,20 xe2,ye2=20,80 xe3,ye3=20 ,160 LimiteAvancement=1 if len(ObusEnnemi)==1: can.dele te(ObusEnnemi[0]) dx=1 # Pas d'avancement d'un obus # tiré par le joueur dyobus=20 # Pas d'avancement d'un obus # tiré p ar un ennemi dyobusEnnemi=10 feu=0 ViesJoueur=3 Score= 0 feuEnnemi=0 Ennemis1=[] Ennemis2=[] Ennemis3=[] ListeEnnemis=[Ennemis1,Ennemis2,Ennemis3] Ennemis=[] projectile =[] CoordEnnemis1=[] CoordEnnemis2=[] CoordEnnemis3=[] ListeCoordEnnemis=[CoordEnnemis1,CoordEnnemis2,CoordEnnemis3] NbreEn nemis1=6 NbreEnnemis2=6 NbreEnnemis3=6 PasAvancement=0 NbreE nnemis=[NbreEnnemis1,NbreEnnemis2,NbreEnnemis3] v=0 BonusActif =0 dxeb=5 EnnemiBonus=[] Creation_Abris() Creation_CanonMo bile() # On détermine de manière aléatoire # le nombre de temps avan t qu'apparaisse # le premier ennemi bonus du jeu :) fen.after(ra ndrange(60000,100000,100),CreationEnnemiBonus) AffichageScore.configure(t ext="Score : "+str(Score),font=('Fixedsys',16)) AffichageVie.conf igure(text="Lives : "+str(ViesJoueur),font=('Fixedsys',16)) # Appel des fonctions de création des ennemis # pour recréer un bataillo n de vaisseaux hostiles # prêts à en découdre à nouveau avec le joueur !! while v<6: Ennemi_Categorie1() Ennemi_Categorie2( ) Ennemi_Categorie3() v+=1 flag=1 # Cet te fonction permet de créer les abris # assurant la défense en papier du canon mobile XD def Creation_Abris(): global ListeAbris,CoordonneesBriques ListeAbris=[] CoordonneesBriques=[] i=0 x=40 y=340 while i<3: limX=x+120 limY=y+60 departx=x while y<limY: while x<limX: ListeAbri s.append(can.create_rectangle(x,y,x+20,y+20,fill='grey')) Coord onneesBriques.append([x,y]) x+=20 x=departx y+=20 i+=1 x+=220 y-=60 # Cette fonction pe rmet de créer le nerf de la guerre # ==> Le canon mobile \o/ def Creation _CanonMobile(): global canon,xc1,xc2,yc1,yc2 canon=[] xc1=20 yc1=440 # Création du canon canon.append(can.create_rectangle(x c1,yc1,xc1+20,yc1+20,fill='green')) xc2=xc1-20 yc2=yc1+20 # C réation de la plate-forme du canon canon.append(can.create_rectangle(xc2, yc2,xc2+60,yc2+20,fill='green')) # Les 3 fonctions ci-dessous von t permettre de créer les ennemis du jeu # Création de la 1er catégorie d'enne mis du jeu def Ennemi_Categorie1(): global ListeEnnemis,ListeCoordEnnemi s,xe,ye ListeCoordEnnemis[0].append([xe,ye]) Ennemis=[] Ennemis.a ppend(can.create_rectangle(xe,ye,xe+60,ye+20,fill='blue')) Ennemis.append(c an.create_rectangle(xe,ye,xe+20,ye+40,fill='blue')) Ennemis.append(can.crea te_rectangle(xe+40,ye,xe+60,ye+40,fill='blue')) ListeEnnemis[0].append(Enne mis) xe=xe+80 # Création de la 2e catégorie d'ennemis du jeu def Enne mi_Categorie2(): global ListeEnnemis,ListeCoordEnnemis,xe2,ye2 ListeCo ordEnnemis[1].append([xe2,ye2]) Ennemis=[] Ennemis.append(can.create_r ectangle(xe2,ye2,xe2+20,ye2+40,fill='violet')) Ennemis.append(can.create_re ctangle(xe2+40,ye2,xe2+60,ye2+40,fill='violet')) Ennemis.append(can.create_ rectangle(xe2+20,ye2+20,xe2+40,ye2+60,fill='violet')) ListeEnnemis[1].appen d(Ennemis) xe2=xe2+80 # Création de la 3e catégorie d'ennemis du jeu def Ennemi_Categorie3(): global ListeEnnemis,ListeCoordEnnemis,xe3,ye3 ListeCoordEnnemis[2].append([xe3,ye3]) Ennemis=[] Ennemis.append(can. create_rectangle(xe3+20,ye3,xe3+40,ye3+60,fill='brown')) Ennemis.append(can .create_rectangle(xe3,ye3+20,xe3+60,ye3+40,fill='brown')) ListeEnnemis[2].a ppend(Ennemis) xe3=xe3+80 # Cette fonction va permettre de créer # l'en nemi bonus du jeu def CreationEnnemiBonus(): global EnnemiBonus,xeb,yeb, BonusActif,DebutJeu,CoordEnnemiBonus,dxeb,flag if flag!=0: if Bo nusActif!=1: BonusActif=1 dxeb=5 hasard=r andrange(0,10,1) if hasard>=5: xeb=0 dxeb=dxeb else: xeb=630 dx eb=-dxeb yeb=randrange(80,400,10) EnnemiBonus.append(c an.create_oval(xeb,yeb,xeb+35,yeb+15,fill='red')) EnnemiBonus.appen d(can.create_oval(xeb+5,yeb+5,xeb+10,yeb+10,fill='yellow')) EnnemiB onus.append(can.create_oval(xeb+15,yeb+5,xeb+20,yeb+10,fill='yellow')) EnnemiBonus.append(can.create_oval(xeb+25,yeb+5,xeb+30,yeb+10,fill='yellow') ) # Cette fonction va permettre d'animer # le mouvement de l 'ennemi bonus def AnimationEnnemiBonus(): global EnnemiBonus,xeb,yeb,dxe b,xtir,ytir,DebutJeu,BonusActif,projectile,flag,feu,Score if flag!=0 and DebutJeu!=0 and BonusActif!=0 : # Si l'ennemi bonus atteint l'autre b out de l'écran # il s'auto-détruit !! XD if dxeb>0: if xeb>=640: BonusActif=0 can.delet e(EnnemiBonus[0]) can.delete(EnnemiBonus[1]) c an.delete(EnnemiBonus[2]) can.delete(EnnemiBonus[3]) xeb=0 yeb=0 EnnemiBonus=[] # Détermination aléatoire du temps d'appel # de la fonct ion qui va permettre de procéder # à la création d'un nouvel en nemi bonus fen.after(randrange(60000,100000,1 00),CreationEnnemiBonus) else: if xeb<=20: BonusActif=0 can.delete(EnnemiBonus[0]) c an.delete(EnnemiBonus[1]) can.delete(EnnemiBonus[2]) can.delete(EnnemiBonus[3]) xeb=0 yeb=0 EnnemiBonus=[] fen.after(randrange(60000,10000 0,100),CreationEnnemiBonus) # On fait l'ennemi bonu s avancer xeb=xeb+dxeb if len(EnnemiBonus) !=0: can.coords(EnnemiBonus[0],xeb,yeb,xeb+35,yeb+15) can.coords(EnnemiBonus[1],xeb+5,yeb+5,xeb+10,yeb+10) can.coords(Enn emiBonus[2],xeb+15,yeb+5,xeb+20,yeb+10) can.coords(EnnemiBonus[3],x eb+25,yeb+5,xeb+30,yeb+10) # On vérifie si l'obus tiré par le joueur # touche l'ennemi bonus si tel est le cas # l'ennemi bonus est détruit et on l'efface # de l'ecran pour faire le joueur empocher 300 pts !! if feu!=0: if ytir<=yeb and ytir>=yeb-25: if xtir>=xeb-10 and xtir<=xeb+40: Bon usActif=0 # On efface l'ennemi bonus # ainsi que l'obus qui l'a touché if len(projectile)!=0: can.delete(projectile[0]) can.del ete(EnnemiBonus[0]) can.delete(EnnemiBonus[1]) can.delete(EnnemiBonus[2]) can.delete(EnnemiBonus[ 3]) # On utlise la fonction score afin # d'afficher le nombre de points gagnés # à la suite de la destruction de # l'ennemi bonus score(300,xeb,yeb,17.5,7.5) # Gain de points ==> Modification du score du joueur Score+=300 AffichageScore.configure(text="Sco re : "+str(Score),font=('Fixedsys',16)) # On remet l es coordonnées de l'ennemi # bonus à zéro pour n'engendrer aucune # erreur xeb,yeb=0,0 xtir,ytir=0,0 # On désac tive l'animation de l'obus # tiré par le joueur feu=0 EnnemiBonus=[] f en.after(randrange(15000,25000,100),CreationEnnemiBonus) # On reboucle le tout fen.after(50,AnimationEnnemiBonus) else: fen.after(50,AnimationEnnemiBonus) # Cette fonction perme t d'afficher # le nombre de points gagnés à la suite # de la destruction d'un ennemi def score(donnee,x,y,x2,y2): global afficherScore afficherSc ore.append(can.create_text(x+x2,y+y2,font=('Fixedsys',8),text=str(donnee)+' pts' ,fill='red')) fen.after(1500,EffacerScore) # Cette fonction permet d'eff acer # le nombre de point gagnés et affichés # suite à la destruction d'un enn emi def EffacerScore(): global afficherScore i=0 while i<le n(afficherScore): can.delete(afficherScore[i]) i+=1 # La fo nction ci-dessous permet # d'animer le canon mobile selon # la direction chois ie par le joueur def move(dx): global xc1,xc2,yc1,yc2,ViesJoueur,flag if ViesJoueur!=0 or flag!=0: xc1=xc1+dx xc2=xc2+dx # Si on arrive au bord de l'écran # le canon mobile se retrou ve bloqué # afin de ne pas aller plus loin :p if xc2 <=0: xc1=20 xc2=0 can.coords(canon[0], xc1,yc1,xc1+20,yc1+20) can.coords(canon[1],xc2,yc2,xc2+60,yc2+20) elif xc2>=600: xc1=600 xc2=580 can.coords(canon[0],xc1,yc1,xc1+20,yc1+20) can.coords(canon[1],xc2 ,yc2,xc2+60,yc2+20) else: can.coords(canon[0],xc1,yc1,xc1+ 20,yc1+20) can.coords(canon[1],xc2,yc2,xc2+60,yc2+20) # Cette fo nction va s'occuper de faire les ennemis se déplacer # automatiquement dans le canevas histoire qu'ils puissent esquiver # les tirs du joueur ( un genre d'IA à deux balles quoi !! XD ) def ennemis(): global dx,feuEnnemi,NbreEnnemi s,Xobus,Yobus,ListeCoordEnnemis,DebutJeu,NbreEnRangees global ListeEnnemis, PasAvancement,NbreEnnemis,flag,LimiteAvancement,BonusActif,PasMax if flag !=0 and len(NbreEnnemis)>=1 and DebutJeu!=0: # Si tous les ennemis ont été détruits # ce n'est pas la peine d'exécuter l'animation # de quelque chose qui n'existe plus :p if NbreEnnemis!=0: i=0 t=0 PasAvancement+=1 # On act ive le système de tir des méchants :p # ==> Armement des canons ==> Prêt à détruire l'ennemi ( le joueur ) # Yes sir !! XD tir_ennemi() # Si jamais les ennemis atteignent le bas # de l'écran la partie s'arrête et le joueur # a perdu !! :p while i<len(ListeCoordEnnemis): while t<len(ListeCoordEnnemis[i]): if ListeCoordEnn emis[i][t][1]>=420: can.delete(ALL) image() flag=0 can.cr eate_text(320,240,font=('Fixedsys',18),text="Game Over !!",fill='red') feu=0 ArretAnimation=0 can.delete(canon[0]) can.delete(cano n[1]) DebutJeu=0 SaveMeilleurS core(Score) xc1,yc1=0,0 xc2,yc 2=0,0 t+=1 t=0 i+=1 i=0 # Si les ennemis arrive au bout de l'écran # leur direction s'inverse et ils vont # dans le sens opposé dy=0 if dx>0: # On va utiliser cette 2e variable afin # de s'assurer de l'inve rsion de la direction # des ennemis dx2=dx if len(ListeCoordEnnemis[0])!=0: if ListeCoordEnnemis[0][len(ListeCoordEnnemis[0])-1][0]>=560: dx=-dx2 dy=10 if len(L isteCoordEnnemis[1])!=0: if ListeCoordEnnemis[1][len(ListeC oordEnnemis[1])-1][0]>=560: dx=-dx2 dy=10 if len(ListeCoordEnnemis[2])!=0: if ListeCoordEnnemis[2][len(ListeCoordEnnemis[2])-1][0]>=560: dx=-dx2 dy=10 elif dx<0 : dx2=dx if len(ListeCoordEnnemis[0])!=0: if ListeCoordEnnemis[0][0][0]<=20: dx=-dx2 dy=10 if len(ListeCoordEnnemis [1])!=0: if ListeCoordEnnemis[1][0][0]<=20: dx=-dx2 dy=10 if len(List eCoordEnnemis[2])!=0: if ListeCoordEnnemis[2][0][0]<=20: dx=-dx2 dy=10 i=0 t=0 # On fait avancer tous les ennemis # du canevas while i<len(ListeCoordEnnemis): while t<len(ListeCoordEnnemis[i]): Liste CoordEnnemis[i][t][0]=ListeCoordEnnemis[i][t][0]+dx ListeCo ordEnnemis[i][t][1]=ListeCoordEnnemis[i][t][1]+dy t+=1 i+=1 t=0 i=0 while i< NbreEnnemis[0]: can.coords(ListeEnnemis[0][i][0],ListeCoordEnne mis[0][i][0],ListeCoordEnnemis[0][i][1],ListeCoordEnnemis[0][i][0]+60,ListeCoord Ennemis[0][i][1]+20) can.coords(ListeEnnemis[0][i][1],ListeCoor dEnnemis[0][i][0],ListeCoordEnnemis[0][i][1],ListeCoordEnnemis[0][i][0]+20,Liste CoordEnnemis[0][i][1]+40) can.coords(ListeEnnemis[0][i][2],List eCoordEnnemis[0][i][0]+40,ListeCoordEnnemis[0][i][1],ListeCoordEnnemis[0][i][0]+ 60,ListeCoordEnnemis[0][i][1]+40) i+=1 i=0 while i<NbreEnnemis[1]: can.coords(ListeEnnemis[1][i] [0],ListeCoordEnnemis[1][i][0],ListeCoordEnnemis[1][i][1],ListeCoordEnnemis[1][i ][0]+20,ListeCoordEnnemis[1][i][1]+40) can.coords(ListeEnnemis[ 1][i][1],ListeCoordEnnemis[1][i][0]+40,ListeCoordEnnemis[1][i][1],ListeCoordEnne mis[1][i][0]+60,ListeCoordEnnemis[1][i][1]+40) can.coords(Liste Ennemis[1][i][2],ListeCoordEnnemis[1][i][0]+20,ListeCoordEnnemis[1][i][1]+20,Lis teCoordEnnemis[1][i][0]+40,ListeCoordEnnemis[1][i][1]+60) i+=1 i=0 while i<NbreEnnemis[2]: can.co ords(ListeEnnemis[2][i][0],ListeCoordEnnemis[2][i][0]+20,ListeCoordEnnemis[2][i] [1],ListeCoordEnnemis[2][i][0]+40,ListeCoordEnnemis[2][i][1]+60) can.coords(ListeEnnemis[2][i][1],ListeCoordEnnemis[2][i][0],ListeCoordEnnemis[ 2][i][1]+20,ListeCoordEnnemis[2][i][0]+60,ListeCoordEnnemis[2][i][1]+40) i+=1 fen.after(50,ennemis) else: fen.after( 50,ennemis) # Cette fonction gère le tir des ennemis # et vérifie si un a at teint le canon # mobile du joueur def tir_ennemi(): global feuEnnemi,Xo bus,Yobus,ObusEnnemi,ListeCoordEnnemis,EnnemiChoisi,ChoixTireur,NbreEnnemis,flag ,DebutJeu if flag!=0: if DebutJeu!=0: if feuEnnemi!=1 : feuEnnemi=1 ObusEnnemi=[] i=0 while i<len(EnnemiChoisi): if Ennem iChoisi[i]==0: del EnnemiChoisi[i] i+=1 if len(EnnemiChoisi)==1: Choix=0 else: Choix=randrange(0 ,len(EnnemiChoisi),1) # En fonction de la catégorie d'ennemis choisie # les coordonnées d'un obus tiré ne seront pas # les mêmes pour tout le monde if len(ObusEnnemi)!= 1: if Choix==0: if NbreEnnemis[0]! =0: # La portion de code ci-dessous va permettre aux # ennemis de choisir le canon avec lequel ils v ont # canarder le joueur et ses défenses CanonChoisi=randrange(0,3,1) ChoixTireur=[] ChoixTi reur.append([ListeCoordEnnemis[0][randrange(0,NbreEnnemis[0],1)][0],ListeCoordEn nemis[0][randrange(0,NbreEnnemis[0],1)][1]]) Xobus= ChoixTireur[0][0]+9 Yobus=ChoixTireur[0][1]+40 if CanonChoisi==1: ObusEnnemi.append(can.create_rectangle(Xobus,Yobus,Xo bus+2,Yobus+40,fill='orange')) else: Xobus=Xobus+40 ObusEnnemi.ap pend(can.create_rectangle(Xobus,Yobus,Xobus+2,Yobus+40,fill='orange')) elif Choix==1: if NbreEnnemis[1]!=0: ChoixTireur=[] ChoixTireur.append([ListeCoordEnnemis[1][randrange(0,NbreEnnemis[1],1 )][0],ListeCoordEnnemis[1][randrange(0,NbreEnnemis[1],1)][1]]) Xobus=ChoixTireur[0][0]+29 Yobus=ChoixT ireur[0][1]+60 ObusEnnemi .append(can.create_rectangle(Xobus,Yobus,Xobus+2,Yobus+40,fill='orange')) elif Choix==2: if NbreEnnemis[2]!=0: ChoixTireur=[] ChoixTireur.append([ListeCoordEnnemis[2][randrange(0,NbreEnnem is[2],1)][0],ListeCoordEnnemis[2][randrange(0,NbreEnnemis[2],1)][1]]) Xobus=ChoixTireur[0][0]+29 Yobus =ChoixTireur[0][1]+60 ObusEnnemi.append(can.create_rectangle(Xobus,Yobu s,Xobus+2,Yobus+40,fill='orange')) # On démarre l'animati on de l'obus # tiré par un des ennemis AnimationObusEnnemi() # Cette fonction pe rmet d'animer l'obus tiré # par un ennemi def AnimationObusEnnemi(): gl obal xe,ye,dyobusEnnemi,Yobus,Xobus,ObusEnnemi,feuEnnemi,xc1,xc2,yc1,yc2,feu,Vie sJoueur global PartieFinie,flag,projectile,DebutJeu,Score,Mort,ArretAnimati on,canon if flag!=0: if feuEnnemi==1: Yobus=Yobus+dyo busEnnemi abri() if Yobus>=480: if len(ObusEnnemi)==1: can.delete(ObusEnnemi[0]) feuEnnemi=0 # Si un ti r ennemi parvient à son objectif en # touchant le canon mobile du j oueur ben il crève ==> partie terminée !! :p e lif Xobus>=xc2 and Xobus<=xc2+60 and Yobus>=yc2 or Xobus>=xc1 and Xo bus<=xc1+20 and Yobus>=yc1: can.delete(canon[0]) can.delete(canon[1]) if len(projectile)!=0: can.delete(projectile[0]) if len(ObusEnnemi)!=0: can.delete(ObusEnnemi[0]) feuEnnemi=0 feu=1 # Diminution du capital de vies # du joueur ViesJoueur=ViesJoueur-1 ArretAnimation=1 Mort=1 # On aff iche les vies restantes du joueur if ViesJoueur>=0: AffichageVie.configure(text="Lives : "+str(ViesJoueur), font=('Fixedsys',16)) # Si le nombre de vie est non nul # le joueur ressucite cela va de soi ! if ViesJoueur>0: fen.after(500,Ressurection_joueur ) else: # On efface l'écran can.delete(ALL) image() can.create_text(320,240,font=('Fixedsys',18),text="Game Ov er !!",fill='red') feu=0 ArretAni mation=0 can.delete(canon[0]) can.dele te(canon[1]) DebutJeu=0 # On vérifie le score SaveMeilleurScore(Score) xc1,yc1=0,0 xc2,yc 2=0,0 # Suspension des animations flag=0 if len(ObusEnnemi)==1: can.coords(ObusEnnemi[0],Xobus,Yobus,Xobus+2,Yobus+40) fen.after(50 ,AnimationObusEnnemi) # Cette fonction va permettre d'afficher un # paysage post-apocalyptique si le joueur # fait un game over !! :( :( def image(): global photo photo=PhotoImage(file='apocalypse.gif') can.create_ima ge(320,240,image=photo) # Cette fonction permet de ressuciter # le déf unt joueur \o/ Amen !! XD def Ressurection_joueur(): global canon,xc1,xc 2,yc1,yc2,feu,flag,ArretAnimation,projectile,Mort if flag!=0: if l en(projectile)!=0: can.delete(projectile[0]) Mort=0 ArretAnimation=0 xc1=20 yc1=440 can.delete(canon[0 ]) can.delete(canon[1]) canon=[] canon.append(can.cre ate_rectangle(xc1,yc1,xc1+20,yc1+20,fill='green')) xc2=xc1-20 yc2=yc1+20 canon.append(can.create_rectangle(xc2,yc2,xc2+60,yc2+20,fill ='green')) feu=0 # Cette fonction va permettre de gérer le tir du canon # ainsi que les collisions avec les cibles situées en # haut d u canevas :) def tir_joueur(event): global xc2,yc2,xtir,ytir,projectile, feu,VieEnnemi,flag,DebutJeu if DebutJeu!=0: if flag!=0: if feu!=1 : feu=1 xtir=xc2+20 ytir=yc2-40 projectile=[(can.create_oval(xtir,ytir,xtir+20, ytir+20,fill='yellow'))] time.sleep(0.09) # On lance l'animation de l'obus # tiré par le joueur AnimationObus() # Cette fonction va gérer l'intéracti on d'un obus avec une # brique composant l'un des abris ainsi si le joueur tire sur # l'un des abris qui lui sont offerts ceux-ci se désagrégeront # sous l'e ffet de ses tirs maladroits :p def abri(): global CoordonneesBriques,Lis teAbris,xtir,ytir,feu,Xobus,Yobus,feuEnnemi,CoordEnnemis,ObusEnnemi,projectile i=0 t=0 while i<len(CoordonneesBriques): x=Coordonnee sBriques[i][t] y=CoordonneesBriques[i][t+1] # Si le joueur t ire sur l'une des briques # composant les abris celle-ci est détruite if xtir==x and ytir==y : can.delete(ListeAbris[i] ) can.delete(projectile[0]) feu=0 del Coo rdonneesBriques[i] del ListeAbris[i] t=0 i+=1 i=0 t=0 if feuEnnemi==1: while i<len(CoordonneesBriques) : x=CoordonneesBriques[i][t] y=CoordonneesBriques[i][ t+1] # Si l'ennemi tire sur l'une des briques # comp osant les abris celle-ci est # également détruite if Xobus>=x and Xobus<=x+20 and Yobus>=y: ca n.delete(ListeAbris[i]) if len(ObusEnnemi)==1: can.delete(ObusEnnemi[0]) ObusEnnemi=[] f euEnnemi=0 del CoordonneesBriques[i] del Liste Abris[i] t=0 i+=1 # Cette fonction va permettre d' animer l'obus tiré par # le canon mobile def AnimationObus(): global pr ojectile,xtir,ytir,dxobus,feu,ycible,xcible,xe,ye,xe2,ye2,xe3,ye3,PasAvancement, dx,ListeAbris,BonusActif global VieEnnemi,feuEnnemi,NbreEnnemis,ListeCoordE nnemis,Score,NbreEnnemis,ListeEnnemis,flag,LimiteAvancement global xeb,yeb, EnnemiBonus,ArretAnimation if flag!=0 and len(projectile)==1 and ArretAni mation!=1: if feu==1: ytir=ytir-dyobus abri() if ytir<=20: feu=0 can.delete (projectile[0]) # Le bloc d'instructions qui suit permet de gérer l'intéraction entre # un tir d'obus provoqué par le joueur et un e nnemi, donc si l'obus # touche un ennemi il est logique de dire que celui-ci est détruit i=0 t=0 while i<len(ListeCoordEnnemis): # Pour qu'il n'y ai p as d'erreur au cas où # La liste des coordonnées des ennemis es t vide # on execute le bloc d'instructions suivant # uniquement quand la liste des coordonnées n'est # pas vi de if len(ListeCoordEnnemis)>=1: if len(ListeCoordEnnemis[i])>=1: while t <len(ListeCoordEnnemis[i]): if xtir+5>=ListeC oordEnnemis[i][t][0] and xtir-5<=ListeCoordEnnemis[i][t][0]+60 : if ytir<=ListeCoordEnnemis[i][t][1]+5 and ytir>=Liste CoordEnnemis[i][t][1]-60 : Score=Score+50 feu=0 A ffichageScore.configure(text="Score : "+str(Score),font=('Fixedsys',16 )) can.delete(projectile[0]) score(50,ListeCoordEnnemis[i][t][0],ListeCoordEnnemis[i][ t][1],30,20) if i==0: NbreEnnemis[0]=NbreEnnemis[0]-1 can.delete(ListeEnnemis[i][t][0]) can.delete(ListeEnnemis[i][t][1]) can.delete(ListeEnnemis[i][t][2]) de l ListeEnnemis[i][t] del ListeCoordEnne mis[i][t] elif i==1: NbreEnnemis[1]=NbreEnnemis[1]-1 can.delete(ListeEnnemis[i][t][0]) can.delete(ListeEnnemis[i][t][1]) can.delete(ListeEnnemis[i][t][2]) del ListeEnnemis[i][t] del ListeCoordEnnem is[i][t] elif i==2: NbreEnnemis[2]=NbreEnnemis[2]-1 can.delete(ListeEnnemis[i][t][0]) can.delete(ListeEnnemis[i][t][1]) del ListeEnnemis[i][t] del ListeCoordE nnemis[i][t] t+=1 t=0 i+=1 # Quand il n'y a plus d'ennemis ben on recomm ence # le carnage mais cette fois en rendant la bataille # plus épicée !! T_T if NbreEnnemis[0]+NbreEnnemis [1]+NbreEnnemis[2]==0: # On efface le canon mobile pour le re créer can.delete(canon[0]) can.delete(canon[ 1]) Creation_CanonMobile() # On reprend to us les paramètres de départ # afin qu'il n'y ai aucune erreur xe,ye=20,20 xe2,ye2=20,80 xe 3,ye3=20,160 # On efface l'ennemi bonus if len(EnnemiBonus)!=0: can.delete(EnnemiBonus[0]) can.delete(EnnemiBonus[1]) can.delete(EnnemiBonu s[2]) can.delete(EnnemiBonus[3]) xeb,yeb =0,0 # Avant de passer au niveau suivant # i l faut effacer les briques restantes # à l'écran if len(ListeAbris)!=0: i=0 while i<len(ListeAbris): can.delete(ListeA bris[i]) i+=1 # On recrée les abris du joueur Creation_Abris() LimiteAvancement+=1 if len(ObusEnnemi)==1: can.delete(ObusEnnemi[0]) if dx<0: dx =-dx # On accelère la cadence des ennemis !! # Caramba !! XD dx=dx+1 flag=0 # Le joueur et les ennemis pourront # à nouveau tirer !! feu=0 feuEnnemi=0 BonusActif=0 Ennemis1=[] Ennemis2=[] Ennemi s3=[] ListeEnnemis=[Ennemis1,Ennemis2,Ennemis3] Ennemis=[] CoordEnnemis1= [] CoordEnnemis2=[] CoordEnnemis3=[] ListeCoordEnnemis=[CoordEnnemis1,CoordEnnemis2,CoordEn nemis3] NbreEnnemis1=6 NbreE nnemis2=6 NbreEnnemis3=6 PasAvancement=0 NbreEnnemis=[NbreEnnemis1,NbreEnnemis2,NbreEnnemis3] v=0 # Appel des fonctions de création des ennemis # pour recréer un bataillon de vaisseaux hostiles # prêts à en découdre à nouveau avec le joueur !! while v<6: Ennemi_Categorie1() Ennemi_Categorie2() Ennemi_Categorie3() v+=1 flag=1 else: can.coords(projectile[0],xtir,ytir,xtir+20,ytir+20) fen.after( 50,AnimationObus) # Les deux fonctions ci-dessous permettent # de diri ger le canon mobile de gauche à droite def right(event): global flag,Deb utJeu if DebutJeu!=0: if flag!=0: move(20) def lef t(event): global flag,DebutJeu if DebutJeu!=0: if flag!=0: move(-20) # Cette fonction permet d'effectuer une pause en cours d e partie def pause(event): global flag,pause,feu,DebutJeu,feu,Mort,Bonus Actif,feuEnnemi,ArretAnimation # Si le jeu n'a pas commencé # la fon ction ne démarre pas # Il en est de même si le joueur # est mort :p if DebutJeu!=0 and Mort!=1: if flag==1: pause=can .create_text(320,240,font=('Fixedsys',18),text="PAUSE") f lag=0 elif flag==0: flag=1 can.delete(pause) AnimationObusEnnemi() if feu==1: Arre tAnimation=0 AnimationObus() # ###################### # # # Programme principal # # # ####################### # Création de la fenêtre principal e fen=Tk() # Titre de la fenêtre fen.title('Space invaders') # Défin ition du canevas ( Ecran de jeu ) can=Canvas(fen,width=640,height=480,bg='bla ck') # Définition des touches qui vont permettre # de diriger le canon mobil e can.bind_all("<Right>",right) can.bind_all("<Left& gt;",left) can.bind_all("<space>",tir_joueur) can.bind_al l("<p>",pause) can.grid(row=1,column=0,columnspan=2,rowspan=3 ) # Installation d'une image de fond # pour être plus dans l'ambiance 8) photo=PhotoImage(file='earth.gif') can.create_image(320,240,image=photo) # D éfinition des boutons # Ce bouton permet de commencer une nouvelle partie Button(fen,text="New game",font=("Fixedsys"),command=new_gam e).grid(row=2,column=2,sticky=N,padx=5) Button(fen,text="Quit",font=( "Fixedsys"),command=fen.destroy).grid(row=3,column=2,sticky=N,padx=5) # On crée les abris ListeAbris=[] CoordonneesBriques=[] i=0 x=40 y =340 while i<3: limX=x+120 limY=y+60 departx=x while y <limY: while x<limX: ListeAbris.append(can.create_re ctangle(x,y,x+20,y+20,fill='grey')) CoordonneesBriques.append([x,y] ) x+=20 x=departx y+=20 i+=1 x+=220 y-=60 # Coordonnées du canon mobile canon=[] xc1=0 yc1=0 xc2=0 yc2 =0 # Création des ennemis situés en haut du canevas Ennemis1=[] Ennemis2= [] Ennemis3=[] ListeEnnemis=[Ennemis1,Ennemis2,Ennemis3] Ennemis=[] # Ce tte liste contiendra les coordonnées # de position des ennemis dans le canevas CoordEnnemis1=[] CoordEnnemis2=[] CoordEnnemis3=[] ListeCoordEnnemis=[Co ordEnnemis1,CoordEnnemis2,CoordEnnemis3] NbreEnnemis1=6 NbreEnnemis2=6 Nbre Ennemis3=6 NbreEnnemis=[NbreEnnemis1,NbreEnnemis2,NbreEnnemis3] # Définiti on des coordonnées de départ # de chacune des rangées d'ennemis xe,ye=0,0 x e2,ye2=0,0 xe3,ye3=0,0 i=0 t=0 # On dessine chacune des catégories # d' ennemis dans le canevas en utilisant # les fonctions qui sont dédiées à leur cr éation while i<6: Ennemi_Categorie1() Ennemi_Categorie2() E nnemi_Categorie3() i+=1 # Détermination aléatoire de l'ennemi # qui tir a en premier et ainsi de suite RangEnnemiChoisi=randrange(0,3,1) Ennemi1Ch oisi=randrange(0,NbreEnnemis[0],1) Ennemi2Choisi=randrange(0,NbreEnnemis[1],1) Ennemi3Choisi=randrange(0,NbreEnnemis[2],1) EnnemiChoisi=[Ennemi1Choisi,Enne mi2Choisi,Ennemi3Choisi] # Définition de l'ennemi bonus EnnemiBonus=[] Co ordEnnemiBonus=[] # Coordonnées de l'ennemi bonus xeb=-20 yeb=80 # Ind icateur renseignant sur l'activation # et le passage de l'ennemi bonus dans le canevas BonusActif=0 # Pas d'avancement de l'ennemi bonus dxeb=1 # D éfinition des coordonnées d'un obus xtir=xc2 ytir=yc2-20 ObusEnnemi=[] feu=0 feuEnnemi=0 VieEnnemi=1 dyobus=20 dyobusEnnemi=10 dx=0 ChoixTir eur=[] ChoixTireur.append([ListeCoordEnnemis[0][randrange(0,NbreEnnemis[0],1)][ 0],ListeCoordEnnemis[0][randrange(0,NbreEnnemis[0],1)][1]]) Xobus=ChoixTireur [0][0]+9 Yobus=ChoixTireur[0][1]+40 # Le compteur de score Score=0 # L e nombre de vies du joueur avant de morfler définitivement XD ViesJoueur=3 # Cette variable va nous permettre d'ajuster # le pas d'avancement des ennemis en fonction # de leur vitesse afin qu'il n'y ai pas d'erreurs LimiteAvancem ent=0 projectile=[] PasAvancement=0 flag=0 # On affiche les indications co ncernant # le score et les vies restantes du joueur AffichageScore=Label(fen ,font=('Fixedsys',16)) AffichageVie=Label(fen,font=('Fixedsys',16)) AffichageS core.grid(row=0,column=0,sticky=W) AffichageVie.grid(row=0,column=1,sticky=E) # Cette variable va permettre de suspendre certaines # fonctions durant l'aff ichage de l'écran de présentation DebutJeu=0 # Cette variable indique # s i le joueur est mort ==> Canon mobile détruit # de plus si cette variable va ut 1 certaines fonctions # seront par conséquent désactivées Mort=0 Arret Animation=0 # Si le fichier contenant les scores n'existe pas # on le crée a vec comme valeur de départ ==> 0 if existe('HighScore')==0: FichierS core=open('HighScore','w') pickle.dump(0,FichierScore) FichierScore.cl ose() # Cette liste va permettre d'afficher # les scores suite à la destruct ion d'un ennemi afficherScore=[] # On démarre la danse en mettant les enne mis en scène !! ennemis() AnimationEnnemiBonus() # On affiche l'écran d e présentation du jeu EcranDePresentation() # On met le gestionnaire d'évé nements en route fen.mainloop()

Conclusion :


Le zip contient 3 fichier :

==> 1 f ichier dans lequel est stocké le score du joueur
==> 1 fichier qui contient le code source du jeu :p
==> 2 fichier images pour agr&ea cute;menter le jeu ( rien d'incroyable !! Mais bon... )