Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: movement d'objet  (Lu 5129 fois)

0 Membres et 3 Invités sur ce sujet

davs63

  • Newbie
  • *
  • Messages: 17
    • Voir le profil
movement d'objet
« le: Février 17, 2014, 08:09:15 pm »
Bonjour :)

J'aimerai créer une classe qui affiche un personnage à l’écran et ses mouvements

j'ai lue dans le forum qu'on ne pouvait pas hériter de sf.Sprite mais uniquement de sf.Drawable ou sf.TransformableDrawable et à l’intérieur on crée le sprite qui affichera un bout de la texture

J'ai donc codé une petite classe Perso

Mais quand je veux bouger le personnage ( avec .move(x,y) ) il ne bouge pas. .position n'a aucun effet non plus. La position de l'objet change mais pas le sprite. J'ai l'impression que le sprite est indépendant de l'objet

Qu'est ce que j'ai oublié ? :)

import sfml as sf

# ----- CLASSE -----

class Perso (sf.TransformableDrawable) :

    def __init__(self,texture):
        sf.Drawable.__init__(self)
        print("perso chargé ! ")
        self.imgTexture = sf.Texture.from_file(texture)
        self.persoSprite = sf.Sprite(self.imgTexture)
       
    def getImage(self,direction):
        if   direction == 'down' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 0), (32, 32))
        elif direction == 'up' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 96), (32, 32))
        elif direction == 'left' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 32), (32, 32))
        elif direction == 'right' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 64), (32, 32))
        else :
            print("ERROR : class Perso : ... ")
           
    def draw(self, target, states):
        states = sf.RenderStates()
        target.draw(self.persoSprite,states)


# ----- MAIN -----
       
if __name__ == '__main__' :

    window = sf.RenderWindow(sf.VideoMode(800, 600), "PySFML test")
    window.framerate_limit = 60
   
    # On crée une instance de Perso()
    player = Perso('resources/mperso.png')
    player.getImage('down')
    player.position = (150, 50)
   
    # On démarre la boucle de jeu
    while window.is_open :
        # on gère les évènements
        for event in window.events :
            if type(event) is sf.CloseEvent :
                window.close()
       
        # On dessine le niveau
        window.clear()
        window.draw(player)  
        player.move(sf.Vector2(2,0))
        print(player.position)

        window.display()  

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : movement d'objet
« Réponse #1 le: Février 17, 2014, 08:17:23 pm »
Comme indiqué dans le tutoriel, il faut passer la transformation de ton objet aux RenderStates quand tu dessines le sprite. Sinon, personne n'en a connaissance et effectivement elle ne peut pas être appliquée ;)

Par contre je ne sais pas quelle est la syntaxe pour le binding Python, donc je te laisse voir les détails.
Laurent Gomila - SFML developer

davs63

  • Newbie
  • *
  • Messages: 17
    • Voir le profil
Re : movement d'objet
« Réponse #2 le: Février 17, 2014, 11:39:11 pm »
le tuto indique la ligne :

states.transform.combine(self.transformable.transform)

à mettre dans la methode draw de l'objet

je fais un copié collé du tuto :

class MyDrawable(sf.TransformableDrawable):
    def __init__(self):
        sf.Drawable.__init__(self)

    def draw(self, target, states):
        states.transform.combine(self.transformable.transform)
        target.draw(body)
        target.draw(clothes)

mydrawable = MyDrawable()
mydrawable.position = (20, 30) # we have properties \o/

Et sur mon code quand j'applique cette ligne ça me plante python

screenshot en fichier join


Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : movement d'objet
« Réponse #3 le: Février 17, 2014, 11:49:07 pm »
Aucune idée, désolé.

Par contre si tu ne repasses pas les states en paramètre quand tu dessines tes sprites, ça n'aura toujours aucun effet ;)

target.draw(body, states)
target.draw(clothes, states)

(mais ça ne résoudra probablement pas ton crash)
Laurent Gomila - SFML developer

davs63

  • Newbie
  • *
  • Messages: 17
    • Voir le profil
