begin process at 2012 05 24 23:23:53
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Python

 > 

Divers

 > 

Débutant(e)

 > 

Demande d'aide à l'optimisation


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Demande d'aide à l'optimisation

mercredi 20 janvier 2010 à 20:47:47 | Demande d'aide à l'optimisation

elnabo

Bonjour, ayant réaliser un petit code permettant de déplacer un petit rond d'avant en arrière et lui permettant des rotations, à l'aide du clavier en me servant de classe,je me décide à le poster ici pour demander une aide à son optimisation.

Code Python :
#
from Tkinter import *
from math import *
class move:
    ""
    def __init__(self):
        self.x=100
        self.y=100
        self.x1=120
        self.y1=120
        self.ang=0
        fen = Tk()
        self.can = Canvas(fen,width = 300,height = 300,bg='dark grey')
        self.can.bind_all("<Right>",self.droite)
        self.can.bind_all("<Left>",self.gauche)
        self.can.bind_all("<Up>",self.haut)
        self.can.bind_all("<Down>",self.bas)
        self.can.pack()
        self.joueur = self.can.create_oval(self.x-10,self.y-10,self.x+10,self.y+10,fill = 'yellow')
        self.t = self.can.create_line(self.x,self.y,self.x1,self.y1,fill='red')
        fen.mainloop()
        
    
    def gauche(self,event):
        if self.ang==0:
            self.x1+=-5
        else:
            self.x1+=5
        self.eg()
        self.can.coords(self.t,self.x,self.y,self.x1,self.y1)

    def droite(self,event):
        if self.ang==0:
            self.x1+=5
        else:
            self.x1+=-5
        self.ed()
        self.can.coords(self.t,self.x,self.y,self.x1,self.y1)

    def eg(self):
        try:
            self.y1=self.y-sqrt(20**2-(self.x1-self.x)**2)
        except:
            if self.ang != 1:
                self.ang=1
                self.x1+=10
            else:
                self.ang=0
                self.x1+=-10
        if self.ang==1:
            self.y1=self.y+sqrt(20**2-(self.x1-self.x)**2)
        else:
            self.y1=self.y-sqrt(20**2-(self.x1-self.x)**2)

    def ed(self):
        try:
            self.y1=self.y+sqrt(20**2-(self.x1-self.x)**2)
        except:
            if self.ang==0:
                self.ang=1
                self.x1+=-10
            else:
                self.ang=0
                self.x1+=10
        if self.ang==1:
            self.y1=self.y+sqrt(20**2-(self.x1-self.x)**2)
        else:
            self.y1=self.y-sqrt(20**2-(self.x1-self.x)**2)


    def haut(self,event):
        self.x2,self.y2=self.x,self.y
        if self.x1<280 and self.y1<280 and self.x1>20 and self.y1>20 :
            self.can.coords(self.joueur,self.x1-10,self.y1-10,self.x1+10,self.y1+10)
            self.x,self.y=self.x1,self.y1
            self.x1,self.y1=2*self.x-self.x2,2*self.y-self.y2
            self.can.coords(self.t,self.x,self.y,self.x1,self.y1)


    def bas(self,event):
        self.x2,self.y2=2*self.x-self.x1,2*self.y-self.y1
        if self.x<280 and self.y<280 and self.x>20 and self.y>20 :
            self.can.coords(self.joueur,self.x2-10,self.y2-10,self.x2+10,self.y2+10)
            self.x1,self.y1=self.x,self.y
            self.x,self.y= self.x2,self.y2
            self.can.coords(self.t,self.x,self.y,self.x1,self.y1)
        
        

Move = move()


De plus, je me demandais comment je pourrais faire pour permettre la rotation du cercle en même temps que le déplacement de celui ci

Merci d'avance elnabo
jeudi 21 janvier 2010 à 03:46:30 | Re : Demande d'aide à l'optimisation

nyko77

Réponse acceptée !
Bonjour,
Je viens de jeter un coup d'½il à ton code, j'ai trouvé ton idée assez marrante.
Voici quelques idée en vrac:

-En général j'essaye d'éviter le from truk import *. ça va bien pour les petits programme, mais c'est vite le bordel dans des projet plus conséquent.
-Il n'y a aucun commentaire dans ton code, c'est parfois bien utile.
-Je remarque qu'il y a beaucoup de valeurs numériques. Le jours ou t'as envies de mettre un canvas de 500*350 il faut aller bidouiller un peu partout dans ton code. Je pense que tu peux mettre les valeurs taille du canvas, déplacement de l'angle et longueur du déplacement dans le __init__(), (tu peux bien sûr en rajouter, taille du cercle...). Après t'as plus qu'à choisir tes valeurs lorsque tu instancies t'as classe, c'est quand même le bute de POO.
-Je remarque beaucoup de redondance dans ton code, notamment dans les méthodes haut, bas et droite, gauche. Il doit y avoir moyen de les combiner en une seule méthode en passant un argument lors du bind grâce à une fonction lambda, ou tout simplement en "bindant" uniquement <KeyPress>.
-Il est plutôt d'usage de mettre une majuscule pour les noms de classes
-Tu peux remplacer
Code Python :
if self.x1<280 and self.y1<280 and self.x1>20 and self.y1>20 :

par
Code Python :
if 20<self.x1<280 and 20<self.y1<280:

-Je ne suis pas très fort en math, mais il m'a semblé que la trigonométrie était plus approprié pour ce genre de chose.
-Je ne suis pas sûr qu'il soit nécessaire de stoker les coordonnées du joueur, il vaut mieux les récupérer avec .coords().
-tu peux utiliser la méthode .move pour déplacer ton joueur. Tu peux même mettre un tags identique au rond et au trait pour les déplacer en même temps.
-j'ai remarquer deux petits problème dans le fonctionnement de ton applications: le trait est plus long au départ, puisque tu démarres à -20, -20, d'après pythagore ça fait 28.28 alors qu'il fait 20 par la suite. Il y a également un problème dans le changement des angles, le trait ce déplace parfois de 45° et parfois de 15°. J'ai pas regardé la cause du problème.

Bon trève de bacardage, je me suis amusé à mettre en ½uvre mes conseils:
Code Python :
# -*- coding: utf-8 -*-
import Tkinter as tk
from math import cos, sin, pi


class Move:
	def __init__(self, width=300, height=300, precisionAngle=12, moveBy=5, rayonJoueur=10, directionLen=20, xDepart=100, yDepart=100):
		fen = tk.Tk()
		#La valeur avec laquelle on incrémentera l'angle
		self.incrAng = (2*pi) / precisionAngle
		#le "pas" de déplacement
		self.moveBy = moveBy
		#longueur du trait
		self.directionLen = directionLen
		#la valeur de l'angle en cours
		self.ang = 0
		#le x et y maximum du joueur pour ne pas sotir du canevas
		self.maxX = width - self.directionLen
		self.maxY = height - self.directionLen
		
		self.can = tk.Canvas(fen, width=width, height=height, bg='dark grey')
		self.can.pack()
		self.joueur = self.can.create_oval(xDepart-rayonJoueur, 
			yDepart-rayonJoueur, xDepart+rayonJoueur, yDepart+rayonJoueur, fill='yellow', tags="joueur")
		self.direction = self.can.create_line(xDepart, yDepart, xDepart+self.directionLen, yDepart, fill='red', tags="joueur")
		self.can.bind_all("<KeyPress>", self.onKeyPress)
		fen.mainloop()
	
	
	def onKeyPress(self, event):
		key = event.keysym
		if key == "Right":
			self.moveDirection(1)
		elif key == "Left":
			self.moveDirection(-1)
		elif key == "Up":
			self.moveJoueur(1)
		elif key == "Down":
			self.moveJoueur(-1)
				
	def moveDirection(self, sens):
		"""Appelé lorsque que l'utilisateur appuie sur gauche ou droite"""
		#calcul le nouvel angle
		self.ang = self.ang + self.incrAng * sens
		#récupère les coordonnées du début du trait de direction
		x, y = self.getCoord()
		#calcul les coordonnées de la fin du trait de direction
		x1 = x + cos(self.ang) * self.directionLen
		y1 = y + sin(self.ang) * self.directionLen
		#affiche le nouveau trait de direction
		self.can.coords(self.direction, x, y, x1, y1)
	
	def moveJoueur(self, sens):
		"""Appelé lorsque que l'utilisateur appuie sur haut ou bas"""
		#calcul le vecteur de déplacement
		xMove = cos(self.ang) * self.moveBy
		yMove = sin(self.ang) * self.moveBy
		#si je joueur ne sort pas du canvas, déplace le joueur
		if self.verifZone(xMove*sens, yMove*sens):
			self.can.move("joueur", xMove*sens, yMove*sens)
	
	def verifZone(self, xMove, yMove):
		"""vérifie si le joueur sort de la zone"""
		#récupère les coordonnées du joueur
		x, y = self.getCoord()
		#coordonnée du joueur après déplacement
		newX, newY = x + xMove, y + yMove
		#si le joueur ne sort pas du canevas après déplacement
		if self.directionLen<newX<self.maxX and self.directionLen<newY<self.maxY:
			return True
		else:
			return False
			
	def getCoord(self):
		"""retourne les coordonnées du centre du joueur"""
		return self.can.coords(self.direction)[:2]
		
	
Move(300, 200, 24, 3)


Pour changer l'angle en même temps que le joueur se déplace ça semble plus compliqué, il faudrait pouvoir désactiver la répétition des touches.Je me pencherai dessus une autre fois.
jeudi 21 janvier 2010 à 19:19:42 | Re : Demande d'aide à l'optimisation

elnabo

Et bien merci pour cette réponse structuré. Visiblement ça m'a l'air plus pratique.

En fait pour la rotation , je ne me servais uniquement de l'équation d'un cercle pour calculer les coordonnées du point y en fonction du point x que j'incrémentais. Et de ce fait la rotation n'était pas forcement régulière.

Je vais regarder grossièrement tes idées et conseils ce soir, mais je regarderais le plus gros à tête reposée ce Week-End

Encore merci Elnabo
dimanche 24 janvier 2010 à 21:43:07 | Re : Demande d'aide à l'optimisation

elnabo

Voila, j'ai tout bien regardé et j'avoue que c'est plus pratique, plus simple et plus régulier que ma première version.

En plus j'ai compris l'usage de Tkinter sans avoir à charger toutes ces fonctions.

Par contre, j'aurais une question à propos de l'utilisation des tags.
J'ai cru comprendre qu'ils permettaient d'effectuer une/des opération(s) sur plusieurs objet en même temps. Par contre je ne comprends pas pourquoi cette ligne de code permet de modifier quatre coordonnées:
Code Python :
self.can.move("joueur", xMove*sens, yMove*sens)

mardi 26 janvier 2010 à 21:28:55 | Re : Demande d'aide à l'optimisation

nyko77

Réponse acceptée !
La méthode .move() n'assigne pas des coordonnées, mais déplace un objet de x et y.
Prenons un exemple:
Ton joueur est situé aux coordonnées x=50 et y=100.
puis tu exécutes self.can.move("joueur", 10, 20),
ton joueur se situe alors aux coordonnées x=60 et y=120.
Puisque le cercle et le trait on le tag "joueur", les 2 se déplacent en même temps.


mercredi 27 janvier 2010 à 10:57:30 | Re : Demande d'aide à l'optimisation

elnabo

D'accord merci bien


Cette discussion est classée dans : self, x1, can, y1, ang


Répondre à ce message

Sujets en rapport avec ce message

script qui ne marche pas (gros débutant) [ par kers50 ] bonjour tout le monde,je prévient je suis vraiment un débutant j'ai commencer y a quelque jour à apprendre à programmer avec python en tant qu'amateur Tracer un logiciel [ par undertaker4000 ] Bonjour, J'utilise le logiciel Inkscape qui possède des extensions écrites en Python. Je voudrais pouvoir comprendre comment ces extensions fonctionne [Python][Classe] intégration fonction "def" dans une classe [ par Acolyte ] Bonsoir à tous, J'ai un petit problème je veux créer un module digit qui permet d'afficher des chiffres digitaux (virtuel) comme sur les anciens radio matrice symétrique [ par delaval ] bonjour, je suis actuellement en train d'écrire une fonction symétrique qui renvoie True or False selon la matrice que je rentre. Voici mon code:class Validation d'un code baree [ par vianneyba ] Boujour, j'utilise un programme a mon boulot fait par mes soins en python et avec une interface TKinter qui permet de lister une commande apres avoir Tkinter - ScrolledCanvas - Les objets dépassents du Canevas [ par Chris3392 ] Bonjour, Je suis en train de coder une console qui surveille des abus d'utilisation d'armes sur des jeux en réseau (FPS). A cet effet j'ai codé un Sc toutes les lignes+colonnes d'un QTreeWidget [ par WieWeet ] bonjour, mes recherches ( google et autres ) n'ayant rien donné, [code=py] import sys from PyQt4 import QtGui from PyQt4.QtGui import QTreeWidget clas WXPython, probleme avec un notebook [ par faucheuse ] Par défaut Probleme sizer dans un panel dans un notebook Bonjour à tous, J'ai créer un notebook dans lequel je met plusieurs panel ainsi que un ou pl taquin 4*4 probleme affichage tkinter [ par fredericfabry ] Bonjour je me suis lance dans la resolution du probleme du taquin (puzzle) de4*4 mon programme donne le resultat mais je ne suis pas content car j'ai Bug graphique [ par ples ] Bonjour, Je travail sous opensuse-11.4. Pour intégrer le module nidaqmxbase dans Python, je dois recompiler Python-2.7.2, ça ne fonctionne pas autrem


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,042 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales