IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation multimédia/Jeux Python Discussion :

Problème de collision


Sujet :

Programmation multimédia/Jeux Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Mai 2013
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Alimentation

    Informations forums :
    Inscription : Mai 2013
    Messages : 54
    Points : 28
    Points
    28
    Par défaut Problème de collision
    bonjour,

    J'aurais besoin d'aide, je n'arrive pas a faire une fonction crédible pour la détection des collisions.

    voici le code: (les collisions sont dans la section collision )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
     
    from tkinter import *
    from random import randrange as alea
     
    def cellule(posX, posY, liste):
        """Création d'une cellule"""
        can.create_oval(posX, posY, posX+10,
                        posY+10, fill = "red", tag = "Cellule")
     
        numIdent = can.find_withtag("Cellule")
        longTuple = len(numIdent)-1
     
        for donnee in ("Cellule"+str(numIdent[longTuple]),0 , 0, posX, posY):
            liste.append(donnee)
     
    def moveCellule(nbIdent, liste):
        """Gère les mouvements de la cellule"""
     
        adresse = liste.index("Cellule" + str(nbIdent))
     
        posX1 = alea(-2, 3)
        posY1 = alea(-2, 3)
        can.move(nbIdent, posX1, posY1)
     
        liste[adresse + 3] += posX1
        liste[adresse + 4] += posY1
     
    def reproduction(nbIdent, liste):
        """Gère la reproduction des cellules"""
     
        if "Cellule"+str(nbIdent) in liste:
     
            adresse = liste.index("Cellule" + str(nbIdent))
     
            if liste[adresse+1] == 100:
                posAleaX = alea(-20, 21)
                posAleaY = alea(-20, 21)
     
                cellule(liste[adresse+3] + posAleaX,
                        liste[adresse+4] + posAleaY, liste)
     
                liste[adresse+1] = 0
                liste[adresse+2] += 1
     
            if liste[adresse+2] == 1:
                can.itemconfigure(nbIdent, fill = "dark orange")
     
            if liste[adresse+2] == 2:
                can.itemconfigure(nbIdent, fill = "blue")
     
            if liste[adresse+2] == 3:
                can.itemconfigure(nbIdent, fill = "purple")
     
            if liste[adresse+2] == 4:
                can.delete(nbIdent)
     
                for i in range(0, 5):
                    del liste[adresse]
     
            else:
                liste[adresse+1] += 1
     
    def collision(nbIdent, liste):
        """Gère les collisions entre cellules"""
     
        collision = 0
        liste2 = liste[:]
     
        adresse = liste.index("Cellule" + str(nbIdent))
     
        for i in range(0, 5):    
            del liste2[adresse]
     
        for i in range(liste[adresse+3], liste[adresse+3]+11):
            for y in range(liste[adresse+4], liste[adresse+4]+11):
                if i in liste2 and y in liste2:
                    collision = 1
     
        if liste[adresse+3] < 0 or liste[adresse+3] > 590 or liste[adresse+4] < 0 or liste[adresse+4] > 590:
            collision = 1
     
        if collision == 1:
            can.delete(nbIdent)
     
            for i in range(0, 5):
                del liste[adresse]
     
            collision = 0
     
    def gestionCompteur(liste):
        """Affiche le nombre de cellules a l'écran"""
        global compteur
        nombreCellule = "Nombre de cellules = " + str(int(len(liste)/5))
     
        compteur.configure(text = nombreCellule)
     
    def gestionCellule(liste):
        """Appel toute les fonctions pour une cellule donné"""
     
        for nbIdent in can.find_withtag("Cellule"):
            moveCellule(nbIdent, liste)
            collision(nbIdent, liste)
            reproduction(nbIdent, liste)
     
    def animation():
        """Gère la vitesse d'animation"""
        global listeCellule
        gestionCellule(listeCellule)
        gestionCompteur(listeCellule)
        root.after(50, animation)
     
    #----------------------------------------------------------------------------#
    listeCellule = []
     
    root = Tk()
     
    compteur = Label(root, text = "Nombre de cellules = 0")
    compteur.pack(side = TOP, fill = "x")
    can = Canvas(root, bg = "black", width = 600, height = 600)
    can.pack()
     
    Button(root, text = "Quit", bg = "light grey",
           command = root.destroy).pack(side = BOTTOM, fill = "x")
     
    cellule(300, 300, listeCellule)
     
    animation()
     
    root.mainloop()
    Dans le fond, je fais une copie (liste2) de ma première liste (liste) en retirant la cellules actives (pour ne pas la comparer avec elle même), et puis avec un range, je vérifie chaque coordonnées ou se trouve la cellule (imaginer un carré autour de la cellule ou je vérifie chaque point à l'intérieur), si un des points en X et un des points en Y sont dans ma liste2 alors je tue la cellules active.

    Malheureusement sa ne semble pas fonctionner, de temps en temps, lorsqu'il y a beaucoup de cellule, on voie des cellules disparaitre pour rien...

    J'ai essayer plusieur variante, mais je crois que je n'ai pas une bonne approche... Si quelqu'un a des idées je suis preneur

    merci

  2. #2
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Vous pouvez utiliser les méthodes du Canvas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    from tkinter import *
    from random import randrange as alea
     
     
    Cellules = {}
    COLORS =  {0:"red", 1:"dark orange", 2:"blue", 3:"purple"}
     
     
    def Cellule(posX, posY):
        """Création d'une cellule"""
        numIdent = can.create_oval(posX, posY, posX+10, posY+10, fill="red")
        Cellules[numIdent] = [0 , 0]
     
     
    def Reproduction(nbIdent):
        """Gère la reproduction des cellules"""
        Cellules[nbIdent][0] += 1
        if Cellules[nbIdent][0] == 100:
            celcoords = can.coords(nbIdent)
            Cellule(celcoords[0]+alea(-20, 21), celcoords[1]+alea(-20, 21))
            Cellules[nbIdent][0] = 0
            Cellules[nbIdent][1] += 1
        if Cellules[nbIdent][1] == 4:
            can.delete(nbIdent)
            del Cellules[nbIdent]
        else:
            can.itemconfigure(nbIdent, fill=COLORS[Cellules[nbIdent][1]])
     
     
     
    def Collision(nbIdent):
        """Gère les collisions entre cellules et sortie du Canvas"""
        celcds = can.coords(nbIdent)
        dead = False
        if celcds[0]<0 or celcds[2]>590 or celcds[1]<0 or celcds[3]>590:
            dead = True
        else:
            for aboveitem in can.find_closest(*Getcenter(nbIdent), halo=10):
                if aboveitem != nbIdent:
                    dead = True
        if dead:
            can.delete(nbIdent)
            del Cellules[nbIdent]
            return dead
     
     
    def Getcenter(item):
        """Retourne le centre du cercle compris dans le carré x0, y0, x1, y1"""
        itemcoords = can.coords(item)
        x = int(itemcoords[0]+(itemcoords[2]-itemcoords[0]))
        y = int(itemcoords[1]+(itemcoords[3]-itemcoords[1]))
        return x, y
     
     
    def Animation():
        """Gère l'animation"""
        for nbIdent in tuple(Cellules.keys()): 
            # Mouvement  
            posX1 = alea(-2, 3)
            posY1 = alea(-2, 3)
            can.move(nbIdent, posX1, posY1)
            #
            if not Collision(nbIdent):
                Reproduction(nbIdent)
        compteur.configure(text="Nombre de cellules = %d" % len(Cellules))
        root.after(50, Animation)
     
     
    root = Tk()
    compteur = Label(root, text = "Nombre de cellules = 0")
    compteur.pack(fill=X)
    can = Canvas(root, bg="black", width=600, height=600)
    can.pack()
    Button(root, text="Quit", bg="light grey", command=root.destroy).pack(fill=X)
    Cellule(300, 300)
    Animation()
    root.mainloop()
    Sinon vous pouvez aussi calculer la distance entre les deux centre, si elle est du rayon * 2 (pour un diamètre fixe de 10) ou moins les disques se touches.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    from tkinter import *
    from random import randrange as alea
    from math import sqrt
     
     
    Cellules = {}
    COLORS =  {0:"red", 1:"dark orange", 2:"blue", 3:"purple"}
     
     
    def Sqr(a):
        return a*a
     
     
    def Distance(item, other):
        x0, y0 = Getcenter(item)
        x1, y1 = Getcenter(other)
        return int(sqrt(Sqr(y1-y0)+Sqr(x1-x0)))
     
     
    def Cellule(posX, posY):
        """Création d'une cellule"""
        numIdent = can.create_oval(posX, posY, posX+10, posY+10, fill="red")
        Cellules[numIdent] = [0 , 0]
     
     
    def Reproduction(nbIdent):
        """Gère la reproduction des cellules"""
        Cellules[nbIdent][0] += 1
        if Cellules[nbIdent][0] == 100:
            celcoords = can.coords(nbIdent)
            Cellule(celcoords[0]+alea(-20, 21), celcoords[1]+alea(-20, 21))
            Cellules[nbIdent][0] = 0
            Cellules[nbIdent][1] += 1
        if Cellules[nbIdent][1] == 4:
            can.delete(nbIdent)
            del Cellules[nbIdent]
        else:
            can.itemconfigure(nbIdent, fill=COLORS[Cellules[nbIdent][1]])
     
     
    def Collision(nbIdent):
        """Gère les collisions entre cellules et sortie du Canvas"""
        celcds = can.coords(nbIdent)
        dead = False
        if celcds[0]<0 or celcds[2]>590 or celcds[1]<0 or celcds[3]>590:
            dead = True
        else:
            for aboveitem in can.find_closest(*celcds):
                if aboveitem != nbIdent and Distance(aboveitem, nbIdent) <= 10:
                    dead = True
        if dead:
            can.delete(nbIdent)
            del Cellules[nbIdent]
            return dead
     
     
    def Getcenter(item):
        """Retourne le centre du cercle compris dans le carré x0, y0, x1, y1"""
        itemcoords = can.coords(item)
        x = int(itemcoords[0]+(itemcoords[2]-itemcoords[0]))
        y = int(itemcoords[1]+(itemcoords[3]-itemcoords[1]))
        return x, y
     
     
    def Animation():
        """Gère l'animation"""
        for nbIdent in tuple(Cellules.keys()): 
            # Mouvement  
            posX1 = alea(-2, 3)
            posY1 = alea(-2, 3)
            can.move(nbIdent, posX1, posY1)
            #
            if not Collision(nbIdent):
                Reproduction(nbIdent)
        compteur.configure(text="Nombre de cellules = %d" % len(Cellules))
        root.after(50, Animation)
     
     
    root = Tk()
    compteur = Label(root, text = "Nombre de cellules = 0")
    compteur.pack(fill=X)
    can = Canvas(root, bg="black", width=600, height=600)
    can.pack()
    Button(root, text="Quit", bg="light grey", command=root.destroy).pack(fill=X)
    Cellule(300, 300)
    Animation()
    root.mainloop()
    Enfin, c'est des idées. A vous de voir

    @+

    Edit : Le code sorti du contexte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    from tkinter import *
    from math import sqrt
     
     
    def Sqr(a):
        return a*a
     
     
    def Getcenter(item):
        itemcoords = can.coords(item)
        x = itemcoords[0]+(itemcoords[2]-itemcoords[0])
        y = itemcoords[1]+(itemcoords[3]-itemcoords[1])
        return x, y
     
     
    def Distance(item, other):
        x0, y0 = Getcenter(item)
        x1, y1 = Getcenter(other)
        return sqrt(Sqr(y1-y0)+Sqr(x1-x0))
     
     
    def Motion():
        can.move(c1, 1, 1)
        can.move(c2, -1, -1)
        if Distance(c1, c2) <= 100:
            can.itemconfig(c1, fill="red")
            can.itemconfig(c2, fill="red")
            can.create_text(300, 300, text="IMPACT", font=("Helvectica", "16"),
                            fill="yellow", justify=CENTER)
        else:
            root.after(20, Motion)
     
     
    root = Tk()
    root.title("tkinter : two same disk")
    can = Canvas(root, bg="black", width=600, height=600)
    can.pack()
    Button(root, text="Quit", bg="light grey", command=root.destroy).pack(fill=X)
    c1 = can.create_oval(0, 0, 100, 100, fill="blue")
    c2 = can.create_oval(500, 500, 600, 600, fill="blue")
    root.after(1, Motion)
    root.mainloop()

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problême duplication collision AS2
    Par laipreu dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 04/09/2007, 10h01
  2. problème de collision sur objet en rotation
    Par filiplj dans le forum ODE
    Réponses: 2
    Dernier message: 21/08/2007, 16h00
  3. Problème de "collision" avec un "EDIT"
    Par Darkenshin dans le forum Windows
    Réponses: 2
    Dernier message: 31/05/2007, 13h21
  4. Problème de collisions personnage - acteurs
    Par Axelkill dans le forum PhysX et APEX
    Réponses: 3
    Dernier message: 27/02/2007, 18h47
  5. Problème de collision en 2D
    Par Clad3 dans le forum Physique
    Réponses: 3
    Dernier message: 26/05/2006, 00h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo