Astre2.0 casse-briques

Description

Un casse-briques en python 2.6 selon le principe de la gestion des sprites par la méthode des rectangles réduits. J'ai retiré tous les son pour plus de compatibilité et parce qu'on est limité a 1mo pour le zip.

Faites-moi part des bugs encore présents.

Source / Exemple :


################################################################################
#               A S T R E  2.0 par Guillaume Michon                            #
#                                                                              #
#               Genre : Casse-Briques                                          #
#                                                                              #
#       Principe utilise : gestion de collision de sprites par la methode      #
#                          des rectangles reduits.                             #
#                                                                              #
################################################################################
from ressources import images
from module_scores import *
from module_edition import *
from classeSprite import Sprite
from Tkinter import *
from PIL import Image,ImageTk
from random import randrange
from math import cos,sin,radians,sqrt,fabs,atan2
import pickle
import tkFileDialog
import os
import glob
from time import sleep

#--- Gestion des sprites ---
def GestionnaireDeSprites():
    """Boucle principale de gestion des sprites"""

    CheckCollision()
    DessineSprites()
    if not pause :    
        root.after(24,GestionnaireDeSprites)

def CheckCollision():
    """Choisi successivement un sprite dans la liste des sprites mis en
        mouvement et verifie si celui-ci est entré en contact avec un
        sprite de la liste des cibles."""
        
    global nbr_balles_en_jeu,tab_sprites_mvt,tab_sprites_cibles,pause,nbr_vie,\
           text_vie

    #--- Permet de lier la balle a la raquette quand cela est à propos ---#
    for sprite in tab_sprites_mvt:
        if sprite.nom == "balle" :
            if sprite.reaction == "stop":
                for i in tab_sprites_cibles:
                    if i.nom == "raquette":
                        sprite.coord_x = (i.coord_x - sprite.largeur) +\
                                                (sprite.pourcentage * i.largeur)
        #--- Sauvegarde des coordonnées du sprite avant son déplacement ---#
        old_Coord = sprite.GetPosition()
        #--- La methode 'deplacement' revoie 'false' si le sprite est en mode
        #    destruction quand il rencontre une limite de bord          ---#
        if sprite.Deplacement():
            #if len(can.find_enclosed(sprite.coord_x-75,sprite.coord_y-75,sprite.coord_x+sprite.largeur+75,sprite.coord_y+sprite.hauteur+75)) > 1:
                #print can.find_enclosed(sprite.coord_x-75,sprite.coord_y-75,sprite.coord_x+sprite.largeur+75,sprite.coord_y+sprite.hauteur+75)
            #--- On test que la raquette pour un bonus
            if sprite.nom == "bonus":
                if sprite.TestCollision(sprite.cibles[0]):
                    SpriteCollision(sprite,sprite.cibles[0],old_Coord)
            #---Pour les briques en mouvement horizontal
            #  On test que les briques sur le même axe
            elif sprite.option == "mvt horizontal":
                for test_sprite in tab_sprites_cibles:
                    if test_sprite == sprite:
                        continue
                    if test_sprite.coord_y != sprite.coord_y and test_sprite.option != "mvt vertical":
                        continue
                    if sprite.TestCollision(test_sprite):
                        SpriteCollision(sprite,test_sprite,old_Coord)
                        break
                #--- puis la balle
                for test_sprite in sprite.cibles:
                    if sprite.TestCollision(test_sprite):
                        SpriteCollision(sprite,test_sprite,old_Coord)
                        break
            #---Pour les briques en mouvement vertical
            #  On test que les briques sur le même axe                        
            elif sprite.option == "mvt vertical" :
                for test_sprite in tab_sprites_cibles:
                    if test_sprite == sprite:
                        continue
                    if test_sprite.coord_x != sprite.coord_x and test_sprite.option != "mvt horizontal":
                        continue
                    if sprite.TestCollision(test_sprite):
                        SpriteCollision(sprite,test_sprite,old_Coord)
                        break
                #--- puis la balle
                for test_sprite in sprite.cibles:
                    if sprite.TestCollision(test_sprite):
                        SpriteCollision(sprite,test_sprite,old_Coord)
                        break
            #--- Pour la balle et les obus 
            elif sprite.nom == "balle" or sprite.nom == "obus":
                #if len(can.find_enclosed(sprite.coord_x-65,sprite.coord_y-65,sprite.coord_x+sprite.largeur+65,sprite.coord_y+sprite.hauteur+65)) > 1:
                for test_sprite in tab_sprites_cibles:
                    if test_sprite == sprite:
                        continue                    
                    if sprite.TestCollision(test_sprite):
                        SpriteCollision(sprite,test_sprite,old_Coord)
                        break

        #--- Destruction du sprite arrivé à sa limite de bord           ---#
        else:
            can.delete(sprite.image)
            tab_sprites_mvt.remove(sprite)
            if sprite.nom == "balle":
                nbr_balles_en_jeu -= 1
            if nbr_balles_en_jeu == 0:
                nbr_vie -= 1
                can.itemconfigure(text_vie,text=" X "+str(nbr_vie))
                if nbr_vie != 0 :
                    NouvelleBalle()
                else:
                    root.unbind('p')
                    root.unbind('m')
                    pause = True
                    can.create_text(250,300,text='GAME OVER',anchor=NW,
                                    font="Century 18 normal bold",fill='white')
                    root.after(3000,PartieTerminee)
                return

def SpriteCollision(sprite,test_sprite,old_Coord):
    """Actions à accomplir lorsque 2 sprites sont entrés en contact."""
    
    global mode_Vitesse,nbr_balles_en_jeu,tab_sprites_mvt,tab_sprites_cibles,\
           nbr_briques_cassables,level_courant,pause,score,text_score,nbr_vie,\
           text_vie
    
    if sprite.nom == "balle":
        if test_sprite.nom == "raquette":
            sprite.caneva.tag_raise(test_sprite.image)
            if test_sprite.reaction == "colle":
                sprite.reaction = "stop"
                root.bind('<n>',Decolle)
                root.bind('<Button-1>',Decolle)
                sprite.coord_y = (test_sprite.coord_y - sprite.hauteur)
            else:
                sprite.SetPosition(old_Coord[0],\
                                    (test_sprite.coord_y - sprite.hauteur))
            #--- Quand la balle percute la raquette, un pourcentage est calculé
            #    entre le point d'impact et la longueur de la raquette.
            #    L'angle de renvoie de la balle equivaut à ce pourcentage d'un
            #    angle de 180 degrés                                        ---#
            pourcentage = (float(sprite.coord_x-\
                                 (test_sprite.coord_x-sprite.largeur)))\
                                 /test_sprite.largeur
            sprite.pourcentage = pourcentage
            if pourcentage < 0.1:
                pourcentage = 0.1
            elif pourcentage > 0.9:
                pourcentage = 0.9
            angle = radians(pourcentage * 180)
            sprite.angle = angle
            sprite.vitesse_X = -sprite.vitesse * cos(angle)
            sprite.vitesse_Y = -sprite.vitesse * sin(angle)
        elif test_sprite.nom == "brique" or \
             test_sprite.nom == "brique_Bonus" or\
             test_sprite.nom == "brique_incassable" :
            if sprite.reaction == "rebondi" or \
               (sprite.reaction == "traverse" and\
                test_sprite.nom == "brique_incassable"):
                # Impact à eu lieu : on remet le sprite entré en collision
                # à son ancienne position.
                sprite.SetPosition(old_Coord[0],old_Coord[1])
                # Pour toutes les briques percutées par la balle :
                # on cherche si l'impact à eu lieu:
                #   - soit de part le haut ou le bas : alors on inverse la
                #   composante en y de la vitesse de la balle, en lui
                #   ajoutant 0.1 pour éviter un cycle infini de rebonds 
                #   - ou soit de par la gauche ou la droite : alors on inverse
                #   la composante en x de la vitesse de la balle, en lui
                #   ajoutant 0.1 pour éviter un cycle infini de rebonds  
                if (sprite.coord_y+sprite.hauteur)-sprite.ecart_reduit <=\
                    test_sprite.coord_y+test_sprite.ecart_reduit or\
                    sprite.coord_y+sprite.ecart_reduit >=\
                    (test_sprite.coord_y + test_sprite.hauteur)-\
                    test_sprite.ecart_reduit:
                    
                    if sprite.vitesse_Y * test_sprite.vitesse_Y > 0:
                        sprite.vitesse_Y *= -1+(1.0/randrange(80,100))
                    else :
                        sprite.vitesse_Y *= -1+(1.0/randrange(80,100))
                        test_sprite.vitesse_Y *= -1
                    
                elif (sprite.coord_x+sprite.largeur)-sprite.ecart_reduit <=\
                     test_sprite.coord_x+test_sprite.ecart_reduit or\
                     sprite.coord_x+sprite.ecart_reduit >=\
                     (test_sprite.coord_x+test_sprite.largeur)-\
                     test_sprite.ecart_reduit:
              
                    if sprite.vitesse_X * test_sprite.vitesse_X > 0:
                        sprite.vitesse_X *= -1+(1.0/randrange(80,100))
                    else:
                        sprite.vitesse_X *= -1+(1.0/randrange(80,100))
                        test_sprite.vitesse_X *= -1

                if mode_Vitesse == "Lent":
                    sprite.SetVitesse(0.5)
                if mode_Vitesse == "Normal":
                    sprite.SetVitesse(1)
                if mode_Vitesse == "Rapide":
                    sprite.SetVitesse(1.5)                         

            elif sprite.reaction == "traverse":
                test_sprite.solidite = 1
            if test_sprite.nom != "brique_incassable":
                test_sprite.solidite -= 1
                if test_sprite.solidite == 2:
                    test_sprite.caneva.itemconfigure\
                        (test_sprite.image,image=image_brique2coups)
                    test_sprite.image_sprite = image_brique2coups
                elif test_sprite.solidite == 1:
                    test_sprite.caneva.itemconfigure\
                        (test_sprite.image,image=image_brique1coups)
                    test_sprite.image_sprite = image_brique1coups                                            
                elif test_sprite.solidite == 0:
                    score += 100
                    MajScore()
                    can.delete(test_sprite.image)
                    tab_sprites_cibles.remove(test_sprite)
                    if test_sprite.vitesse != 0:
                        tab_sprites_mvt.remove(test_sprite)
                    if test_sprite.nom == "brique_Bonus":
                        Bonus(test_sprite.coord_x,test_sprite.coord_y)
                    nbr_briques_cassables -= 1
                    if nbr_briques_cassables == 0:
                        level_courant += 1
                        if level_courant > len(tableaux_jeu):
                                root.unbind('p')
                                root.unbind('m')
                                pause = True                                                
                                can.create_text(120,300,
                                                text='Felicitations, serie de \
tableaux terminee !!',anchor=NW,font="Century 15 normal bold",fill='white')                                                
                                root.after(12000,PartieTerminee)
                        else:
                            CreationTableau()
                        return
    elif sprite.nom == "brique" or sprite.nom == "brique_Bonus" or \
         sprite.nom == "brique_incassable":
        if test_sprite.nom == "brique" or test_sprite.nom == "brique_Bonus" or\
           test_sprite.nom == "brique_incassable":
            sprite.SetPosition(old_Coord[0],old_Coord[1])
            if (sprite.coord_y+sprite.hauteur)-sprite.ecart_reduit <=\
                test_sprite.coord_y+test_sprite.ecart_reduit or\
                sprite.coord_y+sprite.ecart_reduit >=\
                (test_sprite.coord_y+test_sprite.hauteur)-\
                test_sprite.ecart_reduit:
                  sprite.vitesse_Y *= -1
                  test_sprite.vitesse_Y *= -1
            elif (sprite.coord_x+sprite.largeur)-sprite.ecart_reduit <=\
                 test_sprite.coord_x+test_sprite.ecart_reduit or\
                 sprite.coord_x+sprite.ecart_reduit >=\
                 (test_sprite.coord_x+test_sprite.largeur)-\
                 test_sprite.ecart_reduit:
                    sprite.vitesse_X *= -1
                    test_sprite.vitesse_X *= -1
        elif test_sprite.nom == "balle" :
            if test_sprite.reaction == "rebondi" or\
               (test_sprite.reaction == "traverse" and\
                sprite.nom == "brique_incassable"):
                sprite.SetPosition(old_Coord[0],old_Coord[1])
                if (sprite.coord_y+sprite.hauteur)-sprite.ecart_reduit <=\
                   test_sprite.coord_y+test_sprite.ecart_reduit\
                   or sprite.coord_y+sprite.ecart_reduit >=\
                   (test_sprite.coord_y + test_sprite.hauteur)-\
                   test_sprite.ecart_reduit:
                    if sprite.vitesse_Y * test_sprite.vitesse_Y > 0:
                        sprite.vitesse_Y *= -1
                    else :
                        test_sprite.vitesse_Y *= -1.01
                        sprite.vitesse_Y *= -1
                elif (sprite.coord_x+sprite.largeur)-sprite.ecart_reduit <=\
                     test_sprite.coord_x+test_sprite.ecart_reduit\
                     or sprite.coord_x+sprite.ecart_reduit >=\
                     (test_sprite.coord_x+test_sprite.largeur)-\
                     test_sprite.ecart_reduit:
                    if sprite.vitesse_X * test_sprite.vitesse_X > 0:
                        sprite.vitesse_X *= -1
                    else:
                        test_sprite.vitesse_X *= -1.01
                        sprite.vitesse_X *= -1
                if mode_Vitesse == "Lent":
                    test_sprite.SetVitesse(0.5)
                if mode_Vitesse == "Normal":
                    test_sprite.SetVitesse(1)
                if mode_Vitesse == "Rapide":
                    test_sprite.SetVitesse(1.5)                
            elif test_sprite.reaction == "traverse":
                sprite.solidite = 1
            if sprite.nom != "brique_incassable":
                sprite.solidite -= 1
                if sprite.solidite == 2:
                    sprite.caneva.itemconfigure(
                        sprite.image,image=image_brique2coups)
                    sprite.image_sprite = image_brique2coups
                elif sprite.solidite == 1:
                    sprite.caneva.itemconfigure(
                        sprite.image,image=image_brique1coups)
                    sprite.image_sprite = image_brique1coups                                            
                elif sprite.solidite == 0:
                    score += 100
                    MajScore()
                    can.delete(sprite.image)
                    tab_sprites_cibles.remove(sprite)
                    tab_sprites_mvt.remove(sprite)
                    if sprite.nom == "brique_Bonus":
                        Bonus(sprite.coord_x,sprite.coord_y)
                    nbr_briques_cassables -= 1
                    if nbr_briques_cassables == 0:
                        level_courant += 1
                        if level_courant > len(tableaux_jeu):
                                root.unbind('p')
                                root.unbind('m')
                                pause = True
                                can.create_text(120,300,
                                                text='Felicitations, serie de \
tableaux terminee !!',anchor=NW,font="Century 15 normal bold",fill='white')                                                
                                root.after(12000,PartieTerminee)
                        else:
                            CreationTableau()
                        return                            
    elif sprite.nom == "bonus":
        if test_sprite.nom == "raquette":
            BonusAttrape(test_sprite,sprite)
            return                                
    elif sprite.nom == "obus":
        if test_sprite.nom == "brique" or test_sprite.nom == "brique_Bonus" or\
           test_sprite.nom == "brique_incassable":
            if test_sprite.nom != "brique_incassable":
                test_sprite.solidite -= 1
                if test_sprite.solidite == 2:
                    test_sprite.caneva.itemconfigure(
                        test_sprite.image,image=image_brique2coups)
                    test_sprite.image_sprite = image_brique3coups
                elif test_sprite.solidite == 1:
                    test_sprite.caneva.itemconfigure(
                        test_sprite.image,image=image_brique1coups)
                    test_sprite.image_sprite = image_brique1coups     
                elif test_sprite.solidite == 0:
                    score += 100
                    MajScore()
                    can.delete(test_sprite.image)
                    tab_sprites_cibles.remove(test_sprite)
                    if test_sprite.nom == "brique_Bonus":
                        Bonus(test_sprite.coord_x,test_sprite.coord_y) 
                    nbr_briques_cassables -= 1
                    if nbr_briques_cassables == 0:
                            level_courant += 1
                            if level_courant > len(tableaux_jeu):
                                root.unbind('p')
                                root.unbind('m')                                                     
                                pause = True                                           
                                can.create_text(120,300,
                                                text="Felicitations, serie de \
tableaux terminee !!",anchor=NW,font="Century 15 normal bold",fill='white') 
                                root.after(12000,PartieTerminee)
                            else:
                                CreationTableau()
                            return
            can.delete(sprite.image)
            if sprite in tab_sprites_mvt:
                tab_sprites_mvt.remove(sprite)
            return

def DessineSprites():
    """Redessine tous les sprites en mouvement"""
    for sprite in tab_sprites_mvt:
        sprite.DessineSprite()

#---
def MajScore():
    """Mets a jour le texte score"""
    global score,text_score

    can.itemconfigure(text_score,text="SCORE : "+str(score))

#--- Partie terminee ou game over ---
def PartieTerminee():
    """Verifie si le score actuel fait parti des 5 premiers"""
    global pause,nom

    pause = True
    root.unbind('<Right>')
    root.unbind('<Left>')
    root.unbind('<KeyRelease-Right>')
    root.unbind('<KeyRelease-Left>')
    root.unbind('<Motion>')
    root.unbind('<n>')
    root.unbind('<Button-1>')
    if score > scores_et_tableaux[0][-1][1]:
        nom = ""
        ecart = 0
        MessageTop()
    else:
        root.after(3000,MenuPrincipal,'m')

def MessageTop():
    """Ecrit le texte ammenant l'utilisateur à ecrire son nom"""
    can.delete(ALL)
    can.create_image(319,329,image=fond)
    can.create_text(80,180,
                    text="Votre score fait parti du top 5 !\n\
(pour cette liste de tableau)",
                    anchor=NW,font="Century 15 normal bold",fill='white')
    can.create_text(80,240,text="Veuillez saisir votre nom (10 lettres max) :",
                    anchor=NW,font="Century 15 normal bold",fill='white')
    can.create_text(100,320,
                    text="Entrer = Valider         Fleche Gauche =\
Effacer Lettre",anchor=NW,font="Century 12 normal bold",fill='white')
    root.bind('<Key>',RecupNom)
    root.bind('<Return>',ValideNom)
    root.bind('<Left>',EffaceLettre)
        
    can.create_text(180,280,text=nom+"_",anchor=NW,
                    font="Century 15 normal bold",fill='white')

def EffaceLettre(event):
    """Efface une lettre de la variable nom"""
    global nom

    nom = nom[:-1]
    MessageTop()
    
def RecupNom(event):
    """Récupère la lettre tappée et l'ajoute à la variable 'nom'"""
    global nom

    c = event.char
    if len(nom) < 10:
        nom += c
    MessageTop()

def ValideNom(event):
    """Le nom est ajouté a la liste des scores.Celle-ci est triée par
        scores croissants.Le dernier score est retiré de la liste."""
    
    scores_et_tableaux[0].append((nom[:10],score))
    tab_score = scores_et_tableaux[0]
    tab_scores_range = sorted(tab_score, key=lambda tab_score: tab_score[1],
                              reverse=True)
    scores_et_tableaux[0] = tab_scores_range[:]
    del scores_et_tableaux[0][-1]
    fichier = open(nom_tableau,'w')
    pickle.dump(scores_et_tableaux,fichier)
    fichier.close
    root.unbind('<Key>')
    root.unbind('<Return>')
    root.unbind('<Left>')
    can.after(1000,OptionScores,'4')

#--- Mise a jour du jeu en fonction du Bonus attrape ---
def BonusAttrape(sprite1,sprite2):
    """Détermine l'action à exécuter lorsque la raquette attrape un Bonus."""
    global mode_Vitesse,nbr_balles_en_jeu,nbr_vie,score,text_Bonus,antiSpam

    if sprite2.option != "vie" and sprite2.option != "points":
        can.itemconfigure(text_Bonus,text=sprite2.option)
        
    # On récupère les coordonnées de la balle pour en créer 2 autres à
    # partir de celle-ci si le Bonus est 'multiball'
    for sprite in tab_sprites_mvt:
        if sprite.nom == "balle":
            coord_courante_boule = sprite.GetPosition()
            reaction = sprite.reaction
            image = sprite.image_sprite
            
    can.delete(sprite2.image)
    tab_sprites_mvt.remove(sprite2)
    #--------------------------
    if sprite2.option == "Missiles":
        if sprite1.image_sprite == image_raquetteGun:
            return
        EtatNormal(sprite1)
        antiSpam = 0
        root.bind('<n>',TirObus)
        root.bind('<Button-1>',TirObus)
        sprite1.caneva.itemconfigure(sprite1.image,image=image_raquetteGun)
        sprite1.image_sprite = image_raquetteGun
        sprite1.SetDimension()
    #--------------------------
    elif sprite2.option == "Petite Raquette":
        if sprite1.image_sprite == image_raquettePetite:
            return
        EtatNormal(sprite1)
        sprite1.caneva.itemconfigure(sprite1.image,image=image_raquettePetite)
        sprite1.image_sprite = image_raquettePetite
        sprite1.SetDimension()
    #--------------------------
    elif sprite2.option == "Raquette Normale":
        if sprite1.image_sprite == image_raquette:
            return
        root.unbind('<n>')
        root.unbind('<Button-1>')
        sprite1.reaction = "rebondi"
        mode_Vitesse = "Normal" 
        sprite1.caneva.itemconfigure(sprite1.image,image=image_raquette)
        sprite1.image_sprite = image_raquette
        sprite1.SetDimension()
    #--------------------------
    elif sprite2.option == "Grande Raquette":
        if sprite1.image_sprite == image_raquetteGrande:
            return
        EtatNormal(sprite1)
        sprite1.caneva.itemconfigure(sprite1.image,image=image_raquetteGrande)
        sprite1.image_sprite = image_raquetteGrande
        sprite1.SetDimension()
    #--------------------------
    elif sprite2.option == "Balle Lente":
        if mode_Vitesse == "Lent":
            return
        EtatNormal(sprite1)
        for i in tab_sprites_mvt:
            if i.nom == "balle":
                i.SetVitesse(0.5)
        mode_Vitesse = "Lent"                
    #--------------------------
    elif sprite2.option == "Balle Normale":
        for i in tab_sprites_mvt:
            if i.nom == "balle":
                i.SetVitesse(1)
                i.caneva.itemconfigure(i.image,image=image_balle)
                i.image_sprite = image_balle
                i.reaction = "rebondi"
        mode_Vitesse = "Normal"                
    #--------------------------
    elif sprite2.option == "Balle Rapide":
        if mode_Vitesse == "Rapide":
            return
        EtatNormal(sprite1)
        for i in tab_sprites_mvt:
            if i.nom == "balle":
                i.SetVitesse(1.5)
        mode_Vitesse = "Rapide"                
    #--------------------------
    elif sprite2.option == "Balle Tueuse":
        EtatNormal(sprite1)
        for i in tab_sprites_mvt:
            if i.nom == "balle":
                i.SetVitesse(1)
                i.reaction = "traverse"
                i.caneva.itemconfigure(i.image,image=image_balleTueuse)
                i.image_sprite = image_balleTueuse
    #--------------------------
    elif sprite2.option == "Multiball":
        if sprite1.reaction != "stop":
            EtatNormal(sprite1)
        tab_sprites_mvt.append(CreationBalle(coord_courante_boule[0],
                                              coord_courante_boule[1],60))
        nbr_balles_en_jeu += 1
        tab_sprites_mvt.append(CreationBalle(coord_courante_boule[0],
                                              coord_courante_boule[1],135))
        nbr_balles_en_jeu += 1
    #--------------------------
    elif sprite2.option == "Raquette Collante":
        if sprite1.reaction == "colle":
            return
        EtatNormal(sprite1)
        sprite1.reaction = "colle"
        root.bind('<n>',Decolle)
        root.bind('<Button-1>',Decolle)
        sprite1.caneva.itemconfigure(sprite1.image,image=image_raquetteCollante)
        sprite1.image_sprite = image_raquetteCollante
        sprite1.SetDimension()
    #--------------------------
    elif sprite2.option == "vie":
        nbr_vie += 1
        can.itemconfigure(text_vie,text=" X "+str(nbr_vie))
    #--------------------------
    elif sprite2.option == "points":
        score += 50
        MajScore()

def EtatNormal(sprite):
    """Quand un Bonus est attrapé par la raquette, celle-ci et la/les balles
        passe par leur etat initial."""
    global mode_Vitesse
    
    root.unbind('<n>')
    root.unbind('<Button-1>')
    sprite.reaction = "rebondi"
    mode_Vitesse = "Normal" 
    sprite.caneva.itemconfigure(sprite.image,image=image_raquette)
    sprite.image_sprite = image_raquette
    sprite.SetDimension()
    for i in tab_sprites_mvt:
        if i.nom == "balle":
            i.SetVitesse(1)
            i.caneva.itemconfigure(i.image,image=image_balle)
            i.image_sprite = image_balle
            i.reaction = "rebondi"

def Decolle(event):
    """Décolle la balle de la raquette."""
    for i in tab_sprites_mvt:
        if i.nom == "balle":
            if i.reaction == "stop":
                i.reaction = "rebondi"
                
    root.unbind('<n>')
    root.unbind('<Button-1>')

#--- Apparition d'un Bonus dans le jeu ---                
def Bonus(x,y):
    """Création d'un sprite 'Bonus' aux coordonnées de la brique dans laquelle
        il etait "contenu"."""
    
    hazard = randrange(0,len(tab_Bonus))
    bonus = Sprite(tab_Bonus[hazard][1],can)
    bonus.option = tab_Bonus[hazard][0]
    bonus.SetPosition(x,y)
    bonus.reaction = ""
    bonus.nom = "bonus"
    bonus.reaction_bord_bas = "destruction"
    bonus.vitesse_Y = 4
    bonus.Place()
    tab_sprites_mvt.append(bonus)
    bonus.cibles.append(raquette)

def CreationBalle(x,y,angle):
    """Création d'un sprite 'balle'."""
    global mode_Vitesse,balle
    
    balle = Sprite(image_balle,can)
    balle.nom = "balle"
    balle.SetPosition(x,y)
    balle.vitesse = 10
    balle.vit_base = 10
    balle.vitesse_X = balle.vitesse*cos(radians(angle))
    balle.vitesse_Y = -balle.vitesse*sin(radians(angle))
    if mode_Vitesse == "Normal":
        balle.SetVitesse(1)
    elif mode_Vitesse == "Lent":
        balle.SetVitesse(0.5)
    elif mode_Vitesse == "Rapide":
        balle.SetVitesse(1.5)
    balle.ecart_reduit = 4
    balle.reaction = "rebondi"
    balle.reaction_bord_droit = "rebond"
    balle.reaction_bord_gauche = "rebond"
    balle.reaction_bord_haut = "rebond"
    balle.reaction_bord_bas = "destruction"
    balle.Place()
    for sprite in tab_sprites_mvt:
        if sprite.option == "mvt horizontal" or sprite.option == "mvt vertical" :
            sprite.cibles.append(balle)
    return balle

def NouvelleBalle():
    """Apparition d'une balle sur la raquette
        (nouveau tableau ou balle perdue)."""
    global nbr_balles_en_jeu

    for sprite in tab_sprites_mvt:
        if sprite.nom == "Bonus":
            can.delete(sprite.image)
            tab_sprites_mvt.remove(sprite)
    EtatNormal(raquette)
    balle = CreationBalle(-60,628,60)
    balle.reaction = "stop"
    tab_sprites_mvt.append(balle)
    tab_sprites_cibles.append(balle)
    nbr_balles_en_jeu = 1
    root.bind('<Button-1>',Decolle)
    root.bind('<n>',Decolle)

def CreationTableau():
    """Création d'un tableau en fonction du level"""
    global raquette,nbr_briques_cassables,tableaux_jeu,level_courant,mode_Vitesse,\
            tab_sprites_mvt,tab_sprites_cibles,score,text_score,nbr_vie,\
            text_vie,text_Bonus,pause

    can.delete(ALL)
    can.create_image(319,329,image=fond)
    text_score = can.create_text(10,5,text="SCORE : "+str(score),anchor=NW,
                                 font="Century 10 normal bold",fill='white')
    can.create_text(200,5,text="Menu : M",anchor=NW,
                    font="Century 10 normal bold",fill='white')    
    can.create_text(350,5,text="Pause : P",anchor=NW,
                    font="Century 10 normal bold",fill='white')
    
    can.create_image(550,8,anchor=NW,image=image_raquetteVie)
    text_vie = can.create_text(590,5,text=" X "+str(nbr_vie),anchor=NW,
                               font="Century 10 normal bold",fill='white')
    can.create_text(10,640,text="ASTRE 2.0",anchor=NW,
                    font="Century 10 normal bold",fill='white')
    text_Bonus = can.create_text(638,640,text="",anchor=NE,
                                 font="Century 10 normal bold",fill='white')
    
    tab_sprites_mvt = []
    tab_sprites_cibles = []
    raquette = Sprite(image_raquette,can)
    raquette.nom = "raquette"
    raquette.ecart_reduit = 2
    raquette.SetPosition(260,638)
    raquette.Place()
    root.bind('<Right>',raquette.ToucheDroite)
    root.bind('<Left>',raquette.ToucheGauche)
    root.bind('<KeyRelease-Right>',raquette.ToucheDroiteRelache)
    root.bind('<KeyRelease-Left>',raquette.ToucheGaucheRelache)
    root.bind('<Motion>',raquette.Souris)
    raquette.souris_deplacement_vertical = False
    tab_sprites_cibles.append(raquette)
    tab_sprites_mvt.append(raquette)
    nbr_briques_cassables = 0
    ecart_x = 0
    ecart_y = 0
   
    for ligne in tableaux_jeu[level_courant-1]:
        for valeur_colonne in ligne:
            if valeur_colonne == []:
                ecart_x += 32
                continue
            if valeur_colonne[0] == 1:
                hazard = randrange(1,len(tab_Bonus))
                brique = Sprite(image_brique1coups,can)
                brique.SetPosition(ecart_x,ecart_y)
                brique.ecart_reduit = 0
                if hazard == 1:
                    brique.nom = "brique_Bonus"
                else:
                    brique.nom = "brique"
                brique.reaction = "rebondi"
                brique.solidite = 1
                tab_sprites_cibles.append(brique)
                nbr_briques_cassables += 1
                if valeur_colonne[1] == 'horizontal':
                    brique.option = "mvt horizontal"
                    brique.vitesse_X = 4
                    brique.vitesse = 4
                    brique.reaction_bord_droit = "rebond"
                    brique.reaction_bord_gauche = "rebond"
                    tab_sprites_mvt.append(brique)
                if valeur_colonne[1] == 'vertical':
                    brique.option = "mvt vertical"
                    brique.vitesse_Y = -4
                    brique.vitesse = -4
                    brique.rebord_bas -= 100
                    brique.reaction_bord_haut = "rebond"
                    brique.reaction_bord_bas = "rebond"
                    tab_sprites_mvt.append(brique)                
                brique.Place()
            elif valeur_colonne[0] == 2:
                hazard = randrange(1,len(tab_Bonus))
                brique = Sprite(image_brique2coups,can)
                brique.SetPosition(ecart_x,ecart_y)
                brique.ecart_reduit = 0
                if hazard == 1:
                    brique.nom ="brique_Bonus"
                else:
                    brique.nom = "brique"
                brique.reaction = "rebondi"
                brique.solidite = 2
                tab_sprites_cibles.append(brique)
                nbr_briques_cassables += 1
                if valeur_colonne[1] == 'horizontal':
                    brique.option = "mvt horizontal"
                    brique.vitesse_X = 4
                    brique.vitesse = 4
                    brique.reaction_bord_droit = "rebond"
                    brique.reaction_bord_gauche = "rebond"
                    tab_sprites_mvt.append(brique)
                if valeur_colonne[1] == 'vertical':
                    brique.option = "mvt vertical"
                    brique.vitesse_Y = -4
                    brique.vitesse = -4
                    brique.rebord_bas -= 100
                    brique.reaction_bord_haut = "rebond"
                    brique.reaction_bord_bas = "rebond"
                    tab_sprites_mvt.append(brique)
                brique.Place()
            elif valeur_colonne[0] == 3:
                hazard = randrange(1,len(tab_Bonus))
                brique = Sprite(image_brique3coups,can)
                brique.SetPosition(ecart_x,ecart_y)
                brique.ecart_reduit = 0
                if hazard == 1:
                    brique.nom ="brique_Bonus"
                else:
                    brique.nom = "brique"
                brique.reaction = "rebondi"
                brique.solidite = 3
                tab_sprites_cibles.append(brique)
                nbr_briques_cassables += 1
                if valeur_colonne[1] == 'horizontal':
                    brique.option = "mvt horizontal"
                    brique.vitesse_X = 4
                    brique.vitesse = 4
                    brique.reaction_bord_droit = "rebond"
                    brique.reaction_bord_gauche = "rebond"
                    tab_sprites_mvt.append(brique)
                if valeur_colonne[1] == 'vertical':
                    brique.option = "mvt vertical"
                    brique.vitesse_Y = -4
                    brique.vitesse = -4
                    brique.rebord_bas -= 100
                    brique.reaction_bord_haut = "rebond"
                    brique.reaction_bord_bas = "rebond"
                    tab_sprites_mvt.append(brique)
                brique.Place()
            elif valeur_colonne[0] == 0:
                brique = Sprite(image_briqueIncassable,can)
                brique.SetPosition(ecart_x,ecart_y)
                brique.ecart_reduit = 0
                brique.nom = "brique_incassable"
                brique.reaction = "rebondi"
                tab_sprites_cibles.append(brique)
                if valeur_colonne[1] == 'horizontal':
                    brique.option = "mvt horizontal"
                    brique.vitesse_X = 4
                    brique.vitesse = 4
                    brique.reaction_bord_droit = "rebond"
                    brique.reaction_bord_gauche = "rebond"
                    tab_sprites_mvt.append(brique)
                if valeur_colonne[1] == 'vertical':
                    brique.option = "mvt vertical"
                    brique.vitesse_Y = -4
                    brique.vitesse = -4
                    brique.rebord_bas -= 100
                    brique.reaction_bord_haut = "rebond"
                    brique.reaction_bord_bas = "rebond"
                    tab_sprites_mvt.append(brique)
                brique.Place()
            ecart_x += 32
        ecart_x = 0
        ecart_y +=22
    NouvelleBalle() 
    pause = False

def TirObus(event):
    """Création d'un sprite 'obus'."""
    global antiSpam

    if (antiSpam%2) == 0:
        obus = Sprite(image_obus,can)
        obus.nom = "obus"
        obus.coord_x = raquette.coord_x + (raquette.largeur/2) - (obus.largeur/2)
        obus.coord_y = raquette.coord_y - obus.hauteur
        obus.ecart_reduit = 0
        obus.vitesse_Y = -8
        obus.reaction_bord_haut = "destruction"
        tab_sprites_mvt.append(obus)
        obus.Place()
    antiSpam += 1    

def Chargement(nom_fichier):
    """Chargement du fichier contenant une serie de tableaux et
        les scores correspondants à cette série."""
    global tableaux_jeu,scores_et_tableaux,nom_tableau

    nom_tableau = nom_fichier
    fichier = open(nom_fichier,'r')
    scores_et_tableaux = pickle.load(fichier)
    tableaux_jeu = scores_et_tableaux[1]
    fichier.close
    NouvellePartie()
    
def TableauxDeBase(event):
    """Transmet la série de tableaux de base(touche 1)"""
    
    Chargement("tableau.cb")

def TableauxPersonnels(event):
    """Ouverture d'une fenêtre de dialogue contenant toutes les
        séries de taleaux.(touche 3)"""
     
    chemin_fichier = tkFileDialog.askopenfilename(
                        filetypes = [("Liste de Tableaux","*.cb")])
    (filepath, nom_fichier) = os.path.split(chemin_fichier)
    if nom_fichier != "":
        Chargement(nom_fichier)

def MiseEnPause(event):
    """Mise en pause du gestionnaire de sprite."""
    global pause,text_pause

    if not pause:
        pause = True
        root.unbind('<Right>')
        root.unbind('<Left>')
        root.unbind('<KeyRelease-Right>')
        root.unbind('<KeyRelease-Left>')
        root.unbind('<Motion>')
        text_pause = can.create_text(280,300,text='PAUSE',anchor=NW,
                                     font="Century 18 normal bold",fill='white')
    else:
        pause = False
        GestionnaireDeSprites()
        root.bind('<Right>',raquette.ToucheDroite)
        root.bind('<Left>',raquette.ToucheGauche)
        root.bind('<KeyRelease-Right>',raquette.ToucheDroiteRelache)
        root.bind('<KeyRelease-Left>',raquette.ToucheGaucheRelache)
        root.bind('<Motion>',raquette.Souris)
        can.delete(text_pause)

def Initialisation():
    """Initialisation des variables images et sons."""
    global can,fond,tableaux_jeu,image_brique1coups,image_brique2coups,\
           image_brique3coups,image_balle,image_balleTueuse,image_raquette,\
           image_raquetteGrande,image_raquettePetite,image_raquetteCollante,\
           image_raquetteGun,image_Bonus,image_obus,tab_Bonus,\
           image_briqueIncassable,tab_sprites_mvt,tab_sprites_cibles,\
           image_effaceBrique,pause,score,text_score,image_raquetteVie,\
           image_BonusVie,nom_tableau

    can = Canvas(root,bg='black',width=638,height=658)
    can.pack()
    ressource_images = images()
    fond = ressource_images[0]
    image_raquetteVie = ressource_images[1]
    image_effaceBrique = ressource_images[2]  
    image_brique1coups = ressource_images[3]
    image_brique2coups = ressource_images[4]
    image_brique3coups = ressource_images[5]  
    image_briqueIncassable = ressource_images[6]
    image_balle = ressource_images[7]
    image_balleTueuse = ressource_images[8]
    image_raquette = ressource_images[9]
    image_raquetteGrande = ressource_images[10]
    image_raquettePetite = ressource_images[11]
    image_raquetteCollante = ressource_images[12]
    image_raquetteGun = ressource_images[13]
    image_BonusVie = ressource_images[14]
    image_BonusColle = ressource_images[15]
    image_BonusGun = ressource_images[16]
    image_BonusMultiball = ressource_images[17]
    image_BonusBallelente = ressource_images[18]
    image_BonusBallerapide = ressource_images[19]
    image_BonusBalleNormale = ressource_images[20]
    image_BonusRaquetteGrande = ressource_images[21]
    image_BonusRaquettePetite = ressource_images[22]
    image_BonusRaquetteNormale = ressource_images[23]
    image_BonusBalleTueuse = ressource_images[24]
    image_BonusPoints = ressource_images[25]
    image_obus = ressource_images[26]

    tab_Bonus = [("Missiles",image_BonusGun),
                 ("Petite Raquette",image_BonusRaquettePetite),
                 ("Raquette Normale",image_BonusRaquetteNormale),
                 ("Grande Raquette",image_BonusRaquetteGrande),
                 ("Balle Lente",image_BonusBallelente),
                 ("Balle Normale",image_BonusBalleNormale),
                 ("Balle Rapide",image_BonusBallerapide),
                 ("Balle Tueuse",image_BonusBalleTueuse),
                 ("Multiball",image_BonusMultiball),
                 ("Raquette Collante",image_BonusColle),
                 ("vie",image_BonusVie),
                 ("points",image_BonusPoints)]

    tab_sprites_mvt = []
    tab_sprites_cibles = []
    pause = False

    try:
        nom_fichier = "tableau"
        fichier = open(nom_fichier,'r')
        tableaux_jeu = pickle.load(fichier)
        fichier.close
    except:
        pass
    nom_tableau = "tableau.cb"
    MenuPrincipal('m')

def MenuPrincipal(event):
    """Création de l'interface de menu."""
    global tab_sprites_mvt,pause,nom_tableau,fond,pause

    pause = True
    root.unbind('<Key>')
    root.unbind('<Return>')
    root.unbind('<Button-1>')
    root.unbind("<Button1-Motion>")
    root.unbind('<Right>')
    root.unbind('<Left>')
    root.unbind('7')
    root.unbind('8')
    root.unbind('1')
    root.unbind('2')
    root.unbind('3')
    root.unbind('4')
    root.unbind('s')
    root.unbind('0')
    root.unbind('g')
    root.unbind('c')
    root.unbind('+')
    root.unbind('-')
    root.unbind('h')
    root.unbind('v')
    root.unbind('f')
    tab_sprites_mvt = []
    can.delete(ALL)
    can.create_image(319,329,image=fond)
    can.create_text(180,200,text="A S T R E 2.0",anchor=NW,
                    font="Century 28 normal bold",fill='white')
    can.create_text(180,250,text="1 - Nouvelle Partie",anchor=NW,
                    font="Century 18 normal bold",fill='white')
    can.create_text(180,280,text="2 - Mode Edition",anchor=NW,
                    font="Century 18 normal bold",fill='white')
    can.create_text(180,310,text="3 - Charger Des Tableaux",anchor=NW,
                    font="Century 18 normal bold",fill='white')
    can.create_text(180,340,text="4 - Scores",anchor=NW,
                    font="Century 18 normal bold",fill='white')
    can.create_text(180,370,text="5 - Quitter",anchor=NW,
                    font="Century 18 normal bold",fill='white')
    can.create_text(440,640,text="Auteur - Guillaume Michon",anchor=NW,
                    font="Century 10 normal bold",fill='white')
    root.bind('1',TableauxDeBase)
    root.bind('2',OptionEdition)
    root.bind('3',TableauxPersonnels)
    root.bind('4',OptionScores)
    root.bind('5',Quitter)

def OptionScores(event):
    """Invoque la fonction principale du module gestion des scores."""
    root.bind('<m>',MenuPrincipal)
    scores(root,can,fond,nom_tableau)

def OptionEdition(event):
    """Invoque la fonction principale du module edition."""    
    root.bind('<m>',MenuPrincipal)
    edition(root,can)

def NouvellePartie():
    """Initialisation de quelques variables avant chaques nouvelles
        parties."""
    global level_courant,score,nbr_vie

    root.unbind('1')
    root.unbind('2')
    root.unbind('3')
    root.unbind('4')
    root.unbind('5')
    root.bind('<m>',MenuPrincipal)
    root.bind('<p>',MiseEnPause)
    level_courant = 1
    score = 0
    nbr_vie = 3
    CreationTableau()
    GestionnaireDeSprites()

def Quitter(event):
    """Quitte l'application."""
    root.destroy()

if __name__ == '__main__':
    root = Tk()
    root.title("Astre 2.0")
    root.iconbitmap("Fond2.ico")
    root.resizable(0,0)
    hauteur = root.winfo_height()
    largeur = root.winfo_width()
    root.winfo_screenwidth()
    pos_x = str(((root.winfo_screenwidth()-largeur)/2)-300)
    pos_y = str(((root.winfo_screenheight()-hauteur)/2)-300)
    pos = '+' + pos_x + '+' + pos_y
    root.geometry(pos)
    Initialisation()
    root.mainloop()

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.