Le scroll text de base

"Traveling without moving"

Préparatifs

Nous allons commencer par le cas simple, un scroll texte en ligne avec une fonte dont toutes les lettres font la même largeur (dite fonte "proportionnelle").

Comme nous sommes très malins, nous allons aussi choisir une taille de caractère qui divise "bien" la largeur de l'écran. Par exemple, pour un écran de 320 pixels, une fonte de 16 pixels de large (320/16 se divise "bien", il n'y a pas de reste).

Afin de se simplifier les choses lors de l'affichage, la première chose est de mettre la fonte en forme, en ligne et dans l'ordre ASCII. Ci-dessous, la fonte que je vais utiliser dans mon code d'exemple (qui vient du site de Daniel Guldkrans) et remise en forme par mes soins :

Fonte 32x25

De cette manière, on pourra très simplement savoir quel caractère se trouve où. Ma fonte, dont chaque caractère fait 32 pixels de large sur 25 de haut, commence au caractère 'espace'. Si je dois afficher un 'B', je sais que ma lettre se trouve à l'offset (('B' - ' ') * 32) sur ma planche.

Méthode

Ensuite, nous allons allouer un buffer de scroll, qui fera très exactement 2 fois la largeur de l'écran, et la hauteur de la fonte. Pourquoi ? L'explication ci-dessous devrait répondre à cette question.

Mettons que le texte à afficher soit la chaîne "SPACE, THE FINAL FRONTIER..." (tiré d'une série bien connue).

Dans ce qui suit, la partie du buffer à afficher à l'écran est encadrée en bleu. Les jolis carrés vanille/fraise ne sont là que pour visualiser plus facilement les blocs. (Et on dira que l'écran est très petit ou la fonte très grosse, parce que comme je vais dérouler l'exemple, je ne vais pas faire ça sur 20 blocs de large).

Initialisation :
On place la première lettre (le 'S') dans le premier bloc à droite après l'affichage : tuto
Ensuite, on rentre dans la gestion appelée depuis la boucle principale.

A chaque frame, on déplace la position d'affichage dans le buffer de scroll et le 'S' commence à entrer dans l'écran. Par exemple après un demi bloc :
tuto
On continue d'avancer. Maintenant le 'S' est entièrement entré et on en arrive au moment ou un nouveau bloc va entrer à son tour par la droite dans la fenêtre d'affichage :
tuto
A ce moment là, 3 étapes :
1 - Je commence par recopier la lettre qui est entrée à droite dans le premier bloc situé en dehors à gauche de mon affichage (soit en réaffichant la lettre, soit en copiant le bloc mémoire. La méthode importe peu tant qu'on retrouve à gauche ce qui est à droite) :
tuto
2 - Est-ce le moment de replacer mon affichage au début du buffer ? Non.
3 - Je copie une nouvelle lettre (le 'P') dans le premier bloc à droite après l'affichage :
tuto
Et on reprend :
On continue d'avancer. Le 'S' est évidement toujours là et le 'P' commence à entrer. A mi-chemin (à partir de maintenant, je ne vais plus montrer cette étape) ça donne :
tuto
On continue d'avancer. Le 'P' est entièrement entré et on en arrive au changement de bloc :
tuto
1 - Je copie la lettre qui est entrée à droite dans le premier bloc situé à gauche de mon affichage :
tuto
2 - Est-ce le moment de déplacer mon affichage ? Non.
3 - Je copie une nouvelle lettre (le 'A') dans le premier bloc à droite après l'affichage :
tuto
On continue d'avancer. Le 'A' est entièrement entré et on en arrive au changement de bloc :
tuto
1 - Je copie la lettre qui est entrée à droite dans le premier bloc situé à gauche de mon affichage :
tuto
2 - Est-ce le moment de déplacer mon affichage ? Non.
3 - Je copie une nouvelle lettre (le 'C') dans le premier bloc à droite après l'affichage :
tuto
On continue d'avancer. Le 'C' est entièrement entré et on en arrive au changement de bloc :
tuto
1 - Je copie la lettre qui est entrée à droite dans le premier bloc situé à gauche de mon affichage :
tuto
2 - Est-ce le moment de déplacer mon affichage ? Oui ! (Enfin !) :
tuto
3 - Je copie une nouvelle lettre (le 'E') dans le premier bloc à droite après l'affichage :
tuto
On continue d'avancer. Le 'E' est entièrement entré et on en arrive au changement de bloc :
tuto
1 - Je copie la lettre qui est entrée à droite dans le premier bloc situé à gauche de mon affichage :
tuto
2 - Est-ce le moment de déplacer mon affichage ? Non.
3 - Je copie une nouvelle lettre (une virgule) dans le premier bloc à droite après l'affichage :
tuto
Et ainsi de suite.

Pour résumer, nous avons donc une fonction appelée toutes les frames qui fait (en pseudo code) :

Scroll text afficher/masquer
ScrollText
{
    Avance de la fenêtre d'affichage dans le buffer.
    Si (Changement de bloc)
    {
        1 - Recopie de la lettre affichée à droite à l'emplacement qui vient de disparaitre à gauche.
        2 - Si nécessaire, replacement de la fenêtre d'affichage au début du buffer.
        3 - Nouvelle lettre à droite.
    }
    Affichage de la fenêtre d'affichage à l'écran.
}

Pour la partie affichage, il ne vous reste qu'à blitter la fenêtre d'affichage à l'écran, et le tour est joué : Le scroll scrolle avec en tout et pour tout une copie de deux blocs de la taille d'un caractère à chaque passage d'un bloc à l'autre. (Evidement, sur PC il faut quand même blitter. Sur un Amiga, on pouvait directement faire pointer une bande de l'écran sur le buffer de scroll avec le copper !)

C'est au niveau de la dernière ligne qu'on peut ensuite introduire de la fantaisie... Par exemple, au lieu d'un bête Blit, on pourrait afficher chaque colonne de pixels du buffer à une hauteur différente. Tiens, ça me donne une idée super originale : Si je plaçais chaque colonne de mon buffer sur une sinusoïde ? (^_^)

Sine scroll

Le code qui va avec cette image, c'est ici.

Les petits trucs auxquels il faut faire attention

Bien se caler "au bloc" quand on copie les lettres. Le scroll pouvant se déplacer de plusieurs pixels à la fois et en un nombre pas forcément multiple de l'unité de bloc choisie, l'offset de l'affichage ne correspond pas forcément à la première colonne d'un bloc.

Quand on replace l'offset d'affichage dans le buffer au début, on ne le remet pas forcément à "0". Ceci toujours pour la même raison, l'offset n'est pas forcément sur la colonne 0 d'un bloc au moment du changement de bloc. Moi je soustrais la largeur de l'écran. (On peut aussi le faire avec un modulo, mais c'est plus lent).

Home