Partage
  • Partager sur Facebook
  • Partager sur Twitter

ISN-Tower Defense

30 avril 2019 à 11:05:53

Bonjour à vous, étant en Terminale S, j'ai choisi comme option informatique et sciences du numériques. Lors du choix de notre projet, mon groupe et moi avons choisit de créer un tower defense, très basique. Le soucis c'est que je suis l'un des seuls à travailler dans le groupe et j'ai des problèmes avec certain fonctionnement de python, je suis donc venue pour que vous puissiez me fournir des marches à suivre pour compléter mon projet. Voici la partie centrale de mon programme:

Il y a ensuite la partie consacré au défense que le joueur va posé:

et pour finir la partie consacré au ennemie se déplaçant dans la carte:

Voici ce que j'aimerais ajouté:

-faire apparaitre plusieurs ennemie sur la carte.

-faire en sorte que les tourelles fassent disparaitre totalement les ennemies lorsque ceux ci sont à proximité et non juste les rétrécirent.

Merci beaucoup à ceux qui donneront de leur attention à mon sujet.

Je suis disponible pour toute question.

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 11:20:11

Hello,

J'aurais quelques remarques mais c'est très difficile pour moi de commenter parce que je ne peux pas copier coller ton code.

Est-ce que tu pourrais poster ton code en utilisant l'icône </> de l'éditeur de post ?

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 11:53:33

Salut potterman, oui pas de problème le voici:

Fenetre principale:

from tkinter import *
from PIL.Image import*
from importlib import reload
import numpy as np
import balle as bl
import tourelle as tr
import time

reload(bl)
reload(tr)

Largeur = 500
Hauteur = 500
budget=20

T=[]
B=[]

def Ballou():
    global budget
    global T
    balle1 = bl.Balle()
    balle1.afficher(Canevas)
    dt=.2
    while 1:
        Mafenetre.update()
        start_time = time.time()
        time.sleep(dt)
        balle1.effacer(Canevas)
        balle1.deplacer(dt)
        balle1.avancer()
        balle1.avancer1()
        balle1.avancer2()
        balle1.avancer3()
        balle1.avancer4()
        balle1.avancer5()
        balle1.avancer6()
        balle1.avancer7()

        balle1.afficher(Canevas)
        for tourelle in T:
            balle1.interaction(tourelle)
        budget=budget+0.20
        print(budget)



def Placer(event):
    global budget
    global T

    if budget>20:
        tourelle1 = tr.Tourelle()
        tourelle1.x=event.x
        tourelle1.y=event.y
        tourelle1.placers(Canevas)
        budget=budget-20
        T.append(tourelle1)
    else:
        print("pas assez d'argent")




Mafenetre = Tk()
Mafenetre.title('Towerdefense')

Canevas = Canvas(Mafenetre, width = Largeur, height =Hauteur, bg ="white")
Canevas.pack()

bouton1=Button(Mafenetre, text="play", command=Ballou) # Bouton qui détruit la fenêtre
bouton1.pack()


Canevas.bind('<Button-1>', Placer)
Canevas.pack()

Canevas.create_rectangle((0,0), (500,50), fill='grey')
Canevas.create_rectangle((0,50), (500,100), fill='green')
Canevas.create_rectangle((0,100), (500,150), fill='grey')
Canevas.create_rectangle((0,150), (500,200), fill='green')
Canevas.create_rectangle((0,200), (500,250), fill='grey')
Canevas.create_rectangle((0,250), (500,300), fill='green')
Canevas.create_rectangle((0,300), (500,350), fill='grey')
Canevas.create_rectangle((0,350), (500,400), fill='green')
Canevas.create_rectangle((0,400), (500,450), fill='grey')
Canevas.create_rectangle((0,450), (500,500), fill='green')
Canevas.create_rectangle((450,50), (500,100), fill='grey')
Canevas.create_rectangle((0,150), (50,200), fill='grey')
Canevas.create_rectangle((450,250), (500,300), fill='grey')
Canevas.create_rectangle((0,350), (50,400), fill='grey')



Mafenetre.mainloop()


tourelle:

class Tourelle:

    def __init__(self):
        self.rayon=10
        self.x=0
        self.y=0


    def placers(self,Can):
        print(self.x,self.y)
        if self.x<500 and self.y<50:
            print("NONNN")
        elif self.y>100 and self.y<150:
            print("NONN")
        elif self.y>200 and self.y<250:
            print("NONN")
        elif self.y>300 and self.y<350:
            print("NONN")
        elif self.y>400 and self.y<450:
            print("NONN")
        elif self.y>500 and self.y<550:
            print("NONN")
        elif self.y<100 and self.y>50 and self.x<500 and self.x>450:
            print("NONN")
        else:
            Can.create_oval(self.x-self.rayon,self.y-self.rayon,self.x+self.rayon,self.y+self.rayon,fill='blue')

balle:

# creation de la classe Balle

import tourelle as tr


class Balle:

    def __init__(self):
        self.rayon=10
        self.x=25
        self.y=25
        self.Vx=25
        self.Vy=0


    def afficher(self,Can):
        print(self.x,self.y)
        Can.create_oval(self.x-self.rayon,self.y-self.rayon,self.x+self.rayon,self.y+self.rayon,fill='red')

    def deplacer(self,dt):
        self.x=self.x+(self.Vx*dt)
        self.y=self.y+(self.Vy*dt)


    def reduire(self):
        self.rayon-=0

    def rebondir(self):

        return
    def effacer(self,Can):
        Can.create_oval(self.x-self.rayon,self.y-self.rayon,self.x+self.rayon,self.y+self.rayon,fill='grey',outline='grey')

    def avancer(self):
        if self.x>470:
            self.Vy=10
            self.Vx=0
    def avancer1(self):
        if self.y>120 and self.x>470:
            self.Vx=-25
            self.Vy=0
    def avancer2(self):
        if self.x<30:
            self.Vx=0
            self.Vy=10
    def avancer3(self):
        if self.y>220:
            self.Vx=25
            self.Vy=0
    def avancer4(self):
        if self.x>450 and self.y>220:
            self.Vx=0
            self.Vy=10
    def avancer5(self):
        if self.y>320:
            self.Vx=-25
            self.Vy=0
    def avancer6(self):
        if self.x<30 and self.y>320:
            self.Vx=0
            self.Vy=10
    def avancer7(self):
            if self.y>420:
                self.Vx=25
                self.Vy=0

    def interaction(self,tourelle):
        if (self.x)-(tourelle.x)+(self.y)-(tourelle.y)**2<10 and self.rayon>0:
            self.rayon=self.rayon-1
            print("salut")




  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 14:26:03

Quelques conseils :

        balle1.avancer()
        balle1.avancer1()
        balle1.avancer2()
        balle1.avancer3()
        balle1.avancer4()
        balle1.avancer5()
        balle1.avancer6()
        balle1.avancer7()

Puis dans la classe :

    def avancer(self):
        if self.x>470:
            self.Vy=10
            self.Vx=0
    def avancer1(self):
        if self.y>120 and self.x>470:
            self.Vx=-25
            self.Vy=0
    def avancer2(self):
        if self.x<30:
            self.Vx=0
            self.Vy=10
    def avancer3(self):
        if self.y>220:
            self.Vx=25
            self.Vy=0
    def avancer4(self):
        if self.x>450 and self.y>220:
            self.Vx=0
            self.Vy=10
    def avancer5(self):
        if self.y>320:
            self.Vx=-25
            self.Vy=0
    def avancer6(self):
        if self.x<30 and self.y>320:
            self.Vx=0
            self.Vy=10
    def avancer7(self):
            if self.y>420:
                self.Vx=25
                self.Vy=0

C'est très très redondant tout ça, et il y a des constantes qui sortent un peu de nulle part : d'où vient le 30 ? Le 320 ? Le 420 ? Et pourquoi fais tu 8 appels à une fonction pour avancer ?

Typiquement, si self.y > 420, les 7 autres appels n'auront servi à rien, puisque self.Vx vaudra 25 et self.Vy vaudra 0 quoi qu'il arrive.

Tu pourrais donc combiner ça dans un premier temps en une seule fonction :

    def avancer(self):
        if self.x>470:
            self.Vy=10
            self.Vx=0
        elif self.y > 120 and self.x > 470:
            self.Vx=-25
            self.Vy=0          
        # etc ...

Puis dans un deuxième temps, tu pourrais donner des noms à ces constantes. Pourquoi 120 et pas un autre nombre ? Imaginons que 120 soit en fait la position du chat en y (je parle de chat parce que je ne sais pas encore de quoi parle ton programme), tu pourrais avoir une constante :

POS_CHAT_Y = 120

# ...

def avancer(self):
  if self.x > 470:
    # ...
  elif self.y > POS_CHAT_Y and self.x > 470:
    # ...

Mais ceci dit il peut y avoir des cas où c'est plus clair d'avoir le chiffre directement plutôt que de définir une constante exprès. En fait le but de tout ça c'est de rendre ton code lisible - la lisibilité du code est importante, pour toi, mais aussi pour ceux qui veulent t'aider à coder.

Ensuite..

reload(bl)
reload(tr)

Quelle est l'utilité de ces deux lignes de code ?

    def reduire(self):
        self.rayon-=0

Idem ?

Sinon pour tes questions :

> faire apparaitre plusieurs ennemie sur la carte.

Je suppose que l'"ennemi" est le Ballou ? Dans ce cas tu pourrais avoir une liste de Ballou. Tu créés une liste de Ballous au départ, et dans ton code, au lieu d'avoir balle1.avancer() etc.. tu aurais une boucle for :

for ballou in ballous:
  ballou.avancer()
  # etc..

> faire en sorte que les tourelles fassent disparaitre totalement les ennemies lorsque ceux ci sont à proximité et non juste les rétrécirent.

C'est toi qui as choisi de faire retrécir en modifiant leur rayon ;) Sinon tu pourrais imaginer avoir un membre de la classe Balle qui se nommerait par exemple "vie". Cette variable vaudrait une valeur initiale (par exemple 10 ?). A chaque fois qu'on tire sur une balle, tu décrémentes ce compteur là - si ce compteur atteint 0, tu enlève le ballou de la liste des ballous.

-
Edité par potterman28wxcv 30 avril 2019 à 14:28:23

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 17:13:19

Salut potterman, alors pour tout te dire le fait qu'il y ait eu 9 fonction avancer c'est qu'au départ j'avais comme cela que c'était la seule façon que j'avais trouvé pour comprendre mon projet, de plus ces fonctions ne font pas avancer la balle mais il l'"informe" à quelle moment elle doit prendre telle ou telle virage.

Pour

reload(br)
reload(tr)

c'est mon professeur qui m'as conseillé de le faire pour qu'a chaque modification le programme recharge ces modifications.

Pour les listes tu aurais un exemple de la marche à suivre, suffit-il juste que je crée une liste et que je modifie le nombre d'objet dans ma liste et enfin comment relier la liste à l’interaction que les balles ont avec les tourelles.

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 19:09:32

Absolument désolé pour le format horrible de ce message. J'ai voulu essayer de faire du Markdown, mais ça ne marche pas comme ça devrait sur ce site, et maintenant je ne peux plus repasser en éditeur normal. Les gens qui s'occupent de ça devraient avoir honte, surtout depuis le temps que ça dure (plusieurs années), au moins la version du Site du Zéro marchait sans aucun problème.. Bref.

Dans les code suivants, remplace tous les &lt; par des <

Katalz a écrit: alors pour tout te dire le fait qu'il y ait eu 9 fonction avancer c'est qu'au départ j'avais comme cela que c'était la seule façon que j'avais trouvé pour comprendre mon projet

Cette façon est vraiment pas bonne du tout. Elle porte à confusion. N'importe quel programmeur qui a de l'expérience te le dira. C'est un peu comme si j'avais écris ça comme code :

def test1(self):
    if self.n &lt; 40:
        self.a = 10    
def test2(self):
    if self.n &lt; 30:
        self.a = 15
def test3(self):
    if self.n &lt; 20:
        self.a = 51
def func(self):
    self.test1()
    self.test2()
    self.test3()

Alors que ce code là est beaucoup plus joli et surtout lisible :

def func(self):
    if self.n &lt; 40:
        self.a = 10
    elif self.n &lt; 30:
        self.a = 15
    elif self.n &lt; 20:
        self.a = 51

Pourquoi est-ce plus lisible ? Parce que tu vois directement ce qu'il se passe ;) Tu n'as pas à aller regarder ce que font test1() test2() et test3() , qui sont d'ailleurs répétés nulle autre part dans le code. Et aussi ça permet de programmer d'une manière plus sûr en faisant des elif. Parce que si jamais j'inversais l'ordre des test1 2 3, mon code ne ferait plus du tout la même chose :

def test1(self):
    if self.n &lt; 20:
        self.a = 10
def test2(self):
    if self.n &lt; 30:
        self.a = 15
def test3(self):
    if self.n &lt; 40:
        self.a = 51
def func(self):
    self.test1()
    self.test2()
    self.test3()

Ce code là va mettre self.a à 51 quoi qu'il arrive. Pourtant, ça n'en donne pas l'impression quand tu regardes juste le code de func.

Katalz a écrit: > de plus ces fonctions ne font pas avancer la balle mais il l'"informe" à quelle moment elle doit prendre telle ou telle virage.

Tes fonctions ne font que définir un vecteur vitesse en fonction de la position de la balle. Elles "n'informent" pas la balle ; elles agissent sur son vecteur vitesse directement. Puis, dans ta fonction deplacer, tu fais le vrai déplacement à partir du vecteur vitesse que tu as défini dans avancer7 ou avancer6 ou avancer5 selon quelle condition s'exécute en dernier..

Katalz a écrit: > c'est mon professeur qui m'as conseillé de le faire pour qu'a chaque modification le programme recharge ces modifications.

Petite question, est-ce que vous travaillez sous IDLE ?

Katalz a écrit: > Pour les listes tu aurais un exemple de la marche à suivre, suffit-il juste que je crée une liste et que je modifie le nombre d'objet dans ma liste

C'est toi qui vois comment tu veux coder ça exactement, je te donne juste des pistes. Comme je disais, tu te crées une liste de balles, en pseudo-code ça donne :

balles = []
for i in range(N):
    balles.append(Balle(...))

Puis tu remplaces ton code qui met à jour une balle par un code qui met à jour toutes tes balles. En pseudo-code, tu remplaces :

update(balle, ...)

Par :

for balle in balles:
    update(balle, ...)

Tu remplaces update par le code qui fait la "mise à jour" de la balle à chaque itération.

Katalz a écrit: > et enfin comment relier la liste à l’interaction que les balles ont avec les tourelles.

Justement, si tu as une liste de balles, tes balles seront ta liste très exactement. Au lieu dans ton code d'avoir une intéraction entre une balle et les tourelles, tu auras des intéractions entre ta liste de balles et une tourelle. En pseudo code, au lieu d'avoir ça :

for tourelle in tourelles:
    interaction(balle, tourelle)

Tu auras :

for balle in balles:
    for tourelle in tourelles:
        interaction(balle, tourelle)

Tu remplaces interaction par le code qui fait l'intéraction entre une balle et une tourelle.

-
Edité par potterman28wxcv 30 avril 2019 à 19:26:40

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 21:28:07

Mais ensuite dans:
def Ballou():
    global budget
    global T
    balle1 = bl.Balle()
    balle1.afficher(Canevas)
    dt=.2
    while 1:
        Mafenetre.update()
        start_time = time.time()
        time.sleep(dt)
        balle1.effacer(Canevas)
        balle1.deplacer(dt)
        balle1.avancer()
        balle1.avancer1()
        balle1.avancer2()
        balle1.avancer3()
        balle1.avancer4()
        balle1.avancer5()
        balle1.avancer6()
        balle1.avancer7()
        balle1.afficher(Canevas)
        for tourelle in T:
            balle1.interaction(tourelle)
        budget=budget+0.20
        print(budget)

ou dois je faire apparaitre ma liste que la fonction prenne en compte la liste et non la balle.

J'ai fais comme vous m'avez dit pour les balle1.avancer le seul problème c'est que quand je passe en elif toutes mes coordonnées sont déréglés et du coup les balles vont n'importe comment.

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 22:11:26

Réfléchis ! Je t'ai dis tout ce que je pouvais, si je te dis plus ça reviendrait à t'écrire ton code à ta place.

Si t'as besoin d'un rafraîchissement sur les listes : https://openclassrooms.com/fr/courses/235344-apprenez-a-programmer-en-python/232026-creez-des-listes-et-des-tuples-1-2

Quant à tes coordonnées si tu mets juste des elif, bien sûr que ça n'aura pas le même résultat. C'est parce que tes conditions étaient mal écrites dès le départ en fait, et t'as rajouté des bandes de scotch sur des bandes de scotch pour pallier au problème au lieu de le résoudre à la source.

Explication de pourquoi mettre des elif peut produire des résultats différents : les deux codes suivants produisent un résultat différent

Code 1 :

if a < 10:
  b = 10
if a < 20:
  b = 20
if a < 40:
  b = 40
print(b)

Si a vaut 9, ce code là affichera 40

if a < 10:
  b = 10
elif a < 20:
  b = 20
elif a < 40:
  b = 40
print(b)

Si a vaut 9, ce code affichera 10

Pour savoir pourquoi, tu peux regarder le chapitre sur les if : https://openclassrooms.com/fr/courses/235344-apprenez-a-programmer-en-python/231174-creez-des-structures-conditionnelles

N'hésite pas à insérer des print(variable) pour comprendre ce qu'il se passe dans ton code. ça peut aider énormément.

Bon courage !

PS : ça prend du temps de programmer, c'est pas magique - en tant que débutant c'est absolument normal que tu galères, on est tous passés par là ! Si tu te sens vraiment perdu, n'hésite pas à jeter un coup d'oeil au tutoriel Python de ce site, des fois ça ne fait pas de mal de tout reprendre de zéro pour bien comprendre ce qu'il se passe. Un tuto c'est un peu comme le solfège en musique - sans solfège tu peux te débrouiller pour faire quelques airs, mais c'est beaucoup plus pénible que pour quelqu'un qui connait son solfège. Je dis ça parce que je n'ai aucune idée de comment les cours de Python se passent en terminale - ça donne l'impression que vous êtes un peu livrés à vous mêmes des fois

-
Edité par potterman28wxcv 30 avril 2019 à 22:12:07

  • Partager sur Facebook
  • Partager sur Twitter
30 avril 2019 à 22:44:51

Bonsoir potterman, merci beaucoup pour votre aide je vais essayer de continuer par moi même mais votre aide ma été gratifiante.

Bonne soirée.

edit: Bonjour , je reviens vous voir car malgré vos explication et la lecteur du cours sur les listes, je ne comprend pas comment mettre mon objet balle dans une classe et le dupliquer pour avoir plusieurs balles et non 1 balle.

-
Edité par Katalz 1 mai 2019 à 14:07:11

  • Partager sur Facebook
  • Partager sur Twitter
2 mai 2019 à 16:20:23

Salut, j'ai essayer de m’intéresser  un peu plus au liste, mais j'ai quelque soucis.

def Ballou():
    global budget
    global T
    for i in range(10):
        balle = bl.Balle()
        listBalle.append(balle)
    for balle in listBalle:
        balle.afficher(Canevas)
    dt=.2
    while 1:
            Mafenetre.update()
            start_time = time.time()
            time.sleep(dt)
            balle.effacer(Canevas)
            balle.deplacer(dt)
            balle.avancer()
            balle.avancer1()
            balle.avancer2()
            balle.avancer3()
            balle.avancer4()
            balle.avancer5()
            balle.avancer6()
            balle.avancer7()
            balle.afficher(Canevas)
            print(listBalle)
    for tourelle in T:
            balle1.interaction(tourelle)
    budget=budget+0.20
    print(budget)


dans ma fonction pour faire apparaitre la balle j,'ai rentré une ligne pour qu'a chaque fois qu'une balle apparaisse il l'a mette dans la liste le soucis c'est que les balles restent afficher mais n'avancent pas



-
Edité par Katalz 2 mai 2019 à 16:57:01

  • Partager sur Facebook
  • Partager sur Twitter
2 mai 2019 à 18:12:16

Que vaut balle dans les lignes 15 à 25 ? Sur quelle(s) balle(s) s'applique(nt) tes fonctions avancer(), avancer1() etc.. ? Du coup, pourquoi tes balles n'avancent pas ?
  • Partager sur Facebook
  • Partager sur Twitter
2 mai 2019 à 18:22:08

En faite si une avance puis quand je rappuie sur play pour avoir une deuxième balle qui apparait, la première se stoppe la deuxième avance et ect. Voila ce que j'obtiens alors que j'aimerais avoir des balles qui se déplace en même temps.

Edit: Plus sérieusement, j'ai l'impression que mon projet est impossible à réaliser, car déjà d'une je suis le seul à travailler dans notre groupe de 3, et que de plus le projet est complexe à la base. J'ai passé pratiquement sur le problème de liste et je n'ai pas trouvé une solution.

-
Edité par Katalz 2 mai 2019 à 20:01:39

  • Partager sur Facebook
  • Partager sur Twitter
2 mai 2019 à 22:04:59

Ton projet n'est pas complexe, tu manques juste d'expérience. Si t'es tout seul c'est pas génial je te conseillerais de parler à ton prof pour qu'il trouve une solution.

J'ai bien compris ton problème. Mais je ne vais pas te donner la solution toute cuite, du coup j'essaie de t'amener a ce que tu trouves par toi même, parce que des problèmes comme ça t'en auras des tonnes : d'où l'utilité d'apprendre à les résoudre par toi même. Parce que ça, ça s'appelle du déboguage, et un programmeur passe en général plus de temps à deboguer qu'a coder ! C'est un procédé normal auquel tout le monde passe. ;)

Donc, je répète : que vaut balle dans les lignes 15 à 25 ? Sur quelles balles s'appliquent la fonction avancer ? Et du coup, pourquoi tes balles n'avancent pas ?

N'hésite pas à insérer des print pour répondre. Et je t'assure que si tu réponds à mes deux premières questions tu vas trouver direct pourquoi ça ne va pas

  • Partager sur Facebook
  • Partager sur Twitter
2 mai 2019 à 22:19:29

Les fonctions avancer() s'appliquent sur la class Balle, or la classe Balle contient les caractéristique propre de la balle, qui est quand à elle dans la liste listBalle, mais du coup logiquement si ma première balle avance alors les suivantes devrait également avancer sans problème car ma liste augmente et contient plusieurs balles au fil du temps.

J'ai essayer de mettre des print("salut") selon l'avancer qui devrait arriver or je ne vois les "salut" que dans les déplacement verticaux de la balle

    def avancer(self):
        if self.x>470:
            self.Vy=10
            self.Vx=0
            print("salut2")
    def avancer1(self):
        if self.y>120 and self.x>470:
            self.Vx=-25
            self.Vy=0
            print("salut2")
    def avancer2(self):
        if self.x<30:
            self.Vx=0
            self.Vy=10
            print("salut3")
    def avancer3(self):
        if self.y>220:
            self.Vx=25
            self.Vy=0
            print("salut4")
    def avancer4(self):
        if self.x>455 and self.y>220:
            self.Vx=0
            self.Vy=10
            print("salut5")
    def avancer5(self):
        if self.y>320:
            self.Vx=-25
            self.Vy=0
            print("salut6")
    def avancer6(self):
        if self.x<30 and self.y>320:
            self.Vx=0
            self.Vy=10
            print("salut7")
    def avancer7(self):
        if self.y>420:
            self.Vx=25
            self.Vy=0
            print("salut8")

Pour finir entre les lignes 15 et 25, balle vaut:

    for i in range(10):
        balle = bl.Balle()
        listBalle.append(balle)
    for balle in listBalle:
        balle.afficher(Canevas)

mais comme je l'es dit, cela sert seulement à faire en sorte que le programme mette la balle dans la list. Non ?




  • Partager sur Facebook
  • Partager sur Twitter
2 mai 2019 à 23:38:41

> Les fonctions avancer() s'appliquent sur la class Balle

Non, les fonctions avancer() s'appliquent sur une instance de la classe Balle !

Là je vais faire un peu de cours Python sur les classes - mais une classe ça te "décrit" les fonctions et les variables qui sont rattachées à un objet. Un objet, c'est une instance d'une classe. Quand tu écris :

    balle = bl.Balle()

Tu dis très précisément : je veux créer une nouvelle instance de ma classe Balle de mon module bl, et je veux que cet objet soit stocké dans la variable balle.

En particulier, quand tu fais balle.afficher(Canevas), tu appelles la fonction afficher sur l'objet particulier balle. Appeler une fonction sur un objet ne veut pas dire que la fonction sera appelée sur tous les objets de la classe ! Loin de là.

Si j'exécute ces lignes là :

for i in range(10):
    balle = bl.Balle()
    listBalle.append(balle)
for balle in listBalle:
    balle.afficher(Canevas)

Cela donne :

1) Première boucle : je crée une instance de Balle que je range dans balle, puis je range dans listBalle cette instance. Je répète ça 10 fois : ma liste contient 10 instances de Balle

2) Deuxième boucle : je vais parcourir ma liste listBalle, et mettre dans la variable balle chaque élément de ma liste. Dans cette boucle, j'utilise la fonction afficher sur la balle. Tout va bien. Pour t'aider à comprendre, cette boucle est en fait équivalente à :

for i in range(len(listBalle)):
  balle = listBalle[i]
  balle.afficher(Canevas)

A la fin de la boucle, que vaut donc balle ? Réponse : balle vaut le dernier élément de ta liste !

Tu peux vérifier ça en faisant print(listBalle), et print(balle) : tu verras que balle sera bien le dernier élément de ta liste.

Lignes 9 et 10, rien ne change, aucune affectation à balle n'est faite : balle est toujours le dernier élément de la liste.

Et ensuite, les fonctions avancer() sont appelées sur l'objet balle, c'est à dire sur le dernier élément de ta liste de balle. Et donc il n'y a que la dernière balle qui avance.


  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 0:01:40

D’accord avec vos explications, je comprend un peu mieux donc il faudrait que mes fonctions agissent sur la liste et non sur la dernière balle, il faut donc que je remplace balle.avancer par listBalle.avancer ou il faut que je fasse en sorte de comprendre toute la liste ?
  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 0:16:58

Katalz a écrit:

D’accord avec vos explications, je comprend un peu mieux donc il faudrait que mes fonctions agissent sur la liste et non sur la dernière balle, il faut donc que je remplace balle.avancer par listBalle.avancer ou il faut que je fasse en sorte de comprendre toute la liste ?


listBalle est un objet de type liste : il n'a pas de fonction avancer

Par contre, tu peux itérer sur toutes les balles de la liste avec une boucle for, et appeler balle.avancer sur chacunes d'entre elles.

Exactement comme tu as fait pour afficher. Mais avec avancer cette fois ci.

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 1:12:53

C’est bizarre car j’etais pourtant sur que mon for  balle in listballe prenait en compte les avancer aussi, merci beaucoup en tous cas vous m’êtes du grande aide.
  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 8:56:00

Et oui, l'instruction balle.avancer n'était pas dans ton for ;) mais là pour ne pas casser la structure de ce que tu as fait tu peux mettre deux boucles for différentes
  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 12:17:14

def Ballou():
    global budget
    global T
    for i in range(50):
        balle = bl.Balle()
        listBalle.append(balle)
    for balle in listBalle:
            balle.afficher(Canevas)
    for balle in listBalle:
            dt=.2
            while 2:
                    Mafenetre.update()
                    start_time = time.time()
                    time.sleep(dt)
                    balle.effacer(Canevas)
                    balle.deplacer(dt)
                    balle.avancer()
                    balle.avancer1()
                    balle.avancer2()
                    balle.avancer3()
                    balle.avancer4()
                    balle.avancer5()
                    balle.avancer6()
                    balle.avancer7()
                    balle.afficher(Canevas)
                    print(budget)
                    budget=budget+0.20
    for tourelle in T:
            balle1.interaction(tourelle)
    budget=budget+0.20
Du coup, j'ai corrigé mon erreur en mettant une boucle for mais maintenant le soucis c'est que j'ai bien ma première balle qui avance mais lorsque une deuxième est crée, la deuxième n'avance pas et la première continue d'avancer.
  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 13:41:10

Oui, t'as mis un 2 dans le while sans savoir à quoi correspond while 1. Donc je vais te faire un petit cours sur le while :

Tu as vu la boucle for qui permet d'itérer sur les éléments de quelque chose, c'est à dire que :

for element in liste:
  action(element)

Va te permettre de répéter une action sur chaque élément de ta liste.

La boucle while, par contre, est différente. Sa syntaxe est :

while condition:
  instructions

While en anglais ça veut dire "tant que". La boucle while indique donc : "tant que ma condition est vraie, alors je fais mes instructions".

On peut traduire toute boucle for en une boucle while. La boucle while suivante est équivalente à ma boucle for du début (l'exemple c'est juste pour te faire comprendre - en pratique, il vaut mieux utiliser les for quand on peut) :

i = 0
while (i < len(liste)):
  element = liste[i]
  action(element)
  i = i+1

Le while 1 est un cas particulier où la condition vaut toujours "vrai" : 1 en binaire c'est vrai, 0 c'est faux. La condition étant toujours vraie, on parle de boucle infinie.

While 2 c'est absolument équivalent à while 1. En fait, quand tu mets while n avec n > 0, ça te le translate en while true.

Autre chose à savoir en Python, est que c'est l'indentation qui détermine "ce qui appartient" à une boucle ou une condition. C'est à dire que le code suivant :

i = 0
while (i < 10):
  j = 0
  while (j < 10):
    print(i, j)
    j = j + 1
  i = i + 1

Va t'afficher tous les couples de nombres de 0 0 à 9 9 en passant par 0 1, 0 2, 0 3, etc..

Par contre, ce code là :

i = 0
while (i < 10):
  j = 0
  while (j < 10):
    print(i, j)
    j = j + 1
    i = i + 1

Va t'afficher 0 0, 1 1, 2 2, 3 3, etc..

Ce qui change entre les deux, c'est l'indentation de la dernière ligne : dans le premier cas, cette ligne fait partie du premier while, dans l'autre elle fait partie du deuxième while.

Donc en fait, ce qu'il se passe là dedans :

    for balle in listBalle:
            dt=.2
            while 2:
                    Mafenetre.update()
                    start_time = time.time()
                    time.sleep(dt)
                    balle.effacer(Canevas)
                    balle.deplacer(dt)
                    balle.avancer()

Tu rentres dans la boucle for, et entame la première itération : balle vaut listBalle[0], c'est à dire le premier élément de ta liste.

Deuxième ligne, dt=.2, OK

Troisième ligne : tu rentres dans une boucle infinie et ne vas jamais en sortir : la première balle de ta liste continue à avancer




-
Edité par potterman28wxcv 3 mai 2019 à 13:43:00

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 13:52:37

donc si je comprend bien, il faut que je remplace le while 1 par while 0, et il faut que je bouge mes fonctions avancer
def Ballou():
    global budget
    global T
    for i in range(50):
        balle = bl.Balle()
        listBalle.append(balle)
    for balle in listBalle:
            balle.afficher(Canevas)
    for balle in listBalle:
            dt=.2
    while 0:
            Mafenetre.update()
            start_time = time.time()
            time.sleep(dt)
            balle.effacer(Canevas)
            balle.deplacer(dt)
            balle.avancer()
            balle.avancer1()
            balle.avancer2()
            balle.avancer3()
            balle.avancer4()
            balle.avancer5()
            balle.avancer6()
            balle.avancer7()
            balle.afficher(Canevas)
            print(budget)
            budget=budget+0.20
    for tourelle in T:
            balle1.interaction(tourelle)
    budget=budget+0.20
je me disais bien que le while poser problème, mais maintenant aucune balle ne bouge, y compris la première. Or quand je met while 1, la première bouge. J'ai également essaye de remplacer la boucle while par une boucle for mais rien ne va non plus.

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 14:18:24

Si tu mets while 0, la condition est toujours fausse : les lignes 12 à 27 ne sont alors jamais exécutées.

Je te conseille vraiment de suivre un tutoriel sur les boucles, là tu confonds tout et surtout tu ne comprends pas ce que tu écris, c'est un peu comme si tu pratiquais de la magie noire : t'as mis ça à tel endroit, ça marche, mais tu ne sais pas pourquoi - du coup quand il faut faire des modifications tu es complètement perdu et tu modifies des trucs au pif en espérant que ça marche.

Suivre un vrai tuto ne devrait pas te prendre beaucoup de temps, et tu comprendras enfin ce que tu manipules :)

https://openclassrooms.com/fr/courses/235344-apprenez-a-programmer-en-python/231260-apprenez-a-faire-des-boucles

https://openclassrooms.com/fr/courses/235344-apprenez-a-programmer-en-python/232026-creez-des-listes-et-des-tuples-1-2

-
Edité par potterman28wxcv 3 mai 2019 à 14:21:58

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 14:30:24

Si je met while 1, cela sera toujours vrai donc ma première balle continuera toujours d'avancer au détriment des autres.

Si je met while 0, cela sera toujours faux donc aucune de mes balles avancera.

Mais du coup il faudrait retirer le while, pour que chaque balle respecte le son trajet et n'influence pas toute les balles ?

J'ai compris comment fonctionne la boucle mais je ne comprend pas qu'elle est le lien entre la boucle et mon programme à part le fait que si ma boucle fonctionne tant que telle chose est vrai, alors elle continueras en infini, je voudrais juste pouvoir avoir plusieurs balles qui avance sur ma fenêtre, et que pour que chaque balle apparaisse, j'appuie sur le bouton play comme avec la première balle.

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 14:54:42

La boucle (while 1) est là pour indiquer la "boucle infinie" de ton jeu : tout jeu a une boucle infinie, c'est à dire un while 1 qui s'arrête lorsque tu quittes le jeu.

Ce code là n'a pas de sens :

    for balle in listBalle:
            dt=.2

Cette boucle là va mettre dt à .2 autant de fois qu'il ya de balle, ça n'a aucun sens. C'est comme si tu écrivais (en supposant 5 balles) :

dt=.2
dt=.2
dt=.2
dt=.2
dt=.2


Tu me dis que tu comprends le fonctionnement des boucles mais je t'assure : tu ne comprends pas du tout. Et tu as besoin, à mon avis, d'un bon rafraichissement des bases. Mettre la charrue avant les boeufs ça ne marche jamais en programmation, faire un jeu 2D quand on ne maitrise pas les boucles c'est illusoire. C'est comme si on te demandait de jouer un morceau de piano sans avoir fait de solfège ; tu serais peut être capable d'intuiter quelques notes, mais ça serait extrèmement difficile et galère.

