Pommex désigne l'abscisse de la Pomme et Pommey son ordonnée. Je souhaite en gros que ma pomme apparaisse aléatoirement. Pour cela j'ai eu l'idée de créer deux listes : une avec toutes les valeurs possibles de son abscisse (pour que ça puisse rentrer dans le cadre de jeu), et une pareil pour l'ordonnée. Cependant je suis incertains sur de nombreuses choses, qui sont la création de mes listes qui comprennent respectivement 80 et 75 valeurs si je ne me trompe pas, ainsi que le choix aléatoire des valeurs pour ensuite placé l'image de Pomme sur l'arène de jeu. J'espère que je m'exprime bien. N'hésitez pas à me poser des questions.
Je vous remercie dès maintenant pour l'aide.
- Edité par GuillaumeBrun3 21 janvier 2018 à 0:58:02
Ensuite, random.choice fera tout à fait l'affaire pour choisir un élément aléatoire.
N'hésite pas à tester ton code directement sur l'idle (et si tu codes autrement qu'avec l'idle je te conseille de changer )
Et je ne veux pas t'importuner, surtout que je ne sais pas dans quel cadre tu souhaites développer ce petit snake, mais tu te complexifies la vie avec pas mal de chose.
Python est orienté objet, et le mot clé global ne s'utilise que tout les 5 ans par un programmeur ayant fait une une thèse en pythonnerie, ou bien tout les jour par ceux faisant du python sans les objets
Ensuite, random.choice fera tout à fait l'affaire pour choisir un élément aléatoire.
N'hésite pas à tester ton code directement sur l'idle (et si tu codes autrement qu'avec l'idle je te conseille de changer )
Et je ne veux pas t'importuner, surtout que je ne sais pas dans quel cadre tu souhaites développer ce petit snake, mais tu te complexifies la vie avec pas mal de chose.
Python est orienté objet, et le mot clé global ne s'utilise que tout les 5 ans par un programmeur ayant fait une une thèse en pythonnerie, ou bien tout les jour par ceux faisant du python sans les objets
Merci tout d'abord pour les listes. J'ai réussi à bien créer ma liste et à faire les tirages au sort.
Est-ce que peut-être tu voudrais que je t'envoie mon code (d'environ 80 lignes) pour voir l'ensemble ? En plus de cela j'ai un autre petit problème que tu pourras peut-être m'aider à résoudre.
@MrFoxtrot, les ranges sont des séquences (objets indexables avec une taille connue), donc il n'est pas nécessaire de les convertir en listes pour effectuer un random.choice dessus.
@GuillaumeBrun3, Plutôt que de faire un range puis un random.choice, autant directement faire un random.randrange qui combine ces deux opérations.
Merci tout d'abord pour les listes. J'ai réussi à bien créer ma liste et à faire les tirages au sort.
Est-ce que peut-être tu voudrais que je t'envoie mon code (d'environ 80 lignes) pour voir l'ensemble ? En plus de cela j'ai un autre petit problème que tu pourras peut-être m'aider à résoudre.
Merci à toi.
Bonjour, oui tu peux toujours, ça me ferais plaisir d’aider, mais je ne donne aucune garantie quant au temps de réponse
@entwanne hum, oui tu as raison, je ferais mieux de regarder la doc avant de dire des salades En tout cas j’apprends pas mal de trucs avec toi !
Merci tout d'abord pour les listes. J'ai réussi à bien créer ma liste et à faire les tirages au sort.
Est-ce que peut-être tu voudrais que je t'envoie mon code (d'environ 80 lignes) pour voir l'ensemble ? En plus de cela j'ai un autre petit problème que tu pourras peut-être m'aider à résoudre.
Merci à toi.
Bonjour, oui tu peux toujours, ça me ferais plaisir d’aider, mais je ne donne aucune garantie quant au temps de réponse
@entwanne hum, oui tu as raison, je ferais mieux de regarder la doc avant de dire des salades En tout cas j’apprends pas mal de trucs avec toi !
Je vois que c'est un projet en ISN, je commencerais par des remarques valables pour tout programme et tout langage.
Premièrement pour le lecteur (moi-même aujourd'hui), il y a plein de mauvaise habitude à écarter :
Il faut toujours nommer les noms de variables en fonction de leur utilités, et idem pour les fonctions. Par exemple FermerPseudoJoueur devrait s’appeler close_pseudo_start_game, mais en pratique c'est simplement que Jouer() ne devrait pas se trouver à la fin cette fonction. Pas besoin d'évoquer les affreux noms que tu as donné à tes fenêtres...
En suite, les langage utilise des normes d'écriture, pour harmoniser et simplifier la lecture pour des codes différents. En Python, on note les noms de constante en majuscule (eg MAX_SCORE = 100) ; les noms de fonction et de variables en minuscule ; et les noms de type avec la première lettre en maj (e.g. Button, Entry, etc. pour tkinter), hormis les type dit 'built-in' (int, str, ...). Ça permet d'éviter les erreurs étant donné que python n'est pas 'typé'. En effet aucune erreur ne sera levée si tu as une fonction fun et que par mégarde tu fais : fun=0. Après cela fun deviendra un entier... Bref, j'ai laissé les maj partout mais ça me pique
Après, pour l'utilisateur. C'est peut-être un détail à ton niveau, mais on ne laisse jamais de code 'flottant' à la fin d'un fichier. Si qqun veut importer ton fichier (pour une page web par exemple), le code sera lu de haut en bas. C'est à dire que rien qu'en faisant from ton_fichier import *, le jeu se lancera ! J'ai mis une condition pour au moins éviter cela mais ce n'est tout de même pas LA solution.
Venant on à ton code, je l'ai remanié, je pense qu'il fonctionne.
Lorsque l'on travail avec tkinter, Tk() est un objet qui constitue une unité au sein d'un projet. Les variables IntVar, StringVar, etc. dépendent directement de cet objet Tk(). Ainsi lorsque tu recréais un objet Tk dans EntrerPseudo(), la variable n'existait plus en revenant dans Jouer() (j'ai mis du temps à comprendre ^^). De plus pour récupérer la valeur de ces variables, il faut utiliser la méthode get().
Donc : l'objet 'Tk' est une instance complète de ton application, et les variables tk y sont liés. Je te conseille vraiment de ne faire qu'un seul objet Tk.
Enfin, je ne vois pas le code correspondant à l'affichage d'un fruit
"""Jeu du Serpent, 2018.""" # un peu de doc, c'est toujours classe
__author__='Nicolas and Guillaume'
__version__='1.0' # Ça c'est assez important si tu travailles
# sans logiciel de gestion de version
from tkinter import *
from random import choice, randrange # pas besoin de tout importer
# Variables
# fen1 : The menu
# fen2 : The game
# fen3 : The pseudo input
global fen1, fen2, fen3, PseudoJoueur, ScoreJoueur, Pseudo, label2
#Fonctions/Commandes :
#Jouer
def Jouer():
global PseudoJoueur, ScoreJoueur, label2
Quitter() # par exemple c'est un peu étrange pour qqun qui lit le code,
# alors qu'une fonction nommée quitter_menu()
# serait plus compréhensible...
fen2 = Tk()
fen2.title('SnakeGame by Nicolas and Guillaume')
fen2['bg']='black'
fond=PhotoImage(file='D:/_Bureau/Cours/Terminale/ISN/Projet/background.ppm',
master=fen2)
label2 = Canvas(fen2, width =1300, height = 1000)
label2.create_image((500,500),image=fond)
label2.pack()
label2.create_rectangle(100, 150, 800, 800, width=8)
Score = label2.create_text(1050, 125, text="Score", font="!Y2KBUG 70 ",
fill="black")
ScoreJoueur = label2.create_text(1050, 275, text="30", font="!Y2KBUG 60",
fill="black")
# J'ai mis PseudoJoueur.GET(), je te laisse regarder
# ce qu'il se passe si tu l'enlève
Pseudo = label2.create_text(1050, 375, text=PseudoJoueur.get(),
font="!Y2KBUG 50 ",fill="black")
# Petit test, ça ne fait jamais de mal # # # # # # # # # # #
fen2.bind('<KeyPress-Return>',lambda x :update_score(100)) #
# # # #
#Pseudo Joueur
def EntrerPseudo():
global fen3, fen1, PseudoJoueur
fen3 = Toplevel(fen1)
# tk.Toplevel est une fenêtre, tout comme l'objet Tk(), mais elle est
# lié à un objet tk (ici : fen1)
fen3.title('Entrez votre pseudo !')
fen3['bg']='black'
fen3.focus_set()
PseudoJoueur=StringVar()
Pseudo = Entry(fen3, width=20, bd=8, bg='black', fg='white',
font="!Y2KBUG 30", textvariable=PseudoJoueur)
Valide = Button(fen3, anchor='center', text="✔", background='black',
foreground='white', font="!Y2KBUG 30 ", width='5',
command=FermerPseudoJoueur)
# Ligne de code magique qui 'bind' le bouton <entré> du clavier
# avec l'activation de ton bouton 'Valide'
Pseudo.bind('<KeyPress-Return>',lambda x : Valide.invoke())
Valide.place(x=800 , y=215, width=400, height=250)
Valide.pack()
Pseudo.focus_set() # cela permet de 'donner le focus', ie ne pas
# avoir à cliquer pour saisir le pseudo
Pseudo.pack()
#Fermer la zone de saisie du pseudo
def FermerPseudoJoueur():
global fen3, PseudoJoueur
fen3.destroy()
Jouer()
#Fruit
def Fruits():
global fen2 # Ne pas oubliez de mettre en global
listex = range(100, 800, 10)
list(listex)
# En faisant : from random import choice, tu peux utiliser
# 'choice' directement.
# En revanche (et c'est mieux apprécié), en faisant 'import random',
# tu serais obligé d'écrire 'random.choice'.
Fruitx=choice(listex)
label2.create_image # Cette ligne n'a aucun effet je pense
listey = range(150, 800, 10)
list(listey)
Fruity=choice(listex)
pomme = PhotoImage(file='D:/_Bureau/Cours/Terminale/ISN/Projet/Fruit.ppm',
master=fen2)
FruitImage = label2.create_image(Fruitx, Fruity, image = pomme)
#Quitter
def Quitter():
fen1.destroy()
def update_score(new_score):
""" Met à jour le score sur label2.
"""
global ScoreJoueur, label2
label2.itemconfigure(ScoreJoueur, text=int(new_score))
if __name__=='__main__':
# Permet d'éviter que le code ne se lance lors d'un import
#Menu
fen1 = Tk()
fen1.title('SnakeGame by Nicolas and Guillaume')
fen1['bg']='black'
label1 = Canvas(fen1, width=1300, height=1000, background="black")
label1.pack()
TexteMenu = label1.create_text(650, 100, text="MENU",
font="!Y2KBUG 70 underline", fill="white")
bouton1 = Button(label1, anchor='center', text="JOUER", background='black',
foreground='white', font="!Y2KBUG 70 ", width='5',
command=EntrerPseudo)
bouton1.place(x=450 , y=215, width=400, height=250)
bouton2 = Button(label1, anchor='center', text="QUITTER", background='black',
foreground='white', font="!Y2KBUG 70 ", width='7',
command=Quitter)
bouton2.place(x=450 , y=550, width=400, height=250)
fen1.mainloop()
Mais, et c'est le plus gros problème de ce code, les variables globals c'est relou, très relou. Je te l'ai déjà dis, je vais simplement te montrer brièvement à quoi ressemblerait un code utilisant la POO. J'ai essayé de le documenté pour que tu puissent comprendre.
Voilà la bête :
class Snake: # C'est un objet, on met une majuscule
def __init__(self):
# Ici, j'initialise l'objet, il s'appelle self.
# Je peux mettre tout ce que je veux dedans ehehe
self.pseudo=str()
self.score=int()
self.mayo = ('fritte','poulet')
self.win = Tk()
self.win.title('SnakeGame by Nicolas and Guillaume')
self.win['bg']='black'
def jouer(self):
"""Main method for the snake.
"""
label = Canvas(self.win, width =1300, height = 1000)
label.create_image((500,500))
label.pack()
label.create_rectangle(100, 150, 800, 800, width=8)
# A chaque fois que l'on déclare une variable précédée de 'self.',
# on peut la réutiliser partout dans le code de l'objet Snake.
self.score = label.create_text(1050, 125, text="Score",
font="!Y2KBUG 70 ",fill="black")
self.score_joueur = label.create_text(1050, 275, text="30",
font="!Y2KBUG 60",fill="black")
self.pseudo = label.create_text(1050, 375, text=self.pseudo,
font="!Y2KBUG 50 ",fill="black")
def entre_pseudo(self):
"""Open a top level windown to input the pseudo.
"""
# Ici, 'win' est définie comme variable réservée à la méthode self.entre_pseudo (car je
# ne mes pas 'self.'). En effet, il ne me semble pas avoir besoin de cette fenêtre en dehors.
# Il faudra destroy à la fin de la méthode.
win = Toplevel(self.win)
# blablabla
win.destroy()
def menu(self):
# Ici l'on mettrais tous ce que tu as mis à la fin de ton code
pass
def fruit(self):
pass
def update_score(self):
pass
def quitter_menu(self):
pass
def quitter_pseudo(self):
pass
def main(self):
"""Main method to master the windows.
"""
self.menu()
##Et seulement à la fin, on fait :
if __name__=='__main__':
snake=Snake()
snake.main()
Ainsi, utiliser une classe permet de stocker les informations au sein de celle-ci, plus besoin de faire d'alchimie avec global. De manière général on utilise jamais global, même si tu ne veux pas faire de classes, on préféra passer les objets en arguments des fonctions :
def create_win():
win = tk.Tk()
return win
def fun(win):
"""Function qui fait qqch avec une fenêtre.
"""
win.faire_qqch()
def play():
fun(create_win())
Et bien voilà, je suis toujours à peu près disponible pour éclaircir le mystère des fruits, enjoy !
Donc : l'objet 'Tk' est un instance complète de ton application, et les variables tk y sont liés. Je te conseille vraiment de ne faire qu'un seul objet Tk.
Il ne faut pas conseiller mais imposer, on ne doit pas avoir plusieurs instances Tk. Si on veut créer une nouvelle fenêtre, on utilisera plutôt la classe Toplevel.
Je souhaite vous adresser un très grand merci pour votre aide apportée. Vos conseils sont précieux, merci beaucoup.
Cependant je n'arrive toujours pas à récupérer le pseudo entré, même avec .get(), mais en effet je pense que cela vient du fait que la fenêtre se ferme, ce qui empêche de stocker correctement la variable.
Pourtant j'ai testé cela :
#Fermer la zone de saisie du pseudo
def fermer_pseudo_joueur():
global fen3, pseudo_joueur, Pseudo
Pseudo = pseudo_joueur.get()
fen3.destroy()
Jouer()
Mhmm, il me semble que le code que j'ai donné précédemment fonctionnait. Sache que lorsque tu lies le widget Entry à un textvariable, ce qui est écrit dans le widget est automatiquement sauvegardé dans le StringVar en question.
Je répond un peu en retard, si tu n’arrives toujours pas à régler le problème, exécute ça, pour info :
import platform as p
import tkinter
disp = lambda cle, valeur: print("{k} -> {v}".format(k=cle, v=valeur))
sys = p.system()
python = p.python_version()
jeu, form = p.architecture()
distribution = p.version()
disp("sys", sys)
disp("jeu d'instructions", jeu)
disp("distribution", distribution)
disp("python version", python)
disp('TCL version',tkinter.TclVersion)
Et aussi, ce petit bout de code que j'avais intercalé, utilise le pour tester certaine fonctions tkinter réticentes...
# Petit test, ça ne fait jamais de mal # # # # # # # #
win.bind('<KeyPress-Return>',lambda x: fun_to_test())#
#
EDIT : Je te donne ces outils par ce que les débuts en prog sont très empiriques, on test, on se questionne, on cherche, ... Aucun programmeur n'est sûr au moment d'exécuter son code que celui-ci va fonctionner (c'est théoriquement impossible !).
En tout cas, bonne continuation, dispo pour d'autres réclamations !
Foxtrot
- Edité par MrFoxtrot 6 février 2018 à 13:40:28
Problème listes/Random
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
entwanne — @entwanne — Un zeste de Python — La POO en Python — Notions de Python avancées — Les secrets d'un code pythonique