Casse brique

Soyez le premier à donner votre avis sur cette source.

Vue 18 647 fois - Téléchargée 2 041 fois

Description

Petit jeu de casse brique, que j'ai fait moi même, pour m'entrainer.
Je mettrais une capture plus tard

Possibilité de se déplacer grâce au clavier ou à la souris
Entrée/Clic Gauche pour lancer une balle.
P pour mettre en pause

Source / Exemple :


# -*- coding: cp1252 -*-
#
#
###############################################
#################  Elnabo   ###################
###########  Casse Brique v1.5  ###############
###############################################
#############  Date de création  ##############
######### Du 02/07/10 au 07/07/10  ############
###############################################
#
#
from Tkinter import *
from random import randrange
from math import cos,pi,sin

class Principale(Tk):
    def __init__(self,parent,vie=5):
        
        Tk.__init__(self,parent)
        
        #Initialisation des paramètres
        
        self.parent = parent    
        self.flag = 0 #Variable permettant d'empêcher/autoriser, la lancement de la balle
        self.vie = [] 
        self.score = 0

        #On crée une liste contenant autant d'élement que de vie
        
        for i in range(0,vie):
            self.vie.append('')

        #On crée un canevas
            
        can = self.can = Canvas(width=490, height = 500,bg='black')
        can.focus()
        
        #Initialisation des commandes
        can.bind_all('<Key>', self.move)
        can.bind_all('<Return>',self.starter)
        can.bind('<Motion>',self.souris)
        can.bind('<Button-1>', self.starter)
        can.bind_all('p',self.pause)

    
        can.create_rectangle(0,470,492,502,fill='light grey') #Pour les vies et le score

        can.create_text(415,480,text='Score: ')
        self.tscore =  can.create_text(460,480,text='0')

        #On crée les balles représentatives des vies
        for i in range(0,vie):
            self.vie[i] = can.create_oval((25*vie)-(25*i),493,(25*vie)-10-(25*i),483,fill='red')

        #On initialise d'autres paramètres
        self.pose = 0 #Pause On/Off
        self.angle = pi/3 #Angle de rebond de la balle
        self.sens = -1 #Sens Haut/Bas de la balle
        self.horizon = 1 #Sens Gauche/Droite de la balle
        
        a = self.lbrique=[] #Liste comportant les briques (pour les supprimers)
        self.l = [] #Coordonnées (tuple) des briques

        coul=['green','yellow','light blue','red','orange'] #Différentes couleurs des briques
        i = 1 #Permet de définir: Résistance des briques/Couleur des briques
        x = 12 #Coordonnées en Abscisses
        y = 40 #Coordonnées en Ordonnées
        
        #On crée les 110 briques du jeu
        
        while x<470:
            a.append([can.create_rectangle(x,y,x+40,y+10,fill=coul[i]),(i%4)+1])
            self.l.append((x,y))
            y+=12
            i+=1
            i = i%5
            # i est la résistance de la brique. Si ((i%4)+1) = 3, il faudra taper 3fois la brique
            if y==160:
                x+=43
                y = 40
                
        #Creation de la balle
        self.boule = self.can.create_oval(250,450,260,460,fill='red')                            
        self.coord = [250,450]

        #Creation de la barre(pour les rebonds)
        self.barre = can.create_rectangle(235,460,275,465,fill='light green')
        self.bar = 235

        can.pack()

    def starter(self,event): #Fonction qui démarre les balles
        if self.flag == 0 and len(self.vie)!=0: 
            self.go()
            self.flag = 1

    def pause(self,event): #Fonction qui met en pause le jeu
        self.pose+=1
        self.pose = self.pose%2
        if self.pose==0:
            self.go()
            self.can.delete(self.text)
        else:
            self.text = self.can.create_text(250,250,text='PAUSE',fill='white')

    def souris(self,event): #Permet de déplacer la barre avec la Souris
        self.bar = a = event.x
        if 5 < a < 455 and self.pose==0:
            self.can.coords(self.barre,a,460,a+40,465)
    
    def move(self,event): #Permet de déplacer la barre avec le Clavier
        a = event.keysym
        if a == 'Left':
            self.direction = -7
        if a == 'Right':
            self.direction = 7

        if a!='Return' and a!='':
            a = self.bar = self.bar+self.direction
            if 5 < a < 455 and self.pose == 0:
                self.can.coords(self.barre,a,460,a+40,465)
            else:
                self.bar-=self.direction
        
    def go(self): #Fonction principale, déplace la balle

        stop = 0

        #On modifie les coordonnées de la balle en fonction des précedentes
        x = self.coord[0]
        y = self.coord[1]
        y += sin(self.angle)*self.sens*5
        x += (cos(self.angle))*self.horizon
        
        self.coord[1]=y
        self.coord[0]=x
        self.can.coords(self.boule,x,y,x+10,y+10)
        #
        
        i = 0
        while i<len(self.l):  #Pour chaque brique
            #On vérifie si elles sont en contact avec la balle
            if self.l[i][1]-2 <= y <= self.l[i][1]+12 and self.l[i][0]-2 <= x <= self.l[i][0]+42:
                #Si oui on change de direction
                self.sens = (-1)*self.sens
                self.lbrique[i][1] += -1
                if self.lbrique[i][1] == 0: #Si la brique ne peut plus tenir
                    #On la détruit et on augmente le score
                    self.can.delete(self.lbrique[i][0])
                    self.score+= 20*(len(self.vie))
                    
                    texte = str(self.score)
                    self.can.delete(self.tscore)
                    self.tscore = self.can.create_text(460,480,text=texte)
                    
                    del self.lbrique[i]
                    del self.l[i]
                    if len(self.l)==0:
                    #Si il n'y a plus de brique on arrête la balle
                        stop = 1
                break
            i+=1

        #Si la balle tape la barre
        if 460 <= y <= 465 and self.bar-10 < x < self.bar+47:
            #Si c'est sur le coin gauche, un angle plus grand
            if self.bar-10 <= x <= self.bar+5:
                self.angle = 2*pi/3
                self.horizon = 5

            #Si c'est sur le coin droit, un angle plus petit
            if self.bar+37 <= x <= self.bar+47:
                self.angle = pi/5
                self.horizon = 5

            #Sinon l'angle sera dans l'autre sens
            if self.bar+5 < x < self.bar+40:
                self.angle = pi/3

            self.sens = (-1)*self.sens

                
        if x<10 or x>478:  #Si on tape sur le bord gauche/droit
            self.horizon = (-1)*self.horizon
            
        if y<10: #Si on tape le plafond
            self.sens = (-1)*self.sens

        if y>466 and x>self.bar+47 or y>466 and x<self.bar-10:
            #Si on tombe à coté de la barre, on perd une vie
            self.can.delete(self.vie[0])
            del self.vie[0]
            stop = 1
            
        if stop == 1: #Si on a perdu une balle,ou gagné, on remet la balle à sa place
            self.flag=0
            self.sens = (-1)*self.sens
            self.can.coords(self.boule,250,440,260,430)
            self.can.coords(self.barre,235,460,275,465)
            self.bar = 235
            self.coord=[250,440]

        if len(self.vie)==0: #Si on a plus de vie, on écrit 'perdu'#
            self.can.create_text(250,250,text='PERDU',fill='white')    
        
        if stop ==0 and self.pose==0: #Si on a pas perdu la balle, on recommence
            self.can.after(2,self.go)

            

app = Principale(None) ###On lance l'application
app.mainloop()

Conclusion :


Bon normalement, il n'y a pas de bug et tout est expliqué en commentaire.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

elnabo
Messages postés
28
Date d'inscription
vendredi 7 août 2009
Statut
Membre
Dernière intervention
2 mai 2016
-
Damn, 9 personnes ont téléchargés. Pourrais-je avoir des commentaires svp?
prog94
Messages postés
10
Date d'inscription
jeudi 23 mars 2006
Statut
Membre
Dernière intervention
9 janvier 2009
-
Salut elnabo,
j'ai regardé ton code et j'ai fais quelques modifications que voici :
- j'ai créé deux nouvelles classes permettant de gérer les balles et les briques, avec pour chacune un constructeur prenant en argument commun aux deux classes une référence au canevas, une position et une taille et deux méthodes : set_position et move.
- j'ai virer le remplissage inutile de ta variable self.vie avec des chaînes vides.
- j'ai eu l'impression que tu avais créé une variable can juste pour ne pas écrire à chaque fois self.can donc j'ai remplacé ça aussi ;)
- tes briques tiennent maintenant dans un seul tableau self.lbrique, on accède au coordonnées grâce aux attributs de la classe Brique
- j'ai remplacer ton tableau de couleurs par un tuple de couleurs, comme tu ne va pas le modifier de toute façon ...
- plus besoin de la variable self.coord, les coordonnées de la boule sont dans son instance
- la barre est maintenant une instance de la classe Brique, plus besoin de self.bar
- j'ai viré la variable intermédiaire a dans la méthode souris
- dans la méthode go(), j'ai remplacer tes premières lignes par un appel à la méthode move de l'instance self.boule, j'ai virer le while pour y mettre un for avec un enumerate me permettant d'itérer sur chacune des briques et de pouvoir la supprimer du tableau self.lbrique grâce à son index.
- le fait de supprimer et de recréé le texte du score était assez moche, la méthode itemconfig du canvas permet de modifier un item du canevas sans avoir à le supprimer et recréé
- j'ai modifier la hauteur de test pour voir si la balle touche la barre pour enlever l'effet "passe au travers"
- enfin chez moi le jeu était vraiment trop rapide j'ai donc changer la vitesse de rafraîchissement du canevas de 2 à 20 pour faire mes tests.

