Et en plus avec cette dernière "subtilité" ton système devient hyper souple, car tu peux lister des séries d'animations à la suite dans ton tableau, et dés lors tu n'as plus qu'à les lancer par l'appel de la bonne frame, et ensuite l'animation se déroule toute seule en boucle jusqu'à interruption (qui peut être ou appelle d'une autre anim, ou mise de la variable de frame à "0").
Tu peux aussi gérer ainsi automatiquement des animations au nombre de frame variable, ou encore optimiser les transitions entre deux animations ayant le même nombre de frame, en faisant correspondre pour chaque animation le même numéro de frame à une posture proche (p.ex. pour une transition animation de marche -> animation de course), et donc avoir un passage d'une anim à l'autre par un décalage du pointeur de frame (+ xx) plutôt qu'un appel de la première frame de la nouvelle animation.
Puis espérer que le pathfinding des deux éléments soient le même alors même que leurs coordonnées de départ et d'arrivé sont sensiblement différentes (y+3).
Ah oui, oups, si tu utilise du pathfinding pour les deux éléments, avec en plus des coordonnées différentes, le résultat peut devenir aléatoire... :/
C'est vrai que je ne connais pas Wintermute après, alors j'ai peut-être bien une vision qq peu "simpliste" de ton problème :P.
En y réfléchissant, je me rends compte que je n'ai tout simplement pas les coordonnées d'arrivée.
Le joueur peut cliquer dans le ciel, ça fera quand même avancer le personnage dans la direction du clic (mais il ne marchera pas jusqu'aux coordonnées exactes du clic puisqu'il ne peut pas aller dans le ciel). C'est le système de pathfinding qui calcule la destination du personnage et le chemin qu'il emprunte.
Comment est codé ce déplacement irrégulier du sprite?
C'est Wintermute qui s'en charge.
L'éditeur de sprite fonctionne avec une interface visuelle : j'entre simplement les nombres et le logiciel se charge du reste.
C'est probablement parce qu'ensuite Wintermute doit se charger de recalculer ces données en fonction de la perspective (le personnage diminuant de taille quand il s'éloigne du premier plan).
En fait quand je codais je m'efforçais de virer à peu près tous les if possibles en utilisant ce genre de technique, parce que si on se laisse aller à la "facilité" que représente les conditions, on finit parfois par avoir des if en cascade avec des temps d'exécution de routine qui deviennent incontrôlables, et de toute façon inutilement longs.
Donc de manière générale, il vaut mieux éviter un surplus de "if".
C'est bon à savoir !
Donc de manière générale, il vaut mieux éviter un surplus de "if".
C'est pas une instruction "if" qui prend beaucoup de temps. Tant que l'on reste avec un "if" qui se contente de faire une comparaison, c'est aussi rapide que d'assigner une valeur à une variable. Ce qui pourrait éventuellement prendre plus de temps d'exécution, c'est si tu as des opérations plus lourdes à l'intérieur de ta condition.
D'ailleurs, lorsque l'on calcule la complexité d'un algorithme, les "if" n'entrent pas en jeu et c'est plutôt les boucles qui vont déterminer la complexité de celui-ci. Les boucles imbriquées, ça c'est certain, c'est à éviter au maximum.
Supprimer un maximum de "if", en plus de ne pas être forcément utile, va certainement rendre ton code moins clair lorsque tu seras amené à le relire pour le modifier.
Bah après c'est ma vision de la chose ^^.
Mais je suis plutôt auto-didcate en la matière, donc c'est peut-être pas la vision "officielle" d'un bon code ,et ça ne se justifie en fait peut-^tre pas vraiment :P.
Mais disons que p.ex., quand tu fais ton premier programme et que tu veux que l'utilisateur rentre une donnée chiffrée avec le clavier, et pas autre chose que des chiffres, le premier truc que tu fais en général c'est ce genre de chose:
Le problème, outre déjà le temps d'exécution si on tape "0" ou une touche non chiffrée, c'est que le temps d'exécution de ta routine est imprévisible! En effet, si on tape "1" l'exéctution va être très courte, mais moins si on tape "0"... Bon ok, c'est négligeable en soit de gérer 1 ou 10 if, mais démultiplier ce genre de choses dans toutes les routines qui passent, ça ne me semble pas l'idéal. Ça peut poser des problèmes à mon sens dés que tu travailles sur des projet "temps réel" comme un jeu justement, où tu dois avoir une bonne visibilité de la durée de chaque routine pour voir qu'est-ce-que tu vas pouvoir enchainer pendant une "boucle" de fonctionnement en gardant une bonne fluidité.
Dans cet exemple, une solution simple est d'avoir un tableau qui contienne autant de valeur que de touches sur le clavier (ça en fait un petit nombre tu me diras, mais pour le coup c'est RÉELLEMENT négligeable en terme de consommation de ressource) et qui renvoie la bonne "valeur" en fonction de la touche considéré (soit le chiffre correspondant pour une touche chiffrée, et -1 sinon).
Dés lors tout cela peut se réduire à:
C'est quand même mieux, non?
En plus comme je te le montrai déjà au-dessus, ce système de tableaux permet d'être très souple, tu peux enrichir les fonctionnalités en un rien de temps, et en manipulant essentiellement des données externes très simples, plutôt que ton code (qui reste simple, et cela réduit d'autant le risque d'introduire des bugs).
Par exemple imagine que finalement tu veuilles autoriser des nombres hexadécimaux, et non plus limiter l’utilisateur aux nombres décimaux: il te suffira de rajouter les valeurs 10 à 15 aux touches A à F dans la table de correspondance, le code lui n'a pas besoin d'être modifié. Trop facile!
Je n'ai pas vraiment suivi le fil de la discussion depuis la dernière fois. Qu'est est le problème finalement ? L'image de l'ombre ne suit pas Mizuka correctement ?
Je vais peut-être répondre à côté mais on ne sait jamais...
Est-ce que ça ne résoudrait pas le problème d'utiliser une image d'ombre qui soit exactement de la même taille que l'image de Mizuka, et positionnée exactement au même endroit, avec le même point de pivot ?
Par exemple avec les 2 images suivantes, si la zone grise représente la taille de ton image (où le blanc serait de l'alpha - de la transparence), est-ce que le fait de l'agrandir comme dans l'image 2, aux dimensions de Mizuka, ne résoudrait pas une partie du problème ? Elle réagirait logiquement de la même façon, non ?
(alors effectivement ce n'est pas pro car ça bouffe de la mémoire inutilement, mais si ça fonctionnait ça serait un premier pas)
Aussi j'ai lu dans un de tes messages précédents, que l'ombre arrive après Mizuka. Est-ce que ce n'est pas lié au fait que tu la places à une distance de 3 pixels plus loin en profondeur ?
Je ne sais pas si ça le fait dans Wintermute, mais généralement quand tu superposes des calques à des profondeurs différentes, celui du fond bouge moins vite à l'écran que celui du premier plan. Tu vois ce que je veux dire ?
Moi ya un truc plus trivial que j'ai pas bien saisi en fait ^^.
Tu ne peux pas simplement recalculer la localisation de l'ombre UNIQUEMENT pendant les phases d'animation de notre petite nipponne, et quand il n'y a pas d'animation/déplacement, laisser dés lors les choses fixes, sans recalculer la position de l'ombre perpétuellement mêm lorsque rien ne se passe? Et en fait même juste recalculer ce positionnement une seule fois à chaque frame d'anim, et c'est tout?
J'ai l'impression qu'on s'éloigne complètement du sujet initial mais bon. Le "problème" du code que tu montres là Nival, c'est que c'est un cas extrêmement simple. Si tu veux faire plus qu'une simple assignation ou tout simplement faire plusieurs assignations, ta technique ne pourra pas être utilisée facilement. Dans le cas des multiples assignations, on pourrait à la limite faire plusieurs tableaux en utilisant le même indice mais ça devient déjà plus laborieux. Dans le cas où tu voudrais par exemple appeler une fonction particulière lorsqu'un utilisateur entre un nombre particulier, cela devient vachement plus complexe.
Par exemple, je m'imagine mal faire un menu avec un tableau comme tu le fais ici dans ton exemple. La plupart du temps, le but sera de faire bien plus qu'une simple assignation et ta technique tomberait donc à l'eau ici.
Après j'admets que dans un cas très simple, cela puisse fonctionner. Je ne suis pas sûr par contre que la différence à l'exécution soit notable. Quoi qu'il arrive, pour qu'elle soit notable, il faudrait faire des tests avec bien plus que 10 valeurs. Ce qui m'embête par contre, c'est que je trouve qu'on en perd en lisibilité. C'est bien plus simple, à mon goût, de savoir ce qui se passe lorsque l'utilisateur appuie sur "5" en relisant le code dans le premier exemple que dans celui plus concis. On verra directement dans notre code "si valeur = 5 alors..." tandis que dans un tableau, on devra repérer nous même le 5ème élément (ou le 6ème, on se comprend ^^).
Dans la plupart des problèmes auxquels on est confronté en programmation, il y a bien souvent plus d'une manière de les résoudre. Certaines solutions sont clairement mauvaises tandis que plusieurs autres peuvent être bonnes.
Enfin bref, tout ça, ça touche à de la programmation pure et dure, je ne suis pas sûr que ce soit le bon endroit pour parler de ça. Après, si une autre discussion s'ouvre à ce sujet, je serais ravi de donner mon avis et de partager mes opinions avec celles des autres membres du Forum.
Je n'ai pas vraiment suivi le fil de la discussion depuis la dernière fois. Qu'est est le problème finalement ? L'image de l'ombre ne suit pas Mizuka correctement ?
Le premier script fonctionnait bien à l'écran mais on a attiré mon attention sur le fait qu'il s'agissait d'une boucle recalculant des positions et ré-affichant des sprites toutes les 10ms... même quand le personnage ne bouge pas.
J'ai essayé sans boucle, en liant directement le déplacement de l'ombre aux frames du perso via un système d'événements. Mais c'était la cata : l'ombre prenait du retard et s'arrêtait souvent à côté du perso.
Je suis revenu à la boucle en essayant de l'optimiser pour qu'elle ne calcule des positions / affiche des sprites que quand c'est nécessaire.
Quand j'y serai arrivé, ce sera bien car ça évitera des calculs inutiles.
A suivre !
Tu ne peux pas simplement recalculer la localisation de l'ombre UNIQUEMENT pendant les phases d'animation de notre petite nipponne, et quand il n'y a pas d'animation/déplacement, laisser dés lors les choses fixes, sans recalculer la position de l'ombre perpétuellement mêm lorsque rien ne se passe?
C'est ce que j'essaie de faire sur les conseils de ConceptGame mais c'est plus compliqué que prévu...
Il y a quelque subtilités : notamment le fait que si le joueur clique très prêt du point de pivot du personnage, celui-ci bougera très légèrement... sans pour autant marcher !
En l'état, on peut faire des sauts de puce et s'éloigner petit à petit de son ombre. C'est très rigolo mais je peux quand même pas laisser ça dans le jeu !
Et en plus avec cette dernière "subtilité" ton système devient hyper souple, car tu peux lister des séries d'animations à la suite dans ton tableau, et dés lors tu n'as plus qu'à les lancer par l'appel de la bonne frame, et ensuite l'animation se déroule toute seule en boucle jusqu'à interruption (qui peut être ou appelle d'une autre anim, ou mise de la variable de frame à "0").
Tu peux aussi gérer ainsi automatiquement des animations au nombre de frame variable, ou encore optimiser les transitions entre deux animations ayant le même nombre de frame, en faisant correspondre pour chaque animation le même numéro de frame à une posture proche (p.ex. pour une transition animation de marche -> animation de course), et donc avoir un passage d'une anim à l'autre par un décalage du pointeur de frame (+ xx) plutôt qu'un appel de la première frame de la nouvelle animation.
Ah oui, oups, si tu utilise du pathfinding pour les deux éléments, avec en plus des coordonnées différentes, le résultat peut devenir aléatoire... :/
C'est vrai que je ne connais pas Wintermute après, alors j'ai peut-être bien une vision qq peu "simpliste" de ton problème :P.
En y réfléchissant, je me rends compte que je n'ai tout simplement pas les coordonnées d'arrivée.
Le joueur peut cliquer dans le ciel, ça fera quand même avancer le personnage dans la direction du clic (mais il ne marchera pas jusqu'aux coordonnées exactes du clic puisqu'il ne peut pas aller dans le ciel). C'est le système de pathfinding qui calcule la destination du personnage et le chemin qu'il emprunte.
C'est Wintermute qui s'en charge.
L'éditeur de sprite fonctionne avec une interface visuelle : j'entre simplement les nombres et le logiciel se charge du reste.
C'est probablement parce qu'ensuite Wintermute doit se charger de recalculer ces données en fonction de la perspective (le personnage diminuant de taille quand il s'éloigne du premier plan).
Donc de manière générale, il vaut mieux éviter un surplus de "if".
C'est bon à savoir !
Et merci pour toutes ces pistes !
C'est pas une instruction "if" qui prend beaucoup de temps. Tant que l'on reste avec un "if" qui se contente de faire une comparaison, c'est aussi rapide que d'assigner une valeur à une variable. Ce qui pourrait éventuellement prendre plus de temps d'exécution, c'est si tu as des opérations plus lourdes à l'intérieur de ta condition.
D'ailleurs, lorsque l'on calcule la complexité d'un algorithme, les "if" n'entrent pas en jeu et c'est plutôt les boucles qui vont déterminer la complexité de celui-ci. Les boucles imbriquées, ça c'est certain, c'est à éviter au maximum.
Supprimer un maximum de "if", en plus de ne pas être forcément utile, va certainement rendre ton code moins clair lorsque tu seras amené à le relire pour le modifier.
Bah après c'est ma vision de la chose ^^.
Mais je suis plutôt auto-didcate en la matière, donc c'est peut-être pas la vision "officielle" d'un bon code ,et ça ne se justifie en fait peut-^tre pas vraiment :P.
Mais disons que p.ex., quand tu fais ton premier programme et que tu veux que l'utilisateur rentre une donnée chiffrée avec le clavier, et pas autre chose que des chiffres, le premier truc que tu fais en général c'est ce genre de chose:
Le problème, outre déjà le temps d'exécution si on tape "0" ou une touche non chiffrée, c'est que le temps d'exécution de ta routine est imprévisible! En effet, si on tape "1" l'exéctution va être très courte, mais moins si on tape "0"... Bon ok, c'est négligeable en soit de gérer 1 ou 10 if, mais démultiplier ce genre de choses dans toutes les routines qui passent, ça ne me semble pas l'idéal. Ça peut poser des problèmes à mon sens dés que tu travailles sur des projet "temps réel" comme un jeu justement, où tu dois avoir une bonne visibilité de la durée de chaque routine pour voir qu'est-ce-que tu vas pouvoir enchainer pendant une "boucle" de fonctionnement en gardant une bonne fluidité.
Dans cet exemple, une solution simple est d'avoir un tableau qui contienne autant de valeur que de touches sur le clavier (ça en fait un petit nombre tu me diras, mais pour le coup c'est RÉELLEMENT négligeable en terme de consommation de ressource) et qui renvoie la bonne "valeur" en fonction de la touche considéré (soit le chiffre correspondant pour une touche chiffrée, et -1 sinon).
Dés lors tout cela peut se réduire à:
C'est quand même mieux, non?
En plus comme je te le montrai déjà au-dessus, ce système de tableaux permet d'être très souple, tu peux enrichir les fonctionnalités en un rien de temps, et en manipulant essentiellement des données externes très simples, plutôt que ton code (qui reste simple, et cela réduit d'autant le risque d'introduire des bugs).
Par exemple imagine que finalement tu veuilles autoriser des nombres hexadécimaux, et non plus limiter l’utilisateur aux nombres décimaux: il te suffira de rajouter les valeurs 10 à 15 aux touches A à F dans la table de correspondance, le code lui n'a pas besoin d'être modifié. Trop facile!
Je n'ai pas vraiment suivi le fil de la discussion depuis la dernière fois. Qu'est est le problème finalement ? L'image de l'ombre ne suit pas Mizuka correctement ?
Je vais peut-être répondre à côté mais on ne sait jamais...
Est-ce que ça ne résoudrait pas le problème d'utiliser une image d'ombre qui soit exactement de la même taille que l'image de Mizuka, et positionnée exactement au même endroit, avec le même point de pivot ?
Par exemple avec les 2 images suivantes, si la zone grise représente la taille de ton image (où le blanc serait de l'alpha - de la transparence), est-ce que le fait de l'agrandir comme dans l'image 2, aux dimensions de Mizuka, ne résoudrait pas une partie du problème ? Elle réagirait logiquement de la même façon, non ?
(alors effectivement ce n'est pas pro car ça bouffe de la mémoire inutilement, mais si ça fonctionnait ça serait un premier pas)
Aussi j'ai lu dans un de tes messages précédents, que l'ombre arrive après Mizuka. Est-ce que ce n'est pas lié au fait que tu la places à une distance de 3 pixels plus loin en profondeur ?
Je ne sais pas si ça le fait dans Wintermute, mais généralement quand tu superposes des calques à des profondeurs différentes, celui du fond bouge moins vite à l'écran que celui du premier plan. Tu vois ce que je veux dire ?
http://www.theicehouse.fr
Moi ya un truc plus trivial que j'ai pas bien saisi en fait ^^.
Tu ne peux pas simplement recalculer la localisation de l'ombre UNIQUEMENT pendant les phases d'animation de notre petite nipponne, et quand il n'y a pas d'animation/déplacement, laisser dés lors les choses fixes, sans recalculer la position de l'ombre perpétuellement mêm lorsque rien ne se passe? Et en fait même juste recalculer ce positionnement une seule fois à chaque frame d'anim, et c'est tout?
J'ai l'impression qu'on s'éloigne complètement du sujet initial mais bon. Le "problème" du code que tu montres là Nival, c'est que c'est un cas extrêmement simple. Si tu veux faire plus qu'une simple assignation ou tout simplement faire plusieurs assignations, ta technique ne pourra pas être utilisée facilement. Dans le cas des multiples assignations, on pourrait à la limite faire plusieurs tableaux en utilisant le même indice mais ça devient déjà plus laborieux. Dans le cas où tu voudrais par exemple appeler une fonction particulière lorsqu'un utilisateur entre un nombre particulier, cela devient vachement plus complexe.
Par exemple, je m'imagine mal faire un menu avec un tableau comme tu le fais ici dans ton exemple. La plupart du temps, le but sera de faire bien plus qu'une simple assignation et ta technique tomberait donc à l'eau ici.
Après j'admets que dans un cas très simple, cela puisse fonctionner. Je ne suis pas sûr par contre que la différence à l'exécution soit notable. Quoi qu'il arrive, pour qu'elle soit notable, il faudrait faire des tests avec bien plus que 10 valeurs. Ce qui m'embête par contre, c'est que je trouve qu'on en perd en lisibilité. C'est bien plus simple, à mon goût, de savoir ce qui se passe lorsque l'utilisateur appuie sur "5" en relisant le code dans le premier exemple que dans celui plus concis. On verra directement dans notre code "si valeur = 5 alors..." tandis que dans un tableau, on devra repérer nous même le 5ème élément (ou le 6ème, on se comprend ^^).
Dans la plupart des problèmes auxquels on est confronté en programmation, il y a bien souvent plus d'une manière de les résoudre. Certaines solutions sont clairement mauvaises tandis que plusieurs autres peuvent être bonnes.
Enfin bref, tout ça, ça touche à de la programmation pure et dure, je ne suis pas sûr que ce soit le bon endroit pour parler de ça. Après, si une autre discussion s'ouvre à ce sujet, je serais ravi de donner mon avis et de partager mes opinions avec celles des autres membres du Forum.
Yep, t'as raison!
Ici pour la suite --> http://www.indiemag.fr/forum/blabla-general-du-forum/t2486-programmation-utilisation-memoire-vs-utilisation-cpu
Le premier script fonctionnait bien à l'écran mais on a attiré mon attention sur le fait qu'il s'agissait d'une boucle recalculant des positions et ré-affichant des sprites toutes les 10ms... même quand le personnage ne bouge pas.
J'ai essayé sans boucle, en liant directement le déplacement de l'ombre aux frames du perso via un système d'événements. Mais c'était la cata : l'ombre prenait du retard et s'arrêtait souvent à côté du perso.
Je suis revenu à la boucle en essayant de l'optimiser pour qu'elle ne calcule des positions / affiche des sprites que quand c'est nécessaire.
Quand j'y serai arrivé, ce sera bien car ça évitera des calculs inutiles.
A suivre !
C'est ce que j'essaie de faire sur les conseils de ConceptGame mais c'est plus compliqué que prévu...
Il y a quelque subtilités : notamment le fait que si le joueur clique très prêt du point de pivot du personnage, celui-ci bougera très légèrement... sans pour autant marcher !
En l'état, on peut faire des sauts de puce et s'éloigner petit à petit de son ombre. C'est très rigolo mais je peux quand même pas laisser ça dans le jeu !
Je reviens dès que ça fonctionne !
Pages