[Tutoriel] Le Super DrawStat
Posté le 08/09/2013 19:36
Vous connaissez le DrawStat, et bien voici le Super DrawStat !
Pour ceux qui ne connaissent pas le DrawStat
Cliquer pour enrouler
Ce tutoriel décrit une méthode permettant dessiner des traits à l'écran. On renseigne dans deux List les coordonnées sur x et sur y de plusieurs points, puis on relie tout ces points entre eux pour faire une image
Le Super DrawStat se comporte de la même façon que le DrawStat normal, cependant la vitesse à laquelle il dessine est bien plus rapide, environ 20% à 40% pour un tracé identique. Et encore plus rapide que les F-line. Voici comment l'utiliser :
Initialisation :
Le Super DrawStat s'initialise en même temps que le ViewWindow, il suffit de rajouter à la suite les trois composantes d'initialisation.
Le paramétrage classique est ViewWindow 1,127,0,1,63,0 Il suffit de rajouter à la suite : ,
MIN,
MAX,
PAS
MIN correspondant à la valeur de départ (1 en général)
MAX la dernière valeur (la taille des List en général)
PAS la valeur dont T (Voir plus bas) augmente à chaque fois, (1 en général)
Pour choisir le dessin à tracer, il suffit de rentrer dans deux List les coordonnées x et y du dessin.
Utilisation :
Il faut utiliser la commande.
Graph(X,Y)=(
Graph(X,Y) est une commande trouvable à l'adresse : SHIFT F4 F5 F3
cette fonction prend deux arguments : la première List correspondant aux x, et la seconde List correspondant aux y.
Voici ce que cela donne au complet
Graph(X,Y)=(List 1[T],List 2[T])
Il est obligatoire de mettre [T], et uniquement T sinon cela ne fonctionnera pas. La variable T est la variable qui va permettre de "lire" le dessin.
Elle commence avec la valeur MIN définie par le ViewWindow, et augmente de PAS jusqu'a arriver à MAX. Il est donc important de bien paramétrer le ViewWindow avec des nombres entiers pour pas avoir une situation telle que List 1[3.7] si T prend la valeur 3.7, ce qui provoque une erreur.
Exemple :
Voici par exemple comment tracer un triangle formé par les points A(10;7), B(30;54) et C(18;29).
La List 1 enregistre les coordonnées des points sur l'axe x, et la List 2 sur l'axe y. Ensuite on trace un trait entre chaque points pour former le triangle. (Il y a 4 points pour refermer le triangle
)
ViewWindow 1,127,0,1,63,0,1,4,1
{10,30,18,10}->List 1
{7,54,29,7}->List 2
Graph(X,Y)=(List 1[T],List 2[T])
Astuces :
Voilà, maintenant vous avez les bases pour pouvoir utilisez le SuperDrawStat, mais son véritable atout réside dans sa flexibilité et sa liberté d'utilisation. Voici quelques astuces très utiles pour exploiter au maximum cette fonction.
Utilisez Tomin, Tomax et Toptch (VARS F1 F3) pour lire et modifier les paramètres d'initialisation MIN, MAX et PAS
MAX doit être inférieur ou égale à la taille des List.
En jouant sur ces paramètres on peut donc dessiner que les 3 premiers traits du dessins, un traits sur deux, que les derniers, ...
Attention, modifier ces paramètres modifient le ViewWindow, c'est à dire qu'au prochain dessin, l'écran sera effacé.
Il est aussi possible de dessinez avec un style de trait différent :
-traits continus : G-Connect(SHIFT MENU F6 F3)
-des points : G-Plot (SHIFT MENU F6 F3)
-traits simples : S-L-Normal (SHIFT MENU F6 F2)
-traits épais : S-L-Thick (SHIFT MENU F6 F2)
-pointillets épais : S-L-Broken (SHIFT MENU F6 F2)
-pointillets : S-L-Dot (SHIFT MENU F6 F2)
Il est possible d'utilisez des équations à la place des List :
Graph(X,Y)=(List 1[T],4)
Graph(X,Y)=(17xList 1[4T],List 2[T]+4)
Graph(X,Y)=(15+T,List 1[T])
...
(La variable qui évolue c'est T, pas X)
Ainsi on peut éviter de créer des List simple comme par exemple {0,1,2,3,...} en remplacant par T qui va prendre successivement ces valeurs (tout dépend du paramétrage bien entendu).
Vous pouvez facilement effectuer un décalage pour afficher vos images.
Par exemple imaginons que vous avez enregistré l'image d'un personnage, dans les List 1 et List 2
En DrawStat
Cliquer pour enrouler
Pour l'afficher aux coordonnées I et J vous deviez faire en DrawStat
{...}->List 1
{...}->List 2
S-Gph1 DrawOn,xyline,List 3,List 4,1,Dot
...
I+List 1->List 3
J+List 2->List 4
DrawStat
On est obligé d'utiliser des List 3 et List 4 pour ne pas modifier les List 1 et List 2 qui enregistrent l'image.
Tandis que en Super DrawStat, on peut s'en passer
{...}->List 1
{...}->List 2
Dim List 1->Tomax
Graph(X,Y)=(I+List 1[T],J+List 2[T])
Dim List 1 permet de récupérer la taille de la List 1. On n'utilise jamais les variables X et Y, elles sont modifiées par les fonctions graphiques donc le résultat ne sera pas ce à quoi vous vous attendiez
Il est également possible de ne pas relier deux points consécutifs dans les List. Par exemple si notre dessin est en plusieurs parties (imaginons un personnage et ses yeux).
L'astuce consiste à rajouter un point trop éloigné pour que la calculette ne le dessine pas et passe au suivant.
par exemple
{10,23,7,e9,12,3}-List 1
{34,30,7,e9,2,3}-List 2
e9 est une façon courte d'écrire 1000000000
Encore plus de vitesse ? Dessiner à la chaîne !
Il arrive que dans certains jeux, il faille dessiner beaucoup d'images à la suite.
Je vais prendre l'exemple d'une carte que l'on veut dessiner en utilisant le principe des
Tiles, ou tuiles en français (entre autres pokemon), on pense naturelement à parcourir dans une boucle toutes les cellules de notre Mat, List, ... qui enregistre notre carte, et afficher les images les unes après les autres.
Cette méthode est simple, mais on voit l'image se construire au fur et à mesure. Le rendu n'est pas terrible et donne une impression de lenteur.
Pour résoudre ce problème, on va charger toutes les images dans une même List, puis tout afficher d'un coup !
Je vous présente la fonction Augment( OPTN F1 F6 F5
Cette fonction permet de mettre bout à bout deux List pour n'en former qu'une
{1,2,3}->List 1
{4,5,6}->List 2
Augment(List 1, List 2)->List 3
List 3 = {1,2,3,4,5,6}
Ainsi votre code pour afficher votre carte aura cette structure :
{e9}->List 1
{e9}->List 2
// boucle
// on récupère dans List 3 et List 4 l'image de tile
Augment(List 1, List 3)->List 1
Augment(List 2, List 4)->List 2
// fin de boucle
Dim List 1->Tomax
GraphXY(List 1[T], List 2[T])
On voit que GrapXY n'est utilisé qu'à la fin, avec les List 1 et 2 remplies, donc la carte est tracé en une fois beaucoup plus rapidement.
Pourquoi List 1 et 2 sont initialisées avec e9 ? Simplement que l'on ne peut pas initialiser des List vides, pour utiliser Augment, il faut au moins un élément dans chaque List.
Il reste une dernière précaution, ajouter e9 à la fin de chaque image, sinon elles seront toutes reliées, évidemment
Pour donner un ordre d'idées, le
gain de vitesse est de 10% pour dessiner des images d'une vingtaine de points et
35% pour dessiner des images avec peu de points. Le système est plus rentable, si le nombre de point par image et faible.
L'inconvénient c'est qu'il y a un temps d'attente, mais placer un Text 1,1,"Chargement" fait tellement pro
mais aussi que cette technique est gourmande en mémoire.
Exemple de jeux utilisant cette méthode :
Block Tower,
A vers B
Economisez les indices de List :
Deux List pour chaque image est assez gourmand en indice, même si il y en a 26 par fichier. Une autre astuce permet d'enregistrer dans une seule List à la fois les coordonnées sur x et sur y d'une image. Pour cela on va utiliser les complexes.
ViewWindow 1,127,0,1,63,0,1,4,1
{10,30,18,10}+i{7,54,29,7}->List 1
Graph(X,Y)=(ReP List 1[T],ImP List 1[T])
On renseigne dans une première accolade les coordonnées x, ensuite on rajoute le
i (SHIFT 0) puis on renseigne dans une deuxième accolade les coordonnées sur y. Rep et Imp permettent de séparer la partie sur x et la partie sur y (OPTN F3 F6). On remarquera que dans l'initialisation du ViewWindow, MAX est toujours égale à 4. La taille de List 1 est toujours 4 et pas 8. Attention, cette astuce ne permet pas de gagner de la mémoire : le poids en octet d'une telle List est multiplier par deux, ce qui pèse autant que deux List.
Performances :
J'ai fait des tests pour comparer les performances :
dessiner 128 traits une fois :
-DrawStat : 1,4 s
-Super DrawStat : 0,9 s
dessiner 3 traits 100 fois :
-DrawStat : 22,4 s
-Super DrawStat : 18,9 s
On voit clairement que le Super DrawStat est plus rapide, en fait le DrawStat affiche les points puis trace les traits alors que le Super DrawStat dessine directement les traits.
Inconvénients :
Il existe deux incovénients, d'une part cela utilise la variable T, qui devient donc inutilisable dans le programme.
D'autre part, il n'est pas possible de dessiner des petits carrés ou des croix comme en DrawStat.
Voilà, si découvrez d'autres astuces n'hésitez pas à les partager, il est en existe énormément
Regardez aussi le tutoriel sur le Multi DrawStat, pas forcement plus rapide, mais qui permet d'autres choses.
Citer : Posté le 12/05/2016 20:01 | #
Ce n'est pas plus ou moins ce dont on parlait implicitement avec Matt et Darkstorm en janvier ici même ?
Je vois des infinis mais pas d'Augment( personnellement... je pense que non. J'ai relu tout le topic et je ne vois aucune référence à cette technique
Citer : Posté le 12/05/2016 20:21 | #
Matt demandait comment dessiner deux carrés à la suite avec un même GraphXY, n'est-ce pas "dessiner à la chaîne", comme se prénomme la "nouveauté" ?
Et je maintiens qu'Augment pourra causer des glitchs si il n'y a pas d'infini entre les Lists, cf mon message précédent, on retombe sur ce qui avait été soulevé par Matt.
Pour moi l'ajout au post principal est l'utilisation d'Augment (je suis pourtant convaincu de l'avoir utilisé et vu à plusieurs reprises), mais sans le point à l'infini la technique est incomplète, et je propose d'aller plus loin en cherchant le moyen le plus rapide d'utiliser cette fonction (entre un appel à un sous-programme pour adresser les Lists ou pré-adresser les Lists).
Je ferai bien les tests moi-même mais je n'ai pas le matériel avec moi actuellement.
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 12/05/2016 20:41 | #
Mais la technique consiste justement à utiliser Augment( sur des listes terminées par des points à l'infini... enfin il me semble.
Citer : Posté le 12/05/2016 20:56 | #
Matt demandait comment dessiner deux carrés à la suite avec un même GraphXY, n'est-ce pas "dessiner à la chaîne", comme se prénomme la "nouveauté" ?
Et je maintiens qu'Augment pourra causer des glitchs si il n'y a pas d'infini entre les Lists, cf mon message précédent, on retombe sur ce qui avait été soulevé par Matt.
D'ailleurs je ne veux pas dire de bêtises mais pour accélérer la vitesse d'affichage il vaut mieux ne pas utiliser de sous-programme pour la création des Lists de Tiles.
Mais ça fait que 13 sprites au max et ne laisse plus aucune List de libre, sinon un tas de If Z=... Qui donne les coordonnées.
Le truc c'est que si t'as besoin des sprites autre part dans le programme, soit tu recopies tout, soit c'est mort. C'est pour ça que je préfère avoir un programme qui sert de base de donnée, j'y accède facilement, à n'importe quel instant. AU prix d'une légère perte de perf, ok.
Citer : Posté le 12/05/2016 22:00 | #
Hoho je me fais sénile dites donc, je n'avais pas vu pour le point à l'infini, j'ai insisté mais je n'aurais pas dû, je ne sais juste plus lire. Toutes mes excuses !
Merci d'avoir quantifié le gain (enfin la perte en l’occurrence) de temps à utiliser un Prog. En effet, puisque c'est si peu, autant rester sur ce système plutôt que de pré-adresser les Lists.
Il faut définitivement que je retrouve où j'avais déjà vu cette technique, je me demande si ce n'est pas pour la MAJ d'Ice Slider que je n'ai jamais postée ou dans un projet avec Alex_1186...
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 12/05/2016 22:57 | #
Pas de soucis
On le voit plus ce Alex_1186, c'est bien dommage.
Citer : Posté le 19/05/2016 06:23 | #
@Ne0tux pendant les cpc lorsque l'ont avait parlé de l'affichage j'utilisait cette technique
Mais finallement j'ai utiliser une autre technique plsu rapide (sur tes conseils )
Citer : Posté le 19/05/2016 13:11 | #
C'est à dire ? Tu utilises quelle technique ?
Citer : Posté le 19/05/2016 17:00 | #
Ce que dis Suruq était spécifique à son utilisation.
Puisqu'il n'avait que 3 graphismes différents, je lui avais conseillé un préadressage des 6 Lists fixes, l'utilisation d'un Drwastat "classique" dont seul le paramétrage changerait (Graph-On/Off), et une fenêtre graphique à origine mobile. Du fait il n'y avait aucune manipulation de List.
En bref, c'est "l'ancienne méthode", qui donne tout de même de bons résultats en terme de poids et de rapidité.
Après ce n'était qu'un conseil, je n'ai pas pu comparer les deux méthodes par moi même. Mais Suruq a l'air de dire que ça prend moins de temps, il pourra d'ailleurs quantifier ça, il l'avait fait lorsque je lui avait expliqué mon point de vue, mais je n'ai plus les chiffres sous les yeux.
Par contre on voit le "chargement" de la map, contrairement à ta dernière astuce 9*, avec laquelle tout s'affiche en même temps, une fois que toutes les Lists ont été "concaténées".
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 19/05/2016 17:44 | #
je n'ai plus les chiffres mais la différence est minime (augment( plus rapide )
mais effectivement le faite de voir la map se charger fait passer le temps plus vite (de mon point de vue)
au final chacun a sont utilité en fonction du contexte :
- le augment( permet un chargement plus rapide sur un nombre petit de tiles
- le drawstat est plus rassurant vis à vis de l'utilisateur ("rassurant" dans le sens ou l'utilisateur sais que ça marche car le niveau/map s'affiche en temps réel )
Citer : Posté le 30/06/2016 20:08 | #
a votre avis est ce qu'il y aurai un moyen d'appliquer cette fonction au mode texte ( pour un projet: RPG en mode texte )
perso j'ai bricolé un bout de programme pour essayer... il fonctionne mais est tellement lent qu'il n'est pas exploitable
Citer : Posté le 01/07/2016 12:58 | #
Du Super DrawStat en mode texte ? Euh... vu que l'écran texte fait 21x7, y'a pas trop moyen de tracer des lignes dessus. Tu veux faire quoi exactement ?
Citer : Posté le 01/07/2016 17:39 | #
Pour mon projet j'ai a peu près 20 maps a faire et plutôt que de faire un programme répétitif et très lourd j'ai pensé a utiliser cette technique pour tracer les contours de mes bâtiment ( bâtiments c'est vite dit en mode texte ) en utilisant les valeurs de 2 listes pour les coordonnées pour tracer mes traits et comme ça faire un programme plus léger et qui pourrai être utilisé pour faire un éditeur de map
Citer : Posté le 01/07/2016 17:44 | #
Ben en soit, tu peux pas tracer des traits en mode texte… À l'inverse, tu peux faire un sous-programme qui te dessine une maison aux coordonnées L et C (ligne/colonne) automatiquement. Faut juste hardcoder le tracé de la maison en fonction de L et C.
Après tu l'appelle dès que t'en a besoin, mais souvent en mode texte la matrice qui sert de tilemap reste le plus efficace/courant.
Citer : Posté le 01/07/2016 17:48 | #
Ce que tu veux faire est faisable, il s'agit d'un algorythme pour relier deux points. C'est assez lourd, mais comme tes murs seront soit verticaux, soit horizontaux ça devient très simple.
Par contre Ici le SuperDrawStat ne te sera d'aucune utilité.
Citer : Posté le 01/07/2016 17:53 | #
J'utilise la une matrice 21x7 pour le dessin et la gestion des collisions mais le mais je ne pense pas pouvoir dessiner 20 maps pour lesquelles chaque fois que je veux afficher un objet je dois écrire
Le code va être énorme a la fin donc il me parait plus facile de tracer les traits plutôt que de faire un programme contenant tous les points.
J'ai déja un début de codeici le problème est qu'il est très lent (les maps mettent 2 sec à se dessiner)
@Ninestars c'est exactement ce que je veux faire mais je n'y arrive pas ( Ah ce niveau de prog de fou que j'ai )
Citer : Posté le 01/07/2016 17:55 | #
Tu peux remplir une matrice comme celà aussi : [[1,2,3][0,0,4][5,0,6]]->Mat A
Citer : Posté le 01/07/2016 17:58 | #
Le code reste tout de même très lourd mais je n'ai besoin de dessiner que des murs horizontaux ou verticaux mais je n'arrive pas a un programme correcte et rapide
Citer : Posté le 02/07/2016 12:09 | #
Hum... Petite question, juste comme ça...
Pourquoi appelle-t-on cette technique "super DrawStat" alors que c'est un tracé paramétrique ?
Je dis ça, hein, je dis rien... Parce que Graph(X,Y) n'est pas un drawstat, en fait.
Citer : Posté le 02/07/2016 12:10 | #
Parce qu'elle s'utilise comme le DrawStat et qu'elle est plus puissante. C'est des raisons historiques.
Citer : Posté le 02/07/2016 12:11 | #
Ah oui, de ce point de vue, effectivement. C'est un peu comme "nos ancêtres les Gaulois", finalement.