Événements liés
  • Démo technique du samedi #2: 12 Mai 2007
Pages: [1] 2 3   Bas de page
Imprimer
Auteur Fil de discussion: [Demo] HBL et Scrolling  (Lu 9168 fois)
0 Membres et 1 Invité sur ce fil de discussion.
Mollusk Hors ligne
PAlib Guru et
Administrateur
*****
Messages: 3480


Voir le profil WWW
Ne vous posez pas de questions, codez !

« 05 Mai 2007, 23:48:56 »

Et hop, nouvelle démo ! Cette semaine, on s'attaque au HBL... Si vous ne savez pas ce que c'est, regardez la vidéo de la démo et instruisez-vous. Wink


Shadow of the Beast


Alors, que voyez-vous de particulier sur cette démo ? Un oeil qui zoome ? Mouais... Un gars qui court ? Mouais... Ok, on ne tourne pas autour du pot, ce qui donne son charme à cette démo (remake de Shadow of the Beast), c'est une impression de profondeur, avec plusieurs niveaux qui scrollent à des vitesses différentes.
Bon, après cette courte mise en matière, on va donc voir ce qui nous intéresse cette semaine : le scrolling parallax et le scrolling différent sur un même fond.

Scrolling Parallax

Alors, le scrolling parallax, c'est quoi ? Tout simplement un mot pour dire que plusieurs fonds scrollent à des vitesses différentes, pour donner une sensation (assez réussie en générale) de profondeur. Pour comprendre le principe, c'est simple : montez dans votre voiture, et roulez... Allez sur une route de campagne bordée par des arbres. Les arbres les plus proches de la route semblent passer très rapidement devant la voiture. Le champ, en revanche, se 'déplace' par rapport à la voiture à une vitesse bien plus réduite. Quant à la petite forêt au loin, elle est encore plus lente, presque immobile... Dans la réalité, il n'y a pas juste 3 couches à vitesses différentes, mais une infinité. Sauf que nos jeux, on est limité par le nombre de fonds. Azn On applique donc cette effet de façon 'caricaturale' par rapport à la réalité, et en pratique ça donne un effet très simple à mettre en place, mais très sympa (cette démo n'a que 60 lignes...).

Dans un souci de simplification, on a ici la vitesse de scrolling de base (le sol), et les différentes couches vont de 2 fois plus rapidement (nuages du haut, barrière) à 4 fois plus lentement (les nuages les plus lointains).

Scrolling Différentiel

Ce qui marque dans cette démo, c'est qu'on a plusieurs scrollings différents... Personnellement, j'en compte 8 : 5 couches de nuages, les montagnes, le sol, et la barrière... 8 ?? Pourtant, la DS n'a que 4 fonds, non ? Et en plus, un des fonds est utilisé pour afficher le ciel avec la lune... Cherchez l'erreur !

Bon, en regardant plus attentivement, on remarque que la plupart des nuages ne se chevauchent pas. En fait, si on n'avait pas à leur appliquer un scrolling différent, on pourrait donc les avoir sur un seul et même fond... C'est le cas pour toutes les couches, en fait, sauf les nuages du haut et la barrière ! Voici les fonds utilisés :

http://www.dev-fr.org/Demos/SOTB/back.png http://www.dev-fr.org/Demos/SOTB/layers.png http://www.dev-fr.org/Demos/SOTB/front.png

Eh oui, un des fonds contient presque toutes les couches qui sont à des scrollings différents ! Pour comprendre comment cela marche, il faut savoir que la DS écrit l'écran ligne par ligne. À la fin de chaque ligne, il y a un très rapide 'temps mort' pendant lequel on peut exécuter un code court avant que la ligne suivante ne commence à être affichée. Ainsi, si on change la valeur du scrolling pendant ce temps mort, la ligne suivante sera décalée. Langue

Il faut donc, dans un premier temps, initialiser la fonction qui sera chargée dans le temps mort, nommée HBL (Horizontal Blank Line) :
Code
(c):
irqSet(IRQ_HBLANK, HBL_function);   irqEnable(IRQ_HBLANK);
Voilà, tout simple, j'ai utilisé les fonctions libnds... Rien de bien méchant, la fonction que j'ai faite se nomme HBL_function (original, je sais).