Voici le code source modifié :

from Tkinter import *
from random import randrange
from math import cos,pi,sin

class Brique:

def __init__(self, boss, x, y, width, height, resistance, color):
self.boss = boss;
self.x = x;
self.y = y;
self.width = width;
self.height = height;
self.resistance = resistance;
self._id = boss.create_rectangle(x, y, x + width, y + height, fill=color);

def set_position(self, x, y):
self.x = x;
self.y = y;
self.boss.coords(self._id, x, y, x + self.width, y + self.height);

def move(self, x, y):
self.x += x;
self.y += y;
self.boss.coords(self._id, x, y, x + self.width, y + self.height);

def delete(self):
self.boss.delete(self._id);

class Ball:

def __init__(self, boss, x, y, size):
self.boss = boss;
self.x = x;
self.y = y;
self.size = size;
self._id = boss.create_oval(x, y, x + size, y + size, fill='red');

def set_position(self, x, y):
self.x = x;
self.y = y;
self.boss.coords(self._id, x, y, x + self.size, y + self.size);

def move(self, x, y):
self.x += x;
self.y += y;
self.boss.coords(self._id, self.x, self.y, self.x + self.size, self.y + self.size);

class Principale(Tk):
def __init__(self,parent,vie=5):

Tk.__init__(self,parent)

#Initialisation des paramètres

self.parent = parent
self.flag = 0 #Variable permettant d'empêcher/autoriser, la lancement de la balle
self.vie = []
self.score = 0

#On crée un canevas

self.can = Canvas(width=490, height = 500,bg='black')
self.can.focus()

#Initialisation des commandes
self.can.bind_all('<Key>', self.move)
self.can.bind_all('<Return>',self.starter)
self.can.bind('<Motion>',self.souris)
self.can.bind('', self.starter)
self.can.bind_all('p',self.pause)

self.can.create_rectangle(0,470,492,502,fill='light grey') #Pour les vies et le score

self.can.create_text(415,480,text='Score: ')
self.tscore = self.can.create_text(460,480,text='0')

#On crée les balles représentatives des vies
for i in range(0, 5):
self.vie.append(Ball(self.can, (25*vie)-(25*i), 493, -10));

#On initialise d'autres paramètres
self.pose = 0 #Pause On/Off
self.angle = pi/3 #Angle de rebond de la balle
self.sens = -1 #Sens Haut/Bas de la balle
self.horizon = 1 #Sens Gauche/Droite de la ballefrom Tkinter import *
from random import randrange
from math import cos,pi,sin

class Brique:

def __init__(self, boss, x, y, width, height, resistance, color):
self.boss = boss;
self.x = x;
self.y = y;
self.width = width;
self.height = height;
self.resistance = resistance;
self._id = boss.create_rectangle(x, y, x + width, y + height, fill=color);

def set_position(self, x, y):
self.x = x;
self.y = y;
self.boss.coords(self._id, x, y, x + self.width, y + self.height);

def move(self, x, y):
self.x += x;
self.y += y;
self.boss.coords(self._id, x, y, x + self.width, y + self.height);

def delete(self):
self.boss.delete(self._id);

class Ball:

def __init__(self, boss, x, y, size):
self.boss = boss;
self.x = x;
self.y = y;
self.size = size;
self._id = boss.create_oval(x, y, x + size, y + size, fill='red');

def set_position(self, x, y):
self.x = x;
self.y = y;
self.boss.coords(self._id, x, y, x + self.size, y + self.size);

def move(self, x, y):
self.x += x;
self.y += y;
self.boss.coords(self._id, self.x, self.y, self.x + self.size, self.y + self.size);

class Principale(Tk):
def __init__(self,parent,vie=5):

Tk.__init__(self,parent)

#Initialisation des paramètres

self.parent = parent
self.flag = 0 #Variable permettant d'empêcher/autoriser, la lancement de la balle
self.vie = []
self.score = 0

#On crée un canevas

self.can = Canvas(width=490, height = 500,bg='black')
self.can.focus()

#Initialisation des commandes
self.can.bind_all('<Key>', self.move)
self.can.bind_all('<Return>',self.starter)
self.can.bind('<Motion>',self.souris)
self.can.bind('', self.starter)
self.can.bind_all('p',self.pause)

self.can.create_rectangle(0,470,492,502,fill='light grey') #Pour les vies et le score

self.can.create_text(415,480,text='Score: ')
self.tscore = self.can.create_text(460,480,text='0')

#On crée les balles représentatives des vies
for i in range(0, 5):
self.vie.append(Ball(self.can, (25*vie)-(25*i), 493, -10));

#On initialise d'autres paramètres
self.pose = 0 #Pause On/Off
self.angle = pi/3 #Angle de rebond de la balle
self.sens = -1 #Sens Haut/Bas de la balle
self.horizon = 1 #Sens Gauche/Droite de la balle
self.lbrique = [] #Liste comportant les briques (pour les supprimers)

coul=('green','yellow','light blue','red','orange') #Différentes couleurs des briques
i = 1 #Permet de définir: Résistance des briques/Couleur des briques
x = 12 #Coordonnées en Abscisses
y = 40 #Coordonnées en Ordonnées

#On crée les 110 briques du jeu

while x<470:
self.lbrique.append(Brique(self.can, x, y, 40, 10, (i % 4) + 1, coul[i]));
y+=12
i = (i + 1) % 5
# i est la résistance de la brique. Si ((i%4)+1) = 3, il faudra taper 3fois la brique
if y==160:
x+=43
y = 40

#Creation de la balle
self.boule = Ball(self.can, 250, 450, 10);

#Creation de la barre(pour les rebonds)
self.barre = Brique(self.can, 235, 460, 40, 5, 0, 'light green')

self.can.pack()

def starter(self,event): #Fonction qui démarre les balles
if self.flag == 0 and len(self.vie)!=0:
self.go()
self.flag = 1

def pause(self,event): #Fonction qui met en pause le jeu
self.pose+=1
self.pose = self.pose%2
if self.pose==0:
self.go()
self.can.delete(self.text)
else:
self.text = self.can.create_text(250,250,text='PAUSE',fill='white')

def souris(self,event): #Permet de déplacer la barre avec la Souris
if 5 < event.x < 455 and not self.pose:
self.barre.set_position(event.x, 460);

def move(self,event): #Permet de déplacer la barre avec le Clavier
a = event.keysym
if a == 'Left':
self.direction = -7
if a == 'Right':
self.direction = 7

if a!='Return' and a!='':
a = self.barre.x + self.direction;
if 5 < a < 455 and self.pose == 0:
self.barre.set_position(a, 460);
else:
self.barre.x -= self.direction;

def go(self): #Fonction principale, déplace la balle

stop = 0

#On modifie les coordonnées de la balle en fonction des précedentes
self.boule.move(cos(self.angle) * self.horizon, sin(self.angle) * self.sens * 5);

for i, brique in enumerate(self.lbrique):
#On vérifie si elles sont en contact avec la balle
if brique.y - 2 <= self.boule.y <= brique.y + 12 and brique.x - 2 <= self.boule.x <= brique.x + 42:
#Si oui on change de direction
self.sens = (-1)*self.sens
brique.resistance -= 1
if not brique.resistance: #Si la brique ne peut plus tenir
#On la détruit et on augmente le score
brique.delete()
self.score += 20 * (len(self.vie))

self.can.itemconfig(self.tscore, text=str(self.score));

del self.lbrique[i]
if not self.lbrique:
#Si il n'y a plus de brique on arrête la balle
stop = 1
break

#Si la balle tape la barre
if 450 <= self.boule.y <= 455 and self.barre.x - 10 < self.boule.x < self.barre.x + 47:
#Si c'est sur le coin gauche, un angle plus grand
if self.barre.x-10 <= self.boule.x <= self.barre.x+5:
self.angle = 2*pi/3
self.horizon = 5

#Si c'est sur le coin droit, un angle plus petit
elif self.barre.x+37 <= self.boule.x <= self.barre.x+47:
self.angle = pi/5
self.horizon = 5

#Sinon l'angle sera dans l'autre sens
else:
self.angle = pi/3

self.sens = (-1) * self.sens

if self.boule.x < 10 or self.boule.x > 478: #Si on tape sur le bord gauche/droit
self.horizon = (-1)*self.horizon

if self.boule.y < 10: #Si on tape le plafond
self.sens = (-1)*self.sens

if self.boule.y > 466 and self.boule.x > self.barre.x + 47 or self.boule.y > 466 and self.boule.x < self.barre.x - 10:
#Si on tombe à coté de la barre, on perd une vie
self.can.delete(self.vie[0])
del self.vie[0]
stop = 1

if stop == 1: #Si on a perdu une balle,ou gagné, on remet la balle à sa place
self.flag=0
self.sens = (-1)*self.sens
self.boule.set_position(250, 440);
self.barre.set_position(235,460);

if len(self.vie)==0: #Si on a plus de vie, on écrit 'perdu'#
self.can.create_text(250,250,text='PERDU',fill='white')

if stop ==0 and self.pose==0: #Si on a pas perdu la balle, on recommence
self.can.after(20,self.go)

app = Principale(None) ###On lance l'application
app.mainloop()

Sinon ton code est assez sympa et bien commenté, continue comme ça ;)
prog94
Messages postés
10
Date d'inscription
jeudi 23 mars 2006
Statut
Membre
Dernière intervention
9 janvier 2009
-
Désolé comme t'as pu le remarqué j'ai eu un problème de copier-coller :(
elnabo
Messages postés
28
Date d'inscription
vendredi 7 août 2009
Statut
Membre
Dernière intervention
2 mai 2016
-
Ok merci pour le commentaire.
J'vais regardé ça.

Sinon est-ce vraiment génant de mettre des variables intermediaires pour simplifier l'écriture?
prog94
Messages postés
10
Date d'inscription
jeudi 23 mars 2006
Statut
Membre
Dernière intervention
9 janvier 2009
-
Eh bien c'est pas très utile et ça alourdit ton code.
C'est vrai que c'est plus long d'écrire self.barre.x au lieu de self.bar mais la plupart des éditeurs de développement ont la complétion maintenant et le mieux est de choisir un nom de variable ni trop long, ni trop court et le plus explicite possible.

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.