Là c'est un peu la même histoire - tu sais qu'une boucle ça "répète" mais tu ne sais pas ce que ça "répète" exactement, c'est une idée abstraite pour toi, et tant que ça reste une idée abstraite pour toi, tu n'arriveras pas à progresser dans ton projet. Parce que ça c'est juste un bug parmi tant d'autres que tu vas découvrir.

Mais ça ne devrait pas te prendre beaucoup de temps de suivre le chapitre que je t'ai indiqué. Une à deux heures grand maximum. Et t'y arriveras beaucoup mieux après. Il vaut mieux passer quelques heures à suivre un vrai tutoriel Python (en commençant par les chapitres que j'ai donnés par exemple) plutôt que de galérer pendant plusieurs journées sur un projet en ayant l'impression de stagner. S'efforcer de continuer le projet sans suivre de tuto ça risque même de te dégouter de la programmation ce qui serait dommage :)

-
Edité par potterman28wxcv 3 mai 2019 à 14:56:51

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 15:02:13

Non se n'est pas forcément que je n'ai pas envie, mais c'est plutôt le fait que j'ai déjà lu le cours sur les boucles et que je manque cruellement de temps étant donné que je suis le seul de mon groupe à travailler, ma note repose uniquement sur mes épaules :( .
  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 15:20:07

Je viens de lire le cours sur les boucles du site, effectivement c'est pas génial il n'y a absolument aucun exercice..

Du coup je t'en fais un maison. Le but de l'exercice va être d'afficher tous les nombres de 0 à 9, puis de 10 à 19, puis de 20 à 29, etc..

Le programme initial :

L = list(range(10)) # [0, 1, 2, ..., 9]
t = 1
while 1:
  # A COMPLETER

  print(L)
  t = t+1
  if (input() == "end"):
    break

Pour faire tourner le programme, tu appuies sur entrer pour avoir une nouvelle itération, et tu rentres "end" pour que ça termine.

Pour l'instant le programme affiche ceci :

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
...

Le but de l'exercice est qu'il affiche :

[0, 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]
...

A toi de jouer : tous les coups sont permis, à condition que tu ne remplisses que là où il y a écrit A COMPLETER (mais ça peut faire plusieurs lignes, tu peux aussi utiliser des variables, comme tu veux). Si tu réussis cet exercice, normalement tu devrais comprendre quoi faire avec ton vrai projet.


-
Edité par potterman28wxcv 3 mai 2019 à 15:20:36

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 16:40:09

c'est bizarre car j'essaye de faire
L = list(range(10)) # [0, 1, 2, ..., 9]
t = 1
while 1:
    L.append(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29)



print(L)
t = t+1
if (input() == "end"):
break

mais je me mange un erreur à propos du "break"

  File "<string>", line 368, in rem_compile
  File "<module1>", line 11
    break
        ^
IndentationError: expected an indented block


  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 16:52:15

L'erreur te dit qu'il y a une erreur d'indentation à la ligne 11. Effectivement, tu n'as pas mis d'indentation au niveau du break comme j'avais fait, du coup Python pense que le break ne fait pas partie du if, ni de la boucle while d'ailleurs.

Les indentations ont une importance, et elles ne sont pas là juste pour faire joli, elles permettent de dire à Python ce qui fait partie d'un if ou d'une boucle. Mais dans mon code de base, les indentations sont correctes.. rajoute des espace là où il faut pour que ça corresponde à ce que j'avais écris avant tes modifications.

D'ailleurs ta solution va printer les nombres de 0 à 29 - ce n'est pas ce que je demande, je veux que ça affiche, dans cet ordre là :

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Puis tu appuies sur entrée (ça c'est déjà géré par la ligne avec input + break), et tu dois afficher :

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Puis tu appuies sur entrée, et tu dois afficher :

[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

Mais en fait ça ne doit jamais s'arrêter, c'est à dire qu'un appuie de plus sur entrée doit afficher :

[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]

ça peut aller jusqu'à 99.. Jusqu'à 999.. jusqu'à ce que tu rentres "end"

Pour repartir d'un bon pied, dans un premier temps fais un copier coller de mon code sans rien changer, et exécute le, c'est à dire que dans la console tu appuies sur entrée successivement et tu devrais voir apparaitre [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] à chaque fois. Puis quand t'en as marre, tu écris "end" et tu appuies sur entrée :

L = list(range(10)) # [0, 1, 2, ..., 9]
t = 1
while 1:
  # A COMPLETER
 
  print(L)
  t = t+1
  if (input() == "end"):
    break

Dans un deuxième temps, modifie A COMPLETER pour que ça affiche les bons nombres



-
Edité par potterman28wxcv 3 mai 2019 à 16:53:55

  • Partager sur Facebook
  • Partager sur Twitter
3 mai 2019 à 17:05:49

Je t'avoue que j'ai compris ce que t'attendais de moi, mais l’exécution me semble flou, en effet j'aurai l'idée de additionner 10 à chaque valeur de la liste et cela en boucle sur toute la liste ce qui permettrait donc d'avoir ce que tu demande, mais je ne sais pas qu'elle L. je peux utiliser.
  • Partager sur Facebook
  • Partager sur Twitter