Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 3 sur 3
  1. #1
    Invité de passage
    Inscrit en
    janvier 2012
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : janvier 2012
    Messages : 1
    Points : 0
    Points
    0

    Par défaut [SFML] Problème de fluidité lors du déplacement de la vue

    Bonjour,

    Pour "m'amuser", j'ai décidé de créer une sorte de mini rpg en python en 3D isométrique et pour cela je suis parti à la recherche d'une bibliothèque. J'ai entendu du bien de SFML, j'ai donc décidé de l'utiliser . Enfin bref le problème est le suivant: sur la fenêtre, ce n'est pas mon personnage qui se déplace mais le fond et cela donne l'illusion que c'est le perso qui bouge (classique :p ). Le problème est que le fond est tellement lent à charger, que cela parrait saccadé. Pourtant je ne charge pas l'image à chaque animation, ... . En gros voici mon code (avec des commentaires pour que vous compreniez comment ca marche sans spécialement utiliser SFML):
    Code :
    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
    #coding: utf8
    from PySFML import sf
    import config as cfg
     
    def dessinerFenetre(fenetre,elements):
        """ Fonction qui prend en paramètre ne liste elements d'objets à afficher
        afficher sur l'objet fenetre """
        fenetre.Clear(sf.Color.Black)
        for i in elements:
            fenetre.Draw(i)
        fenetre.Display()
     
    # On va créer un objet fenetre en mettant une limite de FPS et une certaine définition
    fenetre = sf.RenderWindow(sf.VideoMode(cfg.RESOLUTION[0],cfg.RESOLUTION[1],32), "Arkuria", sf.Style.Close)
    fenetre.SetFramerateLimit(60)
     
    IBackground = sf.Image()
    IBackground.LoadFromFile("default.png") #On charge le background qu'on met dans un objet image créé précédemment
    background = sf.Sprite(IBackground) #On met l'image dans un sprite (les images ne sont pas affichagle tel quel
    vue = sf.View() #On crée un objet View (fonctionnement expliqué en abs du code
    vue.SetHalfSize(cfg.RESOLUTION[0]/2,cfg.RESOLUTION[1]/2) #on définit le centre de la view
    vue.SetCenter(1500,1050) #On définit le nombre de pixel de l'image qui va devoir être affiché 
    fenetre.SetView(vue) #on applique la vue à notre fenetre
     
    while fenetre.IsOpened():
        EventHandler = sf.Event()
        while fenetre.GetEvent(EventHandler):
            """ Boucle d'évenement qui en fonction de l'appui sur les touches Z,Q,S ou D, déplace le
            fond d'écran afin de donner l'impression que le personnage bouge. Pour cela, on déplace la vue
            soit de 70px en hateur par pas de 7px, soit de 100px en largeur par pas de 10px (ce qui n'est pas énorme).
            On fait à chaque fois appel à la fonction dessiner fenetre ci-dessus pour rafraichir la fenetre """
            if EventHandler.Type == sf.Event.Closed:
                fenetre.Close()
            if EventHandler.Type == sf.Event.KeyPressed:
                if EventHandler.Key.Code == sf.Key.Escape:
                    fenetre.Close()
                if EventHandler.Key.Code == sf.Key.Z:
                    for i in range(10):
                        vue.Move(0,-7)
                        dessinerFenetre(fenetre,[background])
                if EventHandler.Key.Code == sf.Key.S:
                    for i in range(10):
                        vue.Move(0,7)
                        dessinerFenetre(fenetre,[background])
                if EventHandler.Key.Code == sf.Key.Q:
                    for i in range(10):
                        vue.Move(-10,0)
                        dessinerFenetre(fenetre,[background])
                if EventHandler.Key.Code == sf.Key.D:
                    for i in range(10):
                        vue.Move(10,0)
                        dessinerFenetre(fenetre,[background])
        dessinerFenetre(fenetre,[background])
    Explication du système de vue : Il permet de se focaliser sur une seule partie de notre fenêtre. Par exemple là j'avais chargé une image comme fond d'écran de 3000px sur 2100 donc forcement elle dépassait de la fenetre (c'est le but hein c'est pour faciliter le mouvement du fond lors du déplacement du perso) et j'ai pu donc définir le centrage de la vue sur le centre de mon image de fond et ainsi lorsque je veux déplacer mon personnage, il me suffit juste de déplacer le centrage de ma vue pour bouger l'image de fond Je sais pas si je suis assez clair ^^"

    Voilà une vidéo de ce qu'il se passe chez moi: [ame="http://www.youtube.com/watch?v=bIOpCT_K23o"]Bug - YouTube[/ame] (j'ai vite collé un perso au centre de mon image pour vérifier que l'image était bien centrée ^^)

    Enfin le problème est que le mouvement se fait en saccadé, alors que je ne met aucun time.sleep() ou que ce soit pour retarder l'affichage, ... Je ne comprends donc pas pourquoi est-ce tant saccadé alors que cela devrait se faire immédiatement. Est-ce parce que j'ai atteind le seuil de la puissance de la bibliothèque ^^ ? Pourtant je pense que la fonction view a été faite pour cela et un image de 3000 sur 2100 pixel ce n'est pas si grand ^^ . Ou alors c'est que j'ai fais quelque chose mal (j'espère que c'est ça :p ) et dans ce cas je vous demande de l'aide car je ne comprends pas trop de ou vient mon erreur :/ .

    Merci d'avance pour vos réponses,
    Maxime

  2. #2
    Invité de passage
    Homme Profil pro
    Inscrit en
    janvier 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : janvier 2012
    Messages : 1
    Points : 1
    Points
    1

    Par défaut

    Bonjour. Le problème comme avec Pygame, c'est que la boucle tourne trop rapidement ; utilisant un maximum de ressources. Malheureusement, je ne connais pas PySFML.
    Sous pygame, j'aurais procédé comme suit:

    - Utiliser: fenetre.WaitEvent(EventHandler) au lieu de fenetre.GetEvent(EventHandler)

    - Si l'utilisation de: fenetre.GetEvent(EventHandler) s'impose, faire comme ci-dessous.
    Code :
    horloge = pygame.time.Clock() #Je ne connais pas l'équivalent PySFML. Puis juste après la création de ta boucle principale, faire.
    Code :
    1
    2
    3
    while fenetre.IsOpened():
        horloge.tick(temps_en_millisecondes)
        EventHandler = sf.Event()

    Lorsque ton problème sera résolu, peux-tu me le signaler ?
    Bonne chance à toi.

  3. #3
    Membre chevronné
    Homme Profil pro
    Inscrit en
    avril 2004
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : avril 2004
    Messages : 754
    Points : 793
    Points
    793

    Par défaut

    c'est étrange, j'ai répondu à la même question en MP il y a quelques semaines sur un autre forum, mais je n'ai pas eu de retour ...

    bref, je penche pour la vitesse de répétition des touches ...
    sous pygame on a key.set_repeat() pour régler ça. Je ne connais pas vraiment SFML mais je suppose que ça doit être aussi configurable.

    bienvenu realmagma, by the way ...

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •