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()
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.