Re : movement d'objet
« Réponse #4 le: Février 18, 2014, 12:07:06 pm »
Justement :) je le met le states ( avec ou sans ça n'a aucun effet apparemment )

    def draw(self, target, states):
        states.transform.combine(self.transformable.transform)
        target.draw(self.persoSprite, states)
 

alors que dans le tuto il ne le mettent pas :

    def draw(self, target, states):
        states.transform.combine(self.transformable.transform)
        target.draw(body)
        target.draw(clothes)

c'est cette ligne qui crée le probleme :

        states.transform.combine(self.transformable.transform)

Et je comprend pas trop ce que ce code fait.

Le mot combine n'existe pas en python il me semble donc c'est un membre de RenderStates je suppose ? mais je ne le trouve pas non plus dans l'API référence


Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : movement d'objet
« Réponse #5 le: Février 18, 2014, 12:55:11 pm »
Citer
alors que dans le tuto il ne le mettent pas
Bizarre, ça doit être une erreur.

Citer
Et je comprend pas trop ce que ce code fait
Il combine la transformation qui est stockée dans les states, avec la transformation de ton objet.

Note que tu pourrais aussi faire ça :
states.transform = self.transformable.transform
... ça ignorerait la transformation des states, mais comme dans la plupart des cas il n'y en a pas, ça peut au moins te permettre de tester et éventuellement de continuer d'avancer en attendant.

Citer
Le mot combine n'existe pas en python il me semble donc c'est un membre de RenderStates je suppose ? mais je ne le trouve pas non plus dans l'API référence
C'est une fonction de sf.Transformable, puisque tu l'appliques à states.transform et non à states directement ;)
Laurent Gomila - SFML developer

davs63

  • Newbie
  • *
  • Messages: 17
    • Voir le profil
Re : movement d'objet
« Réponse #6 le: Février 18, 2014, 01:21:51 pm »
Après tes explication et moults essais :) j'ai enfin trouvé. Je pense qu'il y a quelques erreurs dans le tuto

donc effectivement il faut bien le states dans  :       

target.draw(self.persoSprite, states)

logique :)

mais dans la ligne qui génère une erreur

states.transform.combine(self.transformable.transform)

il y a un mot de trop : transformable

et sans ce mot cela fonctionne parfaitement, donc :

states.transform.combine(self.transform)

ou

states.transform = self.transform

_________________


Et voici le code complet pour ceux qui veulent un Sprite qui peut bouger :)

import sfml as sf

class Perso (sf.TransformableDrawable) :
   
    def __init__(self,texture):
        sf.Drawable.__init__(self)

        # Chargement de la texture et creation du sprite qui l'utilisera
        self.imgTexture = sf.Texture.from_file(texture)
        self.persoSprite = sf.Sprite(self.imgTexture)
       
    def getImage(self,direction):
       
        # en fonction du parametre 'direction' on decoupe un morceau (sf.Rectangle)
        # de la texture pour la plaquer sur le sprite
        if   direction == 'down' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 0), (32, 32))
            # self.persoSprite.color = sf.Color(255,0,255,250)
        elif direction == 'up' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 96), (32, 32))
        elif direction == 'left' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 32), (32, 32))
        elif direction == 'right' :
            self.persoSprite.texture_rectangle = sf.Rectangle((0, 64), (32, 32))
        else :
            print("ERROR : class Perso : ... ")
           
    def draw(self, target, states):
   
        # Transmission des parametres de transformation de l'obet Perso aux RenderStates ( states )
        states.transform.combine(self.transform)
        # Dessin du srpite avec le RenderStates precedement definie
        target.draw(self.persoSprite, states)

       
       
if __name__ == '__main__' :

    # Creation de la fenetre
    window = sf.RenderWindow(sf.VideoMode(800, 600), "PySFML test")
    # Limitation à 60 FPS
    window.framerate_limit = 60
    # Instance de la classe Perso en indiquant l'image qui servira de texture
    player = Perso('resources/mperso.png')
    player.getImage('down')
    # Position de l'objet
    player.position = sf.Vector2(150, 50)

   
    # On démarre la boucle de jeu
    while window.is_open :
        # on gère les évènements
        for event in window.events :
            if type(event) is sf.CloseEvent :
                window.close()
       
        # Effase le contenue de la fenetre
        window.clear()
        # Transformation de l'objet
        player.move(sf.Vector2(1,0))
        player.rotate(1)
        # Affichage de l'objet
        window.draw(player)  
        # Rafraichissement de la fenetre
        window.display()    
« Modifié: Février 18, 2014, 03:01:32 pm par davs63 »