À partir de là, on sait qu'à chaque HBL/temps mort on aura le chargement de cette fonction, quel que soit la position où l'on se trouve dans le code... Il reste donc à savoir à quelle ligne on est au moment du HBL. Si on sait où on est (verticalement, donc), on pourra en effet appliquer le bon scrolling. Smiley
Code
(c):
void HBL_function(void){
  s16 vcount = PA_GetVcount(); if(vcount > 192) vcount = 0; // Loop
 
  if((vcount >= 0)&&(vcount < 67)) PA_BGScrollX(0, 1, layerscroll); // Normal
  else if(vcount < 78) PA_BGScrollX(0, 1, layerscroll>>1); // 2 fois plus lent
  else if(vcount < 86) PA_BGScrollX(0, 1, layerscroll>>2); // 4 fois plus lent
  else if(vcount < 145) PA_BGScrollX(0, 1, layerscroll>>1); // 2 fois plus lent  
  else PA_BGScrollX(0, 1, layerscroll); // Normal  
}

La fonction PA_GetVcount ne fait que lire dans un registre pour récupérer la valeur. Ce Vcount (Vertical Counter, littéralement compteur vertical, qui indique donc la ligne...) peut prendre des valeurs de 0 à 262. La DS possède 192 lignes, donc à partir de la valeur 192 ce n'est plus en train d'afficher.

Voici aussi la version hors PALib, pour ne pas faire de jaloux. Azn
Code
(c):
void HBL_function(void){
  s16 vcount = REG_VCOUNT; if(vcount > 192) vcount = 0; // Loop
 
  if((vcount >= 0)&&(vcount < 67)) BG1_X0 = layerscroll; // Normal
  else if(vcount < 78) BG1_X0 = layerscroll>>1; // 2 fois plus lent
  else if(vcount < 86) BG1_X0 = layerscroll>>2; // 4 fois plus lent
  else if(vcount < 145) BG1_X0 = layerscroll>>1; // 2 fois plus lent  
  else BG1_X0 = layerscroll; // Normal  
}

Il faut prendre en compte un détail assez important : quand on lit le numéro de la ligne, la DS a en fait déjà affiché celle-ci... Donc, si on lit par exemple le numéro 0, la DS a déjà affiché la ligne 0, il est donc trop tard pour lui appliquer le bon scrolling ! Pour remédier à ce souci, j'ai rajouté un simple if(vcount > 192) vcount = 0;. En effet, puisque de toute façon à partir de 192 on est hors écran, on peut appliquer le scrolling que l'on veut, et ainsi on est sur de ne pas rater le 0. Azn

Le reste de cette fonction me parait assez simple : en fonction de la ligne, on applique un scrolling différent. Azn Dans un souci de rapidité et de 'justesse', j'ai remplacé les divisions par des décalages de bits. >>1 vaut /2, >>2 vaut /4, etc.  Quant à layerscroll, c'est juste une variable à laquelle on ajoute 1 à chaque frame, histoire de faire avancer le tout. Smiley

http://www.dev-fr.org/Demos/SOTB/decoupe.png

Mot de la Fin

Voilà, déjà fini ! Je ne vais pas commenter tout le reste du code, il est très très basique (initialisation d'un fond, déplacement d'un sprite...). Il a été fait avec PAlib, mais les noms de fonctions sont suffisamment explicites pour que tout le monde comprenne Wink   Les fonds n'ont rien de particulier, tous convertis en tiles, 256x192... En fait, dans cette démo, la partie 'cruciale' du code fait moins de 10 lignes !

Cette démo permet de voir qu'avec un peu d'astuce on peut faire des effets bien sympas, et surtout qu'il ne faut pas se fier aux limites 'papier' d'une console, car il existe souvent des méthodes pour les dépasser/contourner...


Dev-Fr.org : Le Jeu

Allez, comme je suis sympa aujourd'hui je vous livre 2 démos pour le prix d'une. Azn En fait, cette démo est plus courte et plus simple à comprendre, et repose elle aussi sur le scrolling dans le HBL...


Je ne vais pas détailler tout le code, qui est VRAIMENT simple Azn, mais je vais montrer les 2 choses importantes...

Code
(c):
#define TAILLE 16
s16 scroll[64] = {};
 
void HBL_function(void){
  u16 vcount = PA_GetVcount()+1; if(vcount > 192) vcount = 0; // Loop
 
  PA_BGScrollX(0, 3, scroll[vcount/TAILLE]); // Normal  
}
Voici le début du code, tout simple. On définit la taille (en pixels), ici j'ai mis 16, parce qu'avec 8 c'était super dur Langue
Le tableau scroll va servir à mettre les valeurs de scrolling différents. On peut donc avoir 64 valeurs, donc assez pour des zones de 3 pixels Wink
Et enfin, la fonction HBL_function... Elle sera chargée comme tout à l'heure, pas la peine d'en reparler. Ici, le code est tout simple. À noter qu'on ajoute 1 à Vcount... Pourquoi ? Car le numéro est le numéro qu'on a à la fin de la ligne... Donc quand on sort le numéro de ligne 0, en fait on a déjà mis à jour la ligne 0, donc la ligne qui aura le nouveau scrolling est la ligne 1...

Je vous épargne le code qui charge le fond, et celui qui applique un scrolling différent à chaque bloc, au hasard. Azn On en arrive donc au code la boucle principale :

Code
(c):
if(Stylus.Newpress){
   partie = Stylus.Y /TAILLE; // Par tranches de 8...
   oldx = Stylus.X;
}  
 
if(Stylus.Held){
   scroll[partie] -= Stylus.X-oldx;
   oldx = Stylus.X;
}
En gros, quand on touche l'écran ça regarde quelle partie (en hauteur) on a touchée pour savoir quelle partie déplacer... Ceci permet de ne pas changer de ligne si la personne bouge en hauteur par la suite. Ensuite, tant que le stylet touche l'écran, on ajuste la valeur dans le tableau scroll en fonction du déplacement horizontal par rapport à la frame précédente... et c'est tout ! Eh oui, tout simple. Azn

Maintenant, passez ça en 8 pixels ou moins, et essayez de faire le 'puzzle' en moins de 10 secondes pour voir. Wink


SineBg : Faites des Vagues...

Bon, j'en profite pour coller ici l'exemple de PAlib utilisant le HBL pour faire un effet de vague sur un fond scrollant... Rien de bien méchant, je vous laisse voir.


Bon, petit aperçu de la fonction en question :

Code
(c):
void HBL_function(void){
  s16 vcount = PA_GetVcount();
  vcount++;
  if(vcount > 192) vcount = 0; // Get correct vcount
 
  PA_BGScrollX(0, 3, (scrollx&511) + ((PA_Sin((vcount+scrolly)*height+add)*width)>>8));
}

Voilà, rien de bien méchant. Smiley En gros, on applique la fonction Sinus en fonction du numéro de ligne et en prenant en compte le scrolling vertical. Azn Les variables height et width permettent de modifier la hauteur et largeur de la vague (à 8 par défaut), et add est la valeur qui permet à la vague de se 'déplacer'... (on l'augmente de 4 à chaque frame).
Rien de sorcier, comme vous le voyez. Comme quoi, avec quelques lignes de code on peut faire des petits effets sympathiques. Smiley

Bonne fin de week-end à tous, et à la semaine prochaine. Wink
Journalisée

Darkmath Hors ligne
Administrateur
*****
Messages: 489


Voir le profil WWW
« Réponse #1 : 06 Mai 2007, 01:20:11 »

Très sympa Cheesy
Journalisée

birslip Hors ligne
Administrateur
*****
Messages: 513


Voir le profil WWW
« Réponse #2 : 06 Mai 2007, 08:44:58 »

Super sympa comme explication je devrais faire de même avec la mienne  Wink
Par contre, comment tu fais pour prendre des vidéos?
Journalisée

MasterDje Hors ligne
Diet Coke Addict
Global Moderator
*****
Messages: 3242


Voir le profil WWW
« Réponse #3 : 06 Mai 2007, 08:46:05 »

Oué c'est lumineux !  Wink

ça donne envie... tres envie !
faut que trouve un sprite de batmobile  Grin

le coup du code dans le post,c'est un vrai plus !
Journalisée

Alekmaul Hors ligne
Papi codeur et
Administrateur
*****
Messages: 1229


Voir le profil WWW
Out of memory error ...

« Réponse #4 : 06 Mai 2007, 09:02:56 »

Oui, bravo, vraiment très bien comme explication.
Si personne ne fait effectivement la version pure libnds, je vais m'y coller. Pour l'instant, je vais VOTER !
Journalisée

Mon site PortableDev : l'émulation sur GBA et sur DS
Mollusk Hors ligne
PAlib Guru et
Administrateur
*****
Messages: 3480


Voir le profil WWW
Ne vous posez pas de questions, codez !

« Réponse #5 : 06 Mai 2007, 09:04:14 »

Honnêtement, je pense pas que la version libnds ait un intérêt d'un point de vue compréhension. Le code est très court, et en fait la seule 'difficulté' éventuelle serait pour récupérer le Vcount (et encore, suffit d'avoir le nom de registre de libnds).
Journalisée

Darkmath Hors ligne
Administrateur
*****
Messages: 489


Voir le profil WWW
« Réponse #6 : 06 Mai 2007, 09:16:59 »

Personne veut faire la meme pour PSP? Parceque la DS c'est cool mais on est MULTI-PLATEFORME, non?
Journalisée

Mollusk Hors ligne
PAlib Guru et
Administrateur
*****
Messages: 3480


Voir le profil WWW
Ne vous posez pas de questions, codez !

« Réponse #7 : 06 Mai 2007, 09:23:55 »

Mais je ne connais pas la PSP, ca marche pareil ? Azn Enfin genre sur DS pour la 3D ca ne marcherait pas...
Journalisée

MasterDje Hors ligne
Diet Coke Addict
Global Moderator
*****
Messages: 3242


Voir le profil WWW
« Réponse #8 : 06 Mai 2007, 10:04:37 »

c'est vrai que l'equivalent PSP (ou autre, GC ? SDL ?) serait pas mal du tout, mais j'y connais rien non plus, et pi j'en ai pas  Grin ...
Journalisée

Smealum Hors ligne
Assassin
Administrateur
*****
Messages: 590


Voir le profil WWW
Assassin

« Réponse #9 : 06 Mai 2007, 10:28:17 »

Personne veut faire la meme pour PSP? Parceque la DS c'est cool mais on est MULTI-PLATEFORME, non?

Ben t'as qu'à le faire toi, on est multi-plateforme, mais on ne fait que ce qu'on connait nous !  Grin
Journalisée

Pyroh Hors ligne
Aspirant graphiste
Administrateur
*****
Messages: 725


Voir le profil
Vive le jambon !

« Réponse #10 : 06 Mai 2007, 13:42:55 »

Super bonne idée, super boulot  Shocked
Je trouve que c'est vachement intéressant de traiter de cas concrets de la sorte, ca aide pas mal le noob.
Pour la psp je vois pas forcement l'intérêt de faire cette démo, les hardware sont pas les même de même que les possibilités.
Par exemple afficher un png sous DS ne doit pas etre super facile, sous psp ca se fait en 3 coups de cuiller à pot, donc des démos PSP oui mais pas celle qu'on présente sur DS
Journalisée

Citation de: Reppa chez Yus à 4h du mat en regardant "Salut les musclés" sur AB1
Ben quoi ? Matter ça c'est comme faire du retrogaming avec une télé Cheesy
MasterDje Hors ligne
Diet Coke Addict
Global Moderator
*****
Messages: 3242


Voir le profil WWW
« Réponse #11 : 06 Mai 2007, 14:10:12 »

AnarX, je suis pas tout à fait d'accord...
Ok les hardwares sont differents, et les lib de même... mais de voir une façon de faire (parmi d'autres) pour NDS et son equivalent PSP c'est quelque chose de jamais vu. nulle part...

et effectivement la maniere de faire & la complexité de la mise en oeuvre different, mais c'est le resultat final qui compte...

ça peut donner l'envie aux dev DS de sauter le pas et d'aller voir un peu du coté PSP ... qui sait ?

Journalisée

Mollusk Hors ligne
PAlib Guru et
Administrateur
*****
Messages: 3480


Voir le profil WWW
Ne vous posez pas de questions, codez !

« Réponse #12 : 12 Mai 2007, 21:07:02 »

Up, la démo est sortie !
Journalisée

mikegba Hors ligne
VIP
****
Messages: 35


Voir le profil
« Réponse #13 : 12 Mai 2007, 21:53:46 »

 Smiley Vraiment, ça assure sur Dev-fr  !!!     continuez comme ça !! Wink
Journalisée
Mollusk Hors ligne
PAlib Guru et
Administrateur
*****
Messages: 3480


Voir le profil WWW
Ne vous posez pas de questions, codez !

« Réponse #14 : 12 Mai 2007, 21:54:44 »

Oh, merci Mikegba ! Venant de toi ça me rend tout chose Azn
Journalisée

Pages: [1] 2 3   Haut de page
Imprimer

Aller à: