Jour 3 - Entrée/Sortie ← Précédent

Jour 4 - Sprites

Spécification des Sprites DS

Avant de commencer à les utiliser, voyons de quoi est capable la DS...Elle peut afficher 128 sprites différents sur chaque écran, soit un total de 256 sprites! Chacune peut être retournée horizontalement/verticalement, déplacée sur tout l’écran, animée (en mettant à jour l’image utilisée), devenir transparente, ou même devenir une mosaïque! En plus de ça, les sprites peuvent être tournées ou zoomées. Par contre, il y a une limitation sur ce point: vous ne pouvez pas définir un paramètre de rotation/zoom pour chaque sprite, mais uniquement 32 différentes rotations/zooms par écran (appelés rotsets). Ensuite vous pouvez assigner ou non chaque sprite à un rotset. Donc tous les sprites peuvent être tournées, zoomées ou les deux, mais uniquement de 32 manières différentes à la fois. Plusieurs sprites peuvent partager le même rotset sans problème, elles seront tournées ou zoomées de la même manière.

Tailles des écrans DS

Voici un joli petit schéma fait par Bennyboo, qui pourrait s’avérer utile...pas seulement pour les sprites, mais également pour les backgrounds et le reste...

www.palib.info_screens_ds_ds_screen.jpg

En ce qui concerne les sprites, vous devrez juste vérifier la taille en pixels...Alors ça fait 256 pixels de large, et 192 de hauteur. Considérant que le premier pixel n’est pas le numéro 1 mais 0, cela veut dire 0-255 et 0-191...Comme sur le schéma.

De Plus, la position d’un sprite est limitée à certaines valeurs. X peut uniquement se trouver entre 0 et 511, et Y entre 0 et 255. Cela veut dire qu’en plaçant un sprite à la position X = 512 revient à le mettre à la position X = 0 ! C’est ce que nous appelons sprite wrapping. Quand le sprite arrive à la limite, il revient de l’autre côté, et vice versa.

Modes de couleurs

Maintenant, à propos des couleurs... Les sprites disposent de 3 modes de couleurs différents :

  • Palettes de 16 couleurs, on aura 16 palettes par écran. C’est pas mal utilisé sur GBA, mais sur DS il y a peu d’intérêt!
  • Palettes de 256 couleurs (très bon mode, mais ça utilise deux fois plus de mémoire), avec un total de 16 palettes par écran (alors que la gba ne dispose que d’une seule). C’est ce qu’on utilise le plus...
  • 16bit sprites, c’est à dire sans palettes ! Cependant, ces sprites ne sont pas très utilisées, comme ils requièrent plus de Ram Video, et utilisent bien trop de mémoire pour que ce soit utilisable.

Enfin, le mieux est de prendre des sprites de 256 couleurs :-) Vous verrez, même si ça semble limité, vous aurez assez de couleurs pour chaque sprite.

Tailles des sprites

La DS gère plusieurs tailles de sprites, mais il faut vous rappeler que ces tailles sont quand même spécifique. Les seuls tailles sont 8, 16, 32, et 64 pixels de haut et de large. Toutes les tailles ne sont quand même pas possible, voilà les différentes tailles utilisables (la largeur est prise horizontalement, la hauteur verticalement...) :

8 16 32 64
8 8×8 16×8 32×8
16 8×16 16×16 32×16
32 8×32 16×32 32×32 64×32
64 32×64 64×64

Vous pouvez utiliser toutes ces tailles hormis 64×8, 64×16, 16×64, et 8×64...

euh... je fais comment si mon sprite ne fait pas une de ces tailles ? Vous allez obtenir un magnifique sprite super crade et moche... Il y a une façon simple de contourner ce problème : utiliser un logiciel de dessin, juste mettre la taille de l’image à une taille adaptée pour la DS. Par exemple, si vous avez un sprite de 48×48, vous pouvez agrandir la taille du carré à 64×64 ! La même chose pour du 10×64 que vous devrez mettre en 32×64!

Couleur transparente

La dernière chose à prendre en compte, on peut le deviner, vous ne voulez pas que la couleur d’arrière plan de votre sprite soit visible... Si vous avez un sprite rond, comme un fresbee, vous ne voudriez pas qu’en dehors du rond la couleur de fond soit visible. Afin d’enlever cette couleur de fond, ou plutôt de la rendre invisible, vous devez choisir la couleur qui sera transparente (une seule par sprite): la meilleure est le magenta (rose pétant!), car généralement on ne l’utilise que très peu souvent (rouge: 255, vert: 0, bleu: 255), mais certains prefèrent utiliser le noir, mais comme cette couleur est souvent utilisé dans les sprites, je ne pense pas que ce soit un choix judicieux...

Convertir avec PAGfx

Vous savez ce qui aurait été cool ? Si des sprites pouvaient être employés tels qu’ils sont, sans aucune modification, directement sur DS... désolé de vous décevoir, arrêtez de réver ! :’( Actuellement, les choses sont comme cela, mais vous verrez que convertir un sprite au format DS, ce n’est pas aussi compliqué que ça...)

L’outil que nous allons utiliser est PAGfx, un convertisseur créé par Mollusk et Kleevah, il ne peut pas être plus facile à utiliser. Il y a 2 manières de l’utiliser, une pour des débutants, en utilisant l’interface visuelle, une pour les utilisateurs avancés, avec juste le fichier de PAGfx.ini. Les deux méthodes offrent les mêmes possibilités, ne vous inquiétez pas.

Interface visuelle PAGfx

Chaque chose à la fois... Entrez dans votre dossier PAlibTools, et vous devriez voir un dossier PAGfx. Ouvrez le, et l’intérieur que vous devriez avoir 4 fichiers.

  • PAGfx.txt est juste une aide rapide et un changelog. Vous ne devriez pas vraiment en avoir besoin, car je vais tout expliquer...
  • PAGfx.ini est le fichier ini utilisé pour convertir les sprites, backgrounds et textures... J’en parlerai dans la deuxième partie...
  • PAGfx.exe est le fichier exe qui convertit vos sprites, basé sur le fichier ini... Vous verrez cela plus tard...
  • PAGC Frontend.exe est le frontend ! Maintenant, c’est celui que vous allez vous ouvrir pour l’instant.

Si vous recevez un message d’erreur, c’est parce que vous n’avez pas installé le .NET Framework. Vous pouvez juste télécharger et installer ça

Maintenant, en ouvrant le frontend, voici ce que vous obtenez :

Boutons

Je vais expliquer les boutons, bien que ce soit assez explicite...

  • “Add Files” ajoute un fichier en tant que sprite, background ou texture cela depend d’où vous vous trouvez..
  • “Remove Files” retire les fichier séléctionnés
  • “Load INI” charge le fichier PAGfx.ini dans le répertoire courant
  • “Save INI” sauvegarde tous les infos des sprites/background/textures dans le fichier PAGfx.ini pour une future conversion avec PAGfxConverter.exe
  • “Save and Convert” sauvegarde juste dans le fichier INI, et charge PAGfxConverter.exe pour convertir immédiatement, c’est ce qu’on utilise le plus...

Ensuite, vous voyez qu’il y a 3 onglets : Sprites, Backgrounds, et Textures... rien de bien compliqué à comprendre...

Préférences de transparence

Comme je le disais avant, vous pouvez choisir la couleur qui sera la couleur transparente pour le fond des sprites, et c’est plutôt important. Dans PAGC Frontend, vous avez un cadre “transparent color” , dans lequel vous pouvez choisir entre 4 couleurs de transparence : noir, blanc, magenta, et vert. Comme dit avant, je recommande le magenta, mais le noir est souvent employé...

Ajouter un sprite

Ok, pour voir comment ça marche, nous allons commencer par ajouter un fichier... il suffit d’ajouter un fichier image. Regardons les options disponibles pour les sprites...

  • Filename : le nom du fichier ! Duh...
  • ColorMode : C’est un paramétre important... vous pouvez choisir entre les modes 16 couleurs, 256 couleurs ou 16 bits. En fait, le plus utilisé est le mode 256 couleurs.
  • PaletteName : Il s’agit du second paramètre important...comme vu précédemment, la DS peut avoir 16 palettes par écran pour les sprites. Par défaut, le programme met comme nom de palette le nom du sprite. Vous pouvez changer cela pour obtenir quelque chose comme sprite0, et pour les autres sprites sprite1, etc... Si vous voulez assigner à plusieurs sprites une même palette, il vous suffit d’indiquer le même nom de palette ici :-) Il n’est pas possible de faire plus simple... Le nom réel de la palette sera nomdepalette_Pal, mais nous verrons cela bientôt..
  • Path : rien que le chemin d’accès... rien de plus...

Et c’est en fait tout ce que vous devez connaître .

Conversion

Maintenant, cliquez sur ‘Save and Convert’, ce qui affichera quelques infos étranges que vous devriez déja comprendre, et si non, c’est tout bon, vous n’en avez pas besoin maintenant, puis le processus s’arretera en indiquant que tout à fonctionné (si votre sprite comportait moins de 256 couleurs...si non, vous serez embété ! Je rigole, si non, utilisez un sprite des exemples de sprites de la PAlib). Si tout a fonctionné, vous devriez avoir quelque chose comme ça :

Vous verrez que le convertisseur a ‘produit’ quelques fichiers :

  • SpriteName.c est le fichier contenant toutes les données de votre sprite, et qui sera utilisé pour charger votre sprite
  • PaletteName.pal.c contient... la palette ! Donc vous en aurez besoin pour charger votre sprite avec les bonnes couleurs...
  • all_gfx.c est un fichier très sympa, qui, en fait, relie tous les sprites, fonds d’écran, et fichiers palettes... Pourquoi ? parce qu’à la place de charger chaque fichier image.c individuellement à votre projet, vous aurez juste à ajouter celui-ci, qui ajoutera directement les autres fichiers pour vous :-)
  • all_gfx.h est à peu près le même que le .c, mais contient les noms des données des sprites et autres, vous verrez cela plus tard...

PAGfx.ini

Pour ceux qui sont plus curieux, vous pouvez maintenant regarder dans PAGfx.ini qui a été créé par le convertisseur... Si vous voulez juste vous servir de l’interface du convertisseur (frontend), pas de soucis, et passez cette partie...

Cela est trés basique, du genre :

#TranspColor Magenta
 
#Sprites :
C:\test.png 256colors test
 
#Backgrounds :
 
#Textures :

Il n’est pas compliqué de comprendre à quoi cela correspond...

  • #TranspColor Magenta est la couleur de transparence que vous utilisez pour vos sprites. Cela peut être blanc (White), noir (Black), vert (Green), ou Magenta...
  • #Sprites : liste des sprites à convertir... chaque ligne à pour forme C:\test.png 256colors test
    • C:\test.png est le chemin absolu vers l’image. Vous pouvez y inscrire un chemin relatif comme test.png, mais assurez vous que PAGfxConverter.exe est dans le même répertoire...
    • 256colors est le mode de couleurs, donc 16colors, 256colors, ou 16bit, pour les sprites... (nous verrons pour les fonds d’ecran plus tard).
    • test est le nom de palette. Je le laisse par défaut, donc ce sera test_Pal...

Et le reste importe peu maintenant, comme pour les fonds d’ecran et textures :-) Simple, n’est-il pas ? Vous pouvez convertir PAGfx.ini en utilisant PAGfxConverter.exe directement... Car l’interface du convertisseur ne fait que modifier PAGfx.ini puis executer PAGfxConverter.exe !

Sprites PAlib

Dans ce premier tutorial sur les sprites, nous allons nous concentrer sur les sprites simples et basiques, afin de les voir se déplacer de haut en bas. Les tutos suivants couvriront les rotations et zoom sur sprites, la transparence, et l’animation. Soyez patient !

Affichage

Le temps est finalement venu d’utiliser le hardware de la DS ! Yahoo !! Ici commence le premier tuto d’affichage des sprites...

Les exemples suivants sont tirés de la PAlib v0.72a, car j’ai amelioré les trucs des sprites dans cette version... SVP installez cette version (ou superieur) avant de poursuivre, sinon vous n’aurez pas exactement les mêmes exemples dans le repertoire PAlibExamples...

Ouvrez PAlibExamples/Sprites/Basics/CreateSprite, et regardez le main.c qu’il contient :

#include <PA9.h>
 
// PAGfxConverter Include
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
 
int main(void){
 
	PA_Init(); //PAlib inits
	PA_InitVBL();
	
	PA_LoadSpritePal(0, // Screen
			0, // Palette number
			(void*)sprite0_Pal);	// Palette name
					
	PA_CreateSprite(0, // Screen
			0, // Sprite number
			(void*)vaisseau_Sprite, // Sprite name
			OBJ_SIZE_32X32, // Sprite size
			1, // 256 color mode
			0, // Sprite palette number
			50, 50); // X and Y position on the screen
 
	while(1) // Infinite loops
	{
                PA_WaitForVBL();    
	}
return 0;
}

Comme vous le voyez, tout à déjà été expliqué ! Je ne vais pas revenir sur des trucs du ‘jour 1’ (regardez donc dans la partie ‘décodage des templates’...), en esperant que vous l’ayiez lu...

// PAGfxConverter Include
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"

Cette partie ajoute tous les graphiques que vous avez convertis et collés dans source/gfx. Rien de plus à ajouter à ce sujet (vous pouvez quand même vérifier ce dossier, c’est là que sont les sprites convertis, avec les palettes et le reste...)

PA_LoadSpritePal(0, // Ecran
		0, // Numéro de palette
		(void*)sprite0_Pal);	// Nom de palette

Ceci est important : c’est le chargement de la palette ! Cela charge la palette sur l’ecran du bas (screen 0 est l’ecran du bas, screen 1 celui du haut... ), comme premiére palette (palette 0), et la palette chargée est sprite0_Pal... Pas d’inquiétude pour le ‘(void*)’ devant le nom de palette, il indique juste que la suite est l’emplacement d’une palette... La première des raisons de ‘non-affichage’ d’un sprite est... oublier de charger sa palette ! Et soyez prudent, chargez la palette avec le numéro correct (car il existe 16 palettes différentes pour les sprites...)

PA_CreateSprite(0, // Ecran
		0, // Numéro de sprite
		(void*)vaisseau_Sprite, // Nom de sprite
		OBJ_SIZE_32X32, // Taille de sprite
		1, // 256 color mode
		0, // Numéro de palette de sprite
		50, 50); // Position à l'ecran en X et Y

Ici, tout est ré-expliqué, cet exemple vraiment trés simple ! :-P

  • Screen 0 pour l’ecran du bas, encore... Si vous le chargez sur l’ecran du haut, il ne s’affichera pas. Pourquoi ? Car la palette correspondante n’a pas été chargée sur l’ecran du haut !
  • Sprite number vient ensuite... Comme dèja indiqué, la DS peut avoir jusqu’a 128 sprites sur chaque ecran, numérotés de 0 à 127 (inclus). Pour chaque sprite que vous créez, vous devez choisir un numéro de sprite, qui sera utilisé plus tard pour modifier ce sprite (le mettre à jour, le faire tourner, etc...). Plus encore, le numéro de sprite determine quel sprite est au-dessus de quel autre (sprite 0 est devant tous les autres, sprite 1 est devant tous les autres sauf sprite 0, etc...). Plus le nombre est bas, plus le sprite est prioritaire.
  • La taille de l’objet est composé de 2 variables qui ne sont pas très faciles à utiliser, donc les macros OBJ_SIZE sont là pour vous aider... Si vous ne vous souvenez plus des tailles utilisables, relisez ce tuto du début...
  • Le mode de couleur vient ensuite. Il ne peut prendre que 2 formes : 0 pour 16 couleurs et 1 pour 256 couleurs. Vous voudrez surement utiliser le mode 256 couleurs...
  • Ensuite vient le numéro de palette. Ici, il s’agit de 0... Si vous mettez un chiffre faux, vous pourrez soit avoir un sprite aux couleurs degueulasses (si une autre palette est utilisée), ou aucun sprite (si pas de palette chargée...). Donc, soyez prudent en utilisant ce numéro.
  • Ensuite viennent les coordonnées X et Y du sprite, en pixels, rien de plus. Ces coordonnées ne sont pas celles du milieu du sprite, mais du coin supérieur gauche.

Et c’est en fait tout ce qu’il y a à comprendre ! Quand vous aurez bien pigé, il vous suffit de double-cliquer sur build.bat, puis d’ouvrir la rom sur un emulateur ou une DS... Comme la boucle infinie (while(1)...) ne contient pas de code (autre que le VBL), votre sprite sera posé et immobile.

Avant d’attaquer la partie suivante, essayez de modifier cet exemple pour le voir apparaître sur l’ecran du haut, puis les deux en même temps...

Déplacer

Voila un des aspects qui pourrait être l’un des plus importants des sprites... les déplacer ! Il existe deux methodes differentes, la première utilise le stylet, et la seconde est la méthode universelle que vous emploierez tout le temps...

PA_MoveSprite

Ok, en premier, ouvrez l’exemple ‘MoveSprites’ se trouvant dans PAExamples/Sprites. Nous n’allons pas coller tout le code ici, car une bonne partie de son contenu à dèja été vu...

for (i = 0; i < 16; i++)
{ 
      PA_CreateSprite(0, i,(void*)vaisseau_Bitmap, OBJ_SIZE_32X32,1, 0, i << 4, i << 3);
}
 
// Ceci charge un sprite un peu n'importe où

Bon, maintenant, pourquoi y a t-il un for avant la fonction CreateSprite ? Simplement parce que nous voulons creer 16 sprites (pour tester) similaires. Comme vous pouvez le voir, le numéro de chaque sprite est... i ! Ceci signifie que nous créons des sprites numérotés de 0 à 15. Enfin, vous voyez que les positions x et y sont (i«4) et (i«3). Je ne vais pas en expliquer trop maintenant, mais cela signifie i*16 et i*8. Il y aura un tutorial la-dessus plus tard, dans la partie Mathématiques... Pourquoi i*16 ? Parce que le premier sprite (i = 0) sera à 0, le second à 16, ... Donc nous auront des sprites partout sur l’ecran ! Cool !

Ensuite vient, dans la boucle principale, le code important à mémoriser :

while(1)
{
	
	// Utiliser la fonction MoveSprite sur tous les sprites...
	for (i = 0; i < 16; i++) 
             PA_MoveSprite(i);
	// La fonction MoveSprite verifie si vous touchez un sprite, et le deplace si c'est le cas... Sympa si vous avez plusieurs sprites autour
 
	PA_WaitForVBL();
}

C’est une boucle principale basique, avec une seule fonction : PA_MoveSprite... Maintenant, cette fonction ne peut être plus simple : elle verifie si un numéro de sprite donné, sur l’ecran du bas, est un sprite touché par le stylet... Si c’est le cas, elle reliera les 2 entités, le sprite et le stylet deviendront attachés. Aussi longtemps vous maintiendrez le stylet appuyé, le sprite se deplacera vers la position du stylet :-)

Et pourquoi la boucle for encore ici ? Car nous voulons tester les sprites numérotés de 0 à 15 ! Yup, c’est simple...

Vous pouvez maintenant compiler le code et tester sur votre DS, car cela crash avec dualis r12 (pas r11)... Vous verrez que ce code simple peu donner de très bons résultats, sans trop d’efforts !

PA_SetSpriteXY

PA_SetSpriteXY

Maintenant vient certainement la fonction la plus importante en ce qui concerne les sprites !! La fonction SetSprite !! Son utilisation est simple et basique :

PA_SetSpriteXY(screen, sprite, x, y);

Cela pourrait-il être plus simple à comprendre ? Vous avez juste à donner quel sprite à bouger, l’écran (0 en bas ou 1 en haut), et la nouvelle position, en x et y, et le sprite est alors assigné à cette nouvelle position. Il n’y a qu’une chose que vous avez à connaître vraiment : La position en x,y est celle du coin supérieur gauche. Donc, si votre sprite fait 32×32, il sera utile de donner comme coordonnées x-16 et y-16 pour voir le sprite se centrer sur x, y.

Il est également possible d’utiliser les fonctions PA_SetSpriteX et PA_SetSpriteY si vous ne voulez pas définir en même temps les nouveaux x et y...

limites X et Y

Il y a 2 autres fonctions disponibles : PA_GetSpriteX(screen, sprite) et PA_GetSpriteY(screen, sprite) qui renvoient les coordonnées du sprite dans le système de PAlib... La premiére chose que vous constaterez est que ces valeurs seront toujours dans une fourchette entre 0 et 511 en X, et entre 0 et 255 pour Y, car ce sont les limites hardware... En considérant ceci, si vous utilisez des valeurs hors des fourchettes, le sprite fera le tour de l’écran... Un sprite à la position X = 512 aura en fait une position X = 0, et sera donc affiché ! Pareil pour les Y, avec des valeurs plus limitées...

Touches

Maintenant que vous savez vous servir de cette fonction, la première chose que nous allons voir est comment déplacer un sprite avec la croix directionnelle de la DS ! Maintenant, regardons le code de PAExamples/Sprites/MoveSpritewithKeys...

Je ne vais copier que les lignes importantes :

s32 x = 0;    s32 y = 0; // position du sprite... 
 

Il y a 2 variables (nous allons utiliser maintenant des fonctions que vous devez dèja connaitre :-P) qui vont enregistrer la position du sprite...

x += Pad.Held.Right - Pad.Held.Left;
y += Pad.Held.Down - Pad.Held.Up;

Qu’est-ce que c’est ?? Je sais que ce n’est pas réellement ce qui vient en tête à propos des mouvements de sprites. La façon la plus simple aurait du être :

if (Pad.Held.Right) x = x + 1;

(pour deplacer le sprite d’1 pixel...)

Ici, que se passe-t-il si vous pressez ‘droite’ ? Pad.Held.Right prend une valeur de 1, et Pad.Held.Left prend une valeur de 0. Donc

x += Pad.Held.Right - Pad.Held.Left;   -> x += 1 - 0;

Donc cela déplacera la position en X de 1 pixel, exactement comme faisait l’autre code, sauf qu’ici ça marche pour ‘gauche’ (-1 pixel) et n’utilise pas de if, qui est lent !

Pareil pour ‘haut’ et ‘bas’...

Maintenant, allons à la dernière partie du code :

PA_SetSpriteXY(0, // ecran
		0, // sprite
		x, // position en x
		y); // position en y...

Assez simple, déja expliqué... Maintenant que les positions X et Y ont été mises à jour en fonction du pad, nous allons bouger le sprite vers cette position !

Vous êtes maintenant libre de compiler et de tester (marche même sous dualis...)

Pour ceux qui veulent aller un peu plus loin, comment pouvez-vous changer la vitesse du mouvement ? Dire que vous voulez avancer de 2 pixels au lieu de 1...

...

..

.

Trop tard ! La réponse est :

x += (Pad.Held.Right - Pad.Held.Left) * speed;
y += (Pad.Held.Down - Pad.Held.Up) * speed;

(speed peut avoir n’importe quelle valeur, comme 2 pour 2 pixels...) Si vous ne me croyez pas, testez-moi, remplacez la valeur de speed selon le nombre de pixels à parcourir par cycle (frame) et vous verrez le sprite se déplacer plus vite :-P

Stylet

Pour vérifier ce truc, ouvrez seulement l’exemple MoveSpriteWithStylus, et vous verrez qu’il est encore plus simple à comprendre que le précédent ! En fait, il n’y a qu’une ligne de code importante (le reste est le chargement du sprite et l’affichage de la position du stylet à l’écran)

PA_SetSpriteXY(0,0,Stylus.X,Stylus.Y);

Cela placera le sprite 0, sur l’écran du bas, à la position du stylet en X et en Y... Je pense qu’il n’y en a pas plus à dire :-)

Avec tout cela, vous avez assez de connaissances pour programmer par vous même. Si vous débutez juste en développement DS, je vous recommande de passer au tuto suivant, sur les fond d’écrans (backgrounds) avant de revenir finir celui-là... Ou alors, lisez la partie sur les rotations puis passer au tuto suivant. Si vous êtes un programmeur expérimenté, vous êtes les bienvenus pour aller au bout de ce tutorial...

Sprite touché au stylet

PAlib présente des fonctions qui permettent de savoir si un sprite est cliqué avec le stylet. Cela est pratique pour activer certaines fonctions dans un jeu ou une application. Notez, cependant, que creer cette fonction par vous même sera plus rapide à executer, et elle sera parfaitement adapté à votre jeu, alors que la fonction de PAlib est plus générale et fonctionne pour tous...

Voici un exemple fait grâce à PAlib : SpriteTouched (les sources et le programme à compiler sont disponibles dans le dossier PAlibExamples\Sprites\SpriteTouched)

u8 i = 0; 
for (i = 0; i < 8; i++) PA_CreateSprite(0, i,(void*)mollusk_Sprite, OBJ_SIZE_32X32,1, 0, i << 5, i << 4);
 
PA_OutputSimpleText(1, 0, 10, "Please touch a sprite");
 
while(1)
{	
	// Now we'll test every sprite to see if we touch it...
	for (i = 0; i < 8; i++) {
		if (PA_SpriteTouched(i)) PA_OutputText(1, 0, 15, "Sprite %d  ", i);
		// If we touch the sprite, returns 1...
	}
 
	PA_WaitForVBL();
}

Les deux premières lignes créent des sprites à différentes positions... c’est la meme chose que l’exemple de déplacement de sprite précédent, rien a dire de plus là-dessus...

Mais dans la boucle, on trouve le code le plus interessant : PA_SpriteTouched(sprite). Cette fonction simple renvoie 0 si le sprite n’est pas touché et 1 s’il l’est... C’est suffisant pour tester un sprite à la fois, mais ici nous avons 8 sprites différents. C’est pourquoi j’ai ajouté la boucle for, qui est ici pour tester les sprites de 0 à 7 et pour afficher à l’écran quel sprite a été touché. Vous pouvez remplacer le texte de sortie par quelque chose du style spritetouched = i, ce qui permettra de stocker le numéro du sprite touché dans la variable spritetouched...

Rien de plus à dire sur cet exemple, c’est simple et basique :-) J’espère que vous avez tout compris !

Rotation et Zoom

Maintenant vient le tour d’un autre tuto important, celui concernant les rotations et les zooms ! Comme je dois l’avoir dit plus tôt, les sprites peuvent être tournés et/ou zoomés à l’envie, mais il existe une petite limitation : même si tous les sprites peuvent subir une rotation, un sprite ‘tourné’ doit se voir attribuer un rotset , et seulement 32 rotsets sont disponibles par écran... Alors, comment tous les sprites peuvent-ils être ‘tournés’ quand seulemnt 32 rotsets sont disponibles ????? Ben, vous pouvez avoir plusieurs sprites pour un seul rotset, et, dans ce cas, tous ces sprites seront ‘tournés’/redimensionnés selon les mêmes critères ! Imaginez que vous ayez un vaisseau spatial, qui peut tourner, et qui est fait de plusieurs parties (disons 2 sprites pour les ailes, 1 pour le fuselage, 1 pour le cockpit, et 1 pour les canons;;;). Les parties pourront être ‘tournées’ et redimensionnées exactement de la même manière. Au lieu d’avoir différents rotsets et différents comportements, autant assigner à toutes les parties le même rotset :-)

Il y a 3 exemples pour les rotations et les zooms dans les exemples des sprites PAlib : Rotation, Zoom et RotZoom, qui utilisent 3 différentes fonctions, l’un pour seulement la rotation, un autre seulement pour le zoom, et le troisième qui fait les 2 simultanément...

Rotation

Nous allons commencer avec les rotations de sprites... L’exemple est Sprite_Rotation, et je vais copier ici la partie interessante du code :

// Activation des rotations pour ce sprite
PA_SetSpriteRotEnable(0,// ecran
		      0,// numéro du sprite
		      0);// numéro de rotset. Vous disposez de 32 rotsets (0-31) par ecran. 2 sprites avec le même rotset auront le même comportement...
 
u16 angle = 0; // angle de rotation...
 
while(1)
{
	++angle; // changement de l'angle
	angle &= 511; // limitation de la portée (0-511). Fonctionne seulement avec 1, 3, 7, 15, 31, etc... (2^n  - 1)
	
	// Fonction rapide pour rotations sans zoom...
	PA_SetRotsetNoZoom(0, //ecran
			   0, // rotset
			   angle); // angle, de 0 à 511
	
	PA_WaitForVBL(); // Synchronisation
}

Pour commencer, créez un sprite, comme d’habitude, avec sa palette, et tout le toutim... Ensuite, vous devez activer en mode rotation/zoom et lui donner un rotset (de 0 à 31, vous vous rappelez ?), qui est fait par PA_SetSpriteRotEnable(ecran, sprite, rotset). Une fois cela fait, le sprite est prêt à tourner ! Lorsque vous voulez arréter la capacité de rotation, vous pouvez utiliser PA_SetSpriteRotDisable(ecran, sprite).

Les quelques lignes qui suivent ne sont pas trop importantes, il s’agit juste de déclarer une variable pour l’angle, et d’ajouter 1 degrés à chaque cycle... Il reste une chose importante à savoir à propos des angles. Il ne s’agit d’angle dans un systéme à 360°, mais dans une echelle allant de 0 à 511, et dans le sens inverse des aiguilles d’une montre... Pourquoi ? Parce que c’est ce qu’il y a de mieux pour la ds et que cette methode est plus rapide qu’avec des angles ‘normaux’... Vous allez vous habituer :-)

Bon, qu’est-ce que ce angle &= 511; ? Vous aurez une explication plus compléte à propos de l’operateur & dans le tuto sur les maths à venir. Tout ce que vous devez savoir est qu’il limite la portée d’une variable à une valeur indiquée, mais ne prend en compte que les nombres de forme 2^n - 1 : 1, 3, 7, 15, 31, 63, 127, 255, 511, etc... Donc, dans l’exemple, la variable angle est limitée à une fourchette 0-511, ce qui est exactement la limite de notre angle ! Hehehe... Que se passe-t-il si la valeur dépasse 511 ? Elle revient à 0, et ainsi de suite. Donc, 512 vous donnera 0, 513 donnera 1, etc... Et cela est aussi vrai pour les valeurs négatives, -1 donnera... 511 ! C’est cool (et aussi la raison pour laquelle nous n’utilisons pas un systéme angulaire à 360°).

Ensuite vient une fonction importante, PA_SetRotsetNoZoom(ecran, rotset, angle); . N’oubliez jamais qu’ici, vous manipulez le rotset, et non le sprite, c’est pour cela que vous n’utilisez pas le numéro de sprite... Vous donnez seulement l’ecran, le rotset, et l’angle (0-511) comme arguments, et PA_SetRotsetNoZoom fera tourner le sprite juste comme vous voulez !

Comme cet exemple à un angle augmenté de 1 à chaque cycle (frame), vous pouvez compiler l’exemple et regardez sur le hardware comment ça tourne... Ca peut tourner sur DualiS... mais pas tout le temps, sorry.

Derniére chose : le sprite tourne autour de son point central :-)

Zoom

Maintenant que nous avons vu comment faire tourner un sprite, nous allons voir comment zoomer. C’est assez simple, comme d’habitude, et l’exemple Sprite_Zoom, est très similaire à ce que nous venons de voir... Je ne vais pas coller la partie d’activation du rotset, vous l’avez déjà vu :-P, ok ?

u16 zoom = 256; // Zoom. 256 signifie aucun zoom, 512 est deux fois plus petit, 128 est 2 fois plus gros....
	
while(1)
{
	zoom -= Pad.Held.Up - Pad.Held.Down; // Change le zoom en fonction des touches haut et bas du pad...
 
	// Fonction rapide pour zoomer sans rotation...
	PA_SetRotsetNoAngle(0, //ecran
			    0, // rotset
			    zoom, zoom); // Zoom horizontal et vertical. Vous pouvez déformer un sprite si vous le souhaitez, en ne zoomant que sur un axe...

Pour commencer, vous avez la variable de zoom... Et pourquoi est elle à 256 ? Parce que... 256 signifie PAS de zoom. La DS fonctionne selon les modes suivants :

  • 256 correspond à ‘pas de zoom’, ou alors taille 100%...
  • 512 est un zoom de moitié, soit 50% de la taille...
  • 128 est le zoom double, ou 200% de la taille...

Je sais que ça fait un peu mal au début, mais vous allez vous y habituer. Pour faire simple, le zoom de base est à 256, les valeurs plus petites feront un plus gros sprite, et les grandes valeurs donneront un sprite plus petit. Ici, la variable de zoom est modifiée par les touches haut et bas du pad, donc vous pouvez vérifier le résultat par vous même...

Maintenant, jetons un coup d’oeil sur la fonction importante du zoom : PA_SetRotsetNoAngle(ecran, rotset, zoomx, zoomy);. Pourquoi avons nous 2 valeurs de zoom ??? Parce que vous pouvez zoomer sur votre sprite en X ou en Y indépendamment si vous voulez ! Bien que la plupart du temps vous vouliez zoomer de la même manière dans les 2 axes, il est bon d’avoir d’autres types de zoom... J’ai utilisé cela dans dans une démo de vaisseau spatial, afin de les allonger et de les aplatir pour donner un effet durant les phases d’hyperespace.

Il suffit de compiler et de tester ! Vous verrez ce que ça donne :-) Le sprite est zoomé sur son point central, comme pour les rotations...

Si vous êtes intelligent (ou que vous avez été attentif en lisant ce tutoriel et l’exemple du zoom dans PAlib), vous devez avoir 2 questions, qui sont en fait presque les mêmes :

  1. Que se passe t-il lorsque le zoom fait un sprite trop grand ? Après tout, lorsque vous créez le sprite, vous définissez sa taille, et un trop gros zoom peut dépasser cette taille, et...ne pas fonctionner ??
  2. Pourquoi n’ai-je pas parlé de PA_SetSpriteDblsize(0, 0, 1);, qui se trouve pourtant dans l’exemple PAlib ??

Bon, premièrement : si votre sprite est trop gros, tout se qui dépasse du cadre défini du sprite (comme 32 X 32, par exemple) sera simplement coupé ! Ok, c’est vraiment limitant, mais bon, Nintendo à pensé à tout ! Et c’est là que la question 2, sur le PA_SetSpriteDblsize(ecran, sprite, enable/disable) entre en jeu ! Si vous doublez la taille d’un sprite par cette fonction, cela ne va pas doubler la taille du sprite, mais doubler la taille de son cadre ! Donc un sprite 32 X 32 deviendra un sprite 64 X 64 (avec une image 32 X 32 en son centre), et un sprite 64 X 64 deviendra... un 128 X 128 ! Wouaouh, c’est un gros sprite, ça :-P

Maintenant que vous savez cela, vous voyez comment passer outre la taille limite d’un sprite si vous désirez zoomer un peu plus... Vous devez prendre en compte une dernière chose : si vous doublez la taille du cadre, et sachant que le sprite se situe dans le coin supérieur gauche du cadre... cela change le centre du sprite à l’ecran... donc, si vous placez 2 sprites à des coordonnées identiques, mais l’un de taille doublée et pas l’autre, vous verrez qu’ils ne sont pas placés au même endroit... Ne l’oubliez pas !

Rotation et zoom simultanés

Ces 2 exemples vous ont appris à faire des rotations et zoomer, mais, en fait, vous pouvez faire les 2 enmême temps si vous voulez... L’exemple PA_lib est ‘Sprite_RotZoom’, et cela ressemble à ce que l’on a vu, mais contient des variables de zoom et d’angle... Je ne vais pas coller de code ici, comme c’est inutile, regardez seulement l’exemple :-)

La seule fonction est PA_SetRotset(ecran, rotset, angle, zoomx, zoomy);. C’est comme une combinaison des 2 fonction précédentes, rien de terrible !

J’espere que vous êtes prêts et que vous savez tout ce que vous voulez à propos des rotations et zooms de sprites ! Prêt pour une nouvelle leçon...

Renversement de sprite

Le renversement de sprite est simple sur la DS, donc, même si cela peut sembler un sujet mineur, je vais vous montrer comme c’est simple et important... J’ajouterai un exemple dans la prochaine mise à jour (Sprite/Flips).

Il n’y a que 2 fonctions pour renverser un sprite :

  • PA_SetSpriteHflip(ecran, sprite, 1/0 pour oui/non), pour les renversements horizontaux (gauche/droite)
  • PA_SetSpriteVflip(ecran, sprite, 1/0 pour oui/non), pour les renversements verticaux (haut/bas)

C’est trop simple pour vous ! 1 active le retournement, 0 l’enléve, c’est tout. Vous pouvez renverser horizontalement, verticalement ou les 2 en même temps.

Maintenant, où/comment cela peut-il être utilisé ? Imaginez que vous codez un jeu de combat... Comme Street Fighter 24532 AlphaBetaGamme XX. Vous avez seulement un joueur regardant vers la droite, et un autre regardant vers la gauche. Il y a 2 moyens d’arriver à cela :

  • En ayant en double tous les graphiques, l’un pour la gauche, l’autre pour la droite... C’est du boulot, ça prend de la place, et c’est long à afficher/mettre à jour...
  • En utilisant les renversement inversant la gauche et la droite ! Simple et rapide...

Qu’est-ce qui vous semble être la meilleure solution ? :-P

L'effet Mosaïque

La Mosaïque est un effet facile d’utilisation, mais moi je ne l’aime pas trop :-P Il a été utilisé dans Super Mario Bros, par exemple, et change un peu l’apparence du sprite en remplaçant un pixel unique par des carrés d’une taille définie (passer de carrés de 1×1 à des carrés de 15×15). A quoi ça sert exactement ? Cet effet sera utile notamment pour les effets de transitions sur les sprites, un peu comme un effet de flou, etc... Mais bon, je l’avais bien dit, je ne l’aime pas trop et ne l’utilise jamais.

Allez voir l’exemple Mosaïque sur un sprite qui sera disponible dans la prochaine version de PAlib...

En tout les cas, la DS et PAlib vous offre un control simple sur l’effet Mosaïque. Dès que vous avez créé un sprite, vous pouvez activer l’effet pour ce dit sprite en utilisant PA_SetSpriteMosaic(Screen, Sprite, Mosaic on/off (1/0));.

Une fois ceci fait, vous pouvez modifier les valeurs mosaïques, horizontalement et verticalement (donc vous pouvez avoir des carrés de 1×8 pixels si vous le souhaitez !) en utilisant la fonction suivante : PA_SetSpriteMosaicXY(screen, horizontal block size, vertical size...);

Avez-vous vu la grosse contrainte de ceci ? Et bien... Vous pouvez controler chaque sprite pour activer ou désactiver l’effet Mosaïque, mais le carré Mosaïque s’applique à tous les sprites actifs sur l’écran ! Ce qui veut dire que vous ne pouvez avoir un certain sprite avoir un certain effet, et l’autre sprite un autre effet... C’est le deuxième raison pour laquelle je n’aime pas tant cet effet...

Compilez l’exemple et tester sur la DS, ça devrait marcher (même si ça ne fonctionne pas sur DualiS :-().

La Transparence

La transparence, ou Alpha-Blending, peut être utile dans un jeu ou une application. Il semble grand et professionnel, et n’est en fait pas si difficile que ça à faire ! PAlib utilise le hardware DS pour le réaliser, mais celui-ci a une limitation importante : même si vous pouvez placer n’importe quel sprite que vous aimez avec de la transparence, tous les sprites que vous aurez mis en Alpha-blending auront le même niveau de transparence… Ainsi vous ne pouvez pas avoir par exemple un sprite moitié-transparent et les autres presque totalement… Ils seront tous identiques… Il est assez facile de comprendre le code, et vous avez un exemple d’AlphaBlending dans les exemples de sprite…

PA_SetSpriteMode(0, // ecran
 		 0, // Sprite
		 1); // Alphablending
	
 
s16 alpha = 7; // Niveau de transparence
 
// Activation de l'alpha-blending
PA_EnableSpecialFx(0, // ecran
		   SFX_ALPHA, // Mode Alpha blending
		   0, // Nothing
		   SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD); // Tout normal
 
while(1) // Boucle infinie
{
	alpha += Pad.Newpress.Up - Pad.Newpress.Down;
	PA_SetSFXAlpha(0, // Ecran
			alpha, // Niveau alpha, 0-15
			15); // Laisser à 15
 
	PA_WaitForVBL();
 
}

Le sprite est créé comme n’importe quel sprite normal, l’option de transparence est activée avec PA_SetSpriteMode(screen, sprite, mode) ; Il y a différents modes, vous pouvez examiner le code, il faut juste vous rappeler que 0 ne donne pas de transparence (normal donc), et 1 donne de la transparence...

Une fois activé, le sprite n’est pas encore affecté. Vous devez d’abord activer le système spécial d’effet de DS, Il faut faire appel à PA_EnableSpecialFx(Screen, SFX_ALPHA (mode de mélangement d’alpha), 0 (fixé à 0 pour maintenant), SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD) ; Cette grande liste permet de donner de la transparence au sprite, désolé il n’y a pas plus simple ...

PA_SetSFXAlpha(screen, niveau de alpha(0-15), niveau normal (fixé à 15)) ; est la dernière fonction importante (la variable d’alpha que je mets est modifiée par égalité en haut et en bas...), qui est employée pour placer le niveau de transparence...

Vous devez juste compiler et examiner les différentes valeurs en appuyant sur la touche du haut et du bas pour voir à quoi ressemble le sprite...

Frames

A quoi servent-elles ? Elles peuvent être employées pour animer un sprite de manières complexes, de la faire vivre ! Je vais bientôt parler des animations de sprites, parce que les frames sont d’une certaine manière plus faciles à utiliser, mais aussi plus flexible... cependant, leur maitrise , peut prendre un certain temps. Première chose : si vous voulez employer des frames, vous devez mettre toutes les frames du sprite dans une image simple en la convertissant, et ces frames doivent être les unes au dessus des autres, comme ceci : C’est le secret des animations simples... Cet exemple ne montrera aucune animation, mais c’est le plus commun.Vous pourrez ainsi changer de frame selon la direction... Dans cet exemple, le sprite regardera dans la direction donnée, c’est tout ce dont vous aurez besoin pour le faire venir à la vie !

PA_CreateSprite(0, 0,(void*)frames_Sprite, OBJ_SIZE_16X32,1, 0, 128-16, 64);
 
while(1)
{
	if (Pad.Held.Up) PA_SetSpriteAnim(0, 0, 0); // screen, sprite, frame
	if (Pad.Held.Down) PA_SetSpriteAnim(0, 0, 2); // screen, sprite, frame
	if (Pad.Held.Left) PA_SetSpriteAnim(0, 0, 3); // screen, sprite, frame
	if (Pad.Held.Right) PA_SetSpriteAnim(0, 0, 1); // screen, sprite, frame		
 
	PA_WaitForVBL();
}

Comme vous pouvez voir, le sprite est créé comme n’importe quel sprite normal ! C’est ce qui est cool... Puis, vous voyez le code pour changer la frame, PA_SetSpriteAnim(screen, sprite, le nombre);. Dans ce code, la frame (ou l’image en francais) est changée selon l’appui d’une touche de la croix directionnelle, afin d’avoir le regard du sprite dans la bonne direction... Rien de plus à dire, nous allons donc passer aux animations de sprite ! Ah, une chose que vous devez savoir avant de continuer... Changer la frame des sprites signifie copier la nouvelle image au-dessus de la vieille. Ce qui signifie que cela prend du temps de mettre à jour. Ainsi si trop de frames sont mises à jour à chaque tour, le jeu ralentira (mais pas beaucoup rassurez-vous ^^)...

Animations

Animations Simple

L’animation de Sprite est devenue vraiment facile... Maintenant, vous devez juste charger un sprite, et dire à PAlib de l’animer, d’une frame à une autre, et elle fera une boucle automatiquement. C’est comme pour le choix de frame, vous devez toujours mettre toutes les images dans le même dossier d’image de sprite, une sur l’autre. Voici l’image utilisée dans cet exemple :

Je signalerai juste la partie intéressante du code :

// Load the sprite palette, 
PA_LoadSpritePal(0, // Screen
		0, // Palette number
		(void*)explosion_Pal);	// Palette name
	
// Here, we'll load a few similar sprites sprite to animate... at different speed
PA_CreateSprite(0, 0,(void*)explosion_Sprite, OBJ_SIZE_64X64,1, 0, 0, 64);
PA_CreateSprite(0, 1,(void*)explosion_Sprite, OBJ_SIZE_64X64,1, 0, 64, 64);	
PA_CreateSprite(0, 2,(void*)explosion_Sprite, OBJ_SIZE_64X64,1, 0, 128, 64);	
PA_CreateSprite(0, 3,(void*)explosion_Sprite, OBJ_SIZE_64X64,1, 0, 196, 64);		
	
// Start the animation. Once started, it works on its own !
PA_StartSpriteAnim(0, // screen
		0, // sprite number
		0, // first frame is 0
		6, // last frame is 6, since we have 7 frames...
		5); // Speed, set to 5 frames per second						
PA_StartSpriteAnim(0, 1, 0, 6, 15); // for the second one, speed of 15 fps...	
PA_StartSpriteAnim(0, 2, 0, 6, 30); // for the third one, speed of 30 fps...	
PA_StartSpriteAnim(0, 3, 0, 6, 60); // for the last one, speed of 60 fps...

Pourquoi charge-t-il 4 sprites ? Juste parce que j’ai voulu montrer comment il fait avec 4 vitesses différentes d’animation. Comme vous pouvez le voir, le sprite est chargé comme d’habitude , rien spécial à son sujet, comme toujours... Après, le PA_StartSpriteAnim(screen, sprite, première frame, dernière frame (incluse !), vitesse (dans la fonction de fps)). Une fois chargée, elle anime le sprite exactement comme vous l’avez demandé, à la vitesse donnée, et indéfiniment. Vous pouvez employer PA_StopSpriteAnim(screen, sprite) pour l’arrêter, ou PA_SpriteAnimPause(screen, sprite, pause (1 pour faire une pause, 0 pour ne pas la faire)) pour mettre en pause/reprendre l’animation... Vous pouvez compiler cet exemple et examiner sur votre DS ou sur un emulateur!

Animations Complexes

Ce deuxième exemple d’animation n’emploie pas plus de fonctions que le premier, mais ils vous montre plutôt comment mieux les employer ... C’est l’exemple SpriteAnim2...

L’image est semblable au tuto sur les frames, mais avec plus d’images ! Vous noterez que le sprite a quelques animations qui sont ajoutées pour la direction haut et droit... mais pas à gauche ! Pourquoi ? Puisque l’animation gauche est une copie, renversée, de la bonne animation...(voir tuto sur le renversement plus haut ;) ) Comme ça, vous eviterez de prendre plus d’espace pour rien, il est simplement plus facile de renverser le sprite à l’aide du hardware de la DS... Vous economiserez alors plus de 25% de place,ce qui est réellement beaucoup !! Car se sont les graphismes qui prennent la majeure partie d’une ROM de DS...

Voici maintenant le code !

while(1)
{
	// Animation code...
	if(Pad.Newpress.Up) PA_StartSpriteAnim(0, 0, 0, 3, 6);
	if(Pad.Newpress.Down) PA_StartSpriteAnim(0, 0, 8, 11, 6);		
	if(Pad.Newpress.Right) {
		PA_StartSpriteAnim(0, 0, 4, 7, 6);	
		PA_SetSpriteHflip(0, 0, 0);
	}
	if(Pad.Newpress.Left) {
		PA_StartSpriteAnim(0, 0, 4, 7, 6);	
		PA_SetSpriteHflip(0, 0, 1);
	}
	if(!((Pad.Held.Left)||(Pad.Held.Up)||(Pad.Held.Down)||(Pad.Held.Right))) PA_SpriteAnimPause(0, 0, 1);
	// Moving Code
	y += Pad.Held.Down - Pad.Held.Up;
	x += Pad.Held.Right - Pad.Held.Left;		
	PA_SetSpriteXY(0, 0, x, y);
	
	PA_WaitForVBL();
}

Le sprite est chargé comme n’importe quel sprite, ainsi je ne l’ai pas montré ici... if(Pad.Newpress.Up) PA_StartSpriteAnim(0, 0, 0, 3, 6); Ce code lance l’animation de la frame de 0 à 3 quand la touche Haut est appuyée... Les fps sont vraiment lentes : 6 frames par seconde ! Pourquoi ? Puisque l’animation a très peu d’images, car ce serait trop rapide avec un taux plus élevé d’images. Ce code n’est absolument pas parfait, comme vous pouvez le voir, il ne donne pas de très bons résultats si vous tenez différentes directions en même temps, mais c’est juste le code le plus simple que je pouvais faire... si vous avez besoin de quelque chose de mieux, vous devriez maintenant pouvoir le faire par vous-même :-P

if(Pad.Newpress.Right) {
	PA_StartSpriteAnim(0, 0, 4, 7, 6);	
	PA_SetSpriteHflip(0, 0, 0);
}

Ce fragment de code n’est pas le même que pour les directions haut/bas, parce qu’il vérifie si la partie droite du sprite a été renversée horizontalement ou pas (rappelez-vous, cela économise de l’espace dans la ROM...). C’est pourquoi nous avons utilisé la fonction de Hflip pour la partie gauche... Je ne détaillerai pas le code du déplacement, c’est celui que nous avons employé avant dans le tuto de mouvement... Compilez et testez !

Animations Prolongées

La dernière extension du système d’animation de PAlib est... les animations prolongées ! Qu’est-ce que c’est ? ? ? elles vous permettent un contrôle facile sur les animations qui sont jouées. En les chargeant avec la fonction d’AnimEx au lieu de l’Anim one , vous avez 2 options supplémentaires : * le type d’Animation ANIM_LOOP (0) étant normal, et ANIM_UPDOWN (1) étant une animation de va-et-vient * nombre de Cycle , étant le nombre de fois que vous voulez que l’animation soit jouée. Le régler à -1 lui fera exécuter l’animation infiniment ... Pour ce qui concerne l’ANIM_UPDOWN, une animation de va-et-vient complète compte 2 cycles... Comme vous pouvez le constater, l’animation normale est juste comme la prolongée (ANIM_LOOP), mais réglé à une valeur par défaut pour faire l’animation à l’infini... Le code est un copier/coller de l’exemple, seule la fonction de départ a changé.

// First animation will be normal
PA_StartSpriteAnim(0, // screen
		0, // sprite number
		0, // first frame is 0
		6, // last frame is 3, since we have 4 frames...
		5); // Speed, set to 5 frames per second		
						
// Extended animations for the rest									
PA_StartSpriteAnimEx(0, 1, 0, 6, 5, ANIM_ONESHOT); // just play it once...
PA_StartSpriteAnimEx(0, 2, 0, 6, 5, ANIM_UPDOWN, -1); // back and forth, infinite number of times	
PA_StartSpriteAnimEx(0, 3, 0, 6, 5, ANIM_LOOP, 5); // Play it 5 times

Le macro d’ANIM_ONESHOT est là pour dire que vous voulez jouer l’animation juste une fois. Quand il finit, il revient à la première frame... Si vous voulez qu’il reste à la dernière frame, employez le type d’ANIM_UPDOWN et 1 cycle... Compilez et appréciez !

Profondeur

Souvent, dans les jeux en 3D, On a besoin du recouvrement de sprite. Les gens doivent se voir par dessus les autres, etcaetera. Afin de faire ceci, vous devez établir des priorités. Il y a 2 genres de priorités sur la DS : * Priorité De Sprite : Le sprites ayant les numéros les plus petits seront affichés devant les plus grand. * Priorité De Fond : Pour dépasser la priorité de sprite, vous pouvez changer la priorité de fond. Par défaut, tous les sprites sont devant le fond 0. Vous pouvez placer un sprite pour être devant un fond différent, 1, 2, ou 3. Un sprite sur le fond 2 sera derrière tous les sprites avec une priorité de fond de 0 ou de 1, et devant tous les sprites avec une priorité de 3, sans se préoccuper de leur priorité de Sprite...

Je ne mettrai aucun code ici, juste la fonction : PA_SetSpritePrio(screen, sprite, priorité (0-3)); C’est à peu près tout ce qu’il y a à savoir :-)

Mollusk 29/11/2005 17:42

Dual Sprites

Une des dernières extension à PAlib a été la création des fonctions dual Sprites. Je dois admettre que j’étais un peu contre au début, mais elles étaient tellement demandées que j’ai fini par les faire... Ca m’a pris pas mal de temps et c’était assez rébarbatif : principalement du copier-coller et des petites modifications aux fonctions de sprite.

Assez parlé de moi... les Dual Sprites, qu’est-ce que c’est ??? Eh bien, c’est une version modifiée des sprites, qui permet un affichage sur les 2 écrans comme s’il n’y avait qu’un seul sprite ! Ceci ne signifie pas que un sprite sera affiché sur les 2 écrans en même temps, mais au lieu d’avoir une zone d’affichage de 0-191, elle passe à 0-383, ce qui veut dire que nous utiliserons les deux écrans comme un seul (une fusion en d’autres termes)! Vos sprites pourront donc se déplacer d’un écran à l’autre très facilement. C’est utile pour des jeux comme un Pong, Space Invader, etc...

Le point “y = 0” est le point en haut à gauche de l’écran supérieur. A peu près toutes les fonctions que nous avons déjà vues sont disponible en utilisant le système Dual Sprite de PAlib, elles contiennent le préfixe “Dual” : PA_DualCreateSprite(...), PA_DualSetSpriteXY(sprite, x, y), etc... La seule différence est que ces fonctions ne demandent pas un numéro d’écran (0 ou ), Logique, puisque vous les considérez comme un seul écran...

Je viens de voir que je n’avais pas encore ajouté d’exemple à PAlib, je le ferai peut-être plus tard... Il ne s’agira que de copier-coller, et c’est tellement simple que je ne pense pas que vous en ayez réellement besoin.

Une dernière chose, assez importante : vous avez probablement remarqué que les écrans de la DS ne se touchent pas... ils ont un espace entre eux, et ainsi je me suis demandé comment contrôler cet espace dans les fonctions Dual... Ma dernière décision s’est portée vers un système flexible, j’ai donc ajouté une dernière fonction : PA_SetScreenSpace(espace en pixels). Par défaut, cette valeur est de 48 pixels, c’est la valeur avec laquelle j’étais le plus à l’aise... Cela signifie qu’en déplaçant un sprite d’un écran à l’autre, il se déplace comme s’il y avait 48 pixels entre les 2, pendant lesquels vous ne voyez pas le sprite s’il est trop petit... Evidemment, un sprite de 64×64 sera toujours visible, car il fait plus de 48 pixels... Si vous voulez faire un Pong, vous pouvez laisser cette valeur à 48, ou la mettre à 64 pour avoir peu plus d’espace. Mais si vous faites un shoot’em up, vous pourriez préferer ne pas cacher d’espace au joueur. Dans ce cas, optez pour 0 ou 16, 0 agira comme si les écrans se touchaient...

Optimiser la mémoire et la vitesse

Ceci est un chapitre très important, mais il est vraiment réservé aux utilisateurs avancés... Si vous êtes juste débutant dans le développement DS, revenez-y plus tard...

Fonctionnement des Sprites

Je pense qu’il manquait une petite partie ici : Le fonctionnement du système de sprites... Apprendre ceci vous aidera pour l’organisation de vos graphiques et pour optimiser vos codes...

Qu’est ce qu’un sprite ? ce n’est pas une simple entité, mais un mélange de plusieurs choses :

1. l’image, en ‘format basique’, c’est votre tableau de Name_Sprite, converti avec PAGfx ou gfx2gba ou autre chose... C’est en gros la partie graphique, qui sera copiée dans la VRAM (Video Ram), à un emplacement réservé aux sprites (un emplacement pour l’écran du haut, un autre pour l’écran du bas). Plusieurs sprites peuvent avoir le même graphique : il n’y a qu’une copie dans ce cas et en animant un sprite, son graphique dans la VRAM change, ce qui anime tous les sprites de la même manière.

2. Les palettes des sprites, que tous les sprites ont en commun. PAlib a par défaut 16 palettes pour les sprites, il peut donc y avoir 16 sprites avec une palette différente, ou 10 avec une seule palette etc... Dans beaucoup de cas (surtout au début), on utilise une seule palette pour tous les sprites...

3. La DS utilise les sprites grâce à OAM (Object A-chépuquoi M-chépuquoi ^^ j’arrive pas à m’en rappeler). OAM = Object Atribut Memory (a verifier) C’est un énorme tableau qui contient toutes les informations de chaque sprite... (numéroté de 0 à 127, avec 2 copies : unepar écran). Les infos sont du genre : position (X et Y), forme, taille (carré/rectangle, de 8 pixels ou plus...), renversement horizontal ou vertical, etc... Une info importante : rotation/zoom on/off, et numéro de Rotset (de 0 à 31).

4. Le rotset contient le coefficient de zoom et de rotation des sprites qui utilisent ce rotset. Comme il n’y en a que 32, On ne peut pas tourner 50 sprites de 50 facons différentes à la fois :/ Ca semble assez restrictif mais vous vous rendrez compte qu’on trouve assez vite une solution : utiliser le même zoom et la même rotation pour plusieurs sprites.

FAQ - Sprites

Q1. Mon sprite ne s’affiche pas !!

  • Ok, il y a plusieurs trucs à vérifier...
    • La palette du sprite est-elle chargée ?
    • Cette palette est-elle chargée sur le même écran que le sprite ?
    • La palette et le sprite ont-ils le bon numéro de palette ?
    • Peut être qu’il y a une erreur de code ou un élément mal utilisé
    • Le code qui suit empêche peut-être le fonctionnement du sprite
    • Vérifie les variables d’affichages ( à la fin du PA_CreateSprite... )

Q2. Quand je veux convertir mon sprites ou mon background, PAGC Frontend me dit : “Le fichier spécifié est introuvable”. Du coup, je ne peux pas afficher de sprites ou de backgrounds !

  • Il faut que les fichiers soient dans le même répertoire que le front-end.

Q3. Quand je veux convertir mon sprite ou mon background, PAGC Frontend me dit : “Unhandled exception” et me demande de continuer ou de fermer le programme. Bref, un bon gros plantage/bug!

  • Il suffit, comme précédemment, de mettre votre fichier image dans le même répertoire que le front-end.

Q4. En utilisant le système Dual Sprites, le sprite se met parfois à “clignoter” quand il change d’écran...?

  • Problème résolu, sur l’écran du bas une anim sur un sprite était lancé, mais le sprite était deleté sans enlever l’anim ce qui provoqua ce bug.

Q5. Comment gere t-on les effet lors de la sortie (ou entrée) de sprite sur l’écran ? (Dessin d’un sprite une partie en dehors de l’écran et une partie dessus)?

Q6. Comment supprimer un sprite ?

  • Il suffit d’utiliser la fonction PA_DeleteSprite(u8 screen,u8 obj_number) avec screen le numéro de l’écran où ce trouve le sprite a supprimer et obj_number le numéro associé au sprite à supprimer (utilisation plutôt facile ^^).

Q7. Peut-on déplacer plusieurs sprites associés à une seule palette sans les déplacer un par un (c.à.d. sans utiliser un PA_SetSpriteXY pour chaque sprite) ?

  • Non, je ne pense pas, La palette désigne les couleurs utilisées pour un certain nombre de sprites. Une fois ces sprites chargés, ils n’ont plus aucun lien entre eux.

Q8. Chaque sprite est associé avec un fichier palette, or 16 palettes seulement sont chargeables. Comment afficher plus de 16 sprites alors ?

  • En donnant le même nom de palette à plusieurs sprites lors de la conversion. Il est nul part écrit qu’il faut faire une palette par sprite.

Q9. Chaque sprite est associé avec un fichier palette, or 16 palettes seulement sont chargeables. Mais si on a besoin de plus de 16 palettes ??

Q10. Pourquoi n’y a-t-il pas de réponse à la Q5 ? Parce que personne n’en a la réponse.

Q11. Pourquoi lorsque je lance le Homebrew sur ma NDS avec mes linker les sprites, les background ainsi que les textes ne s’affiche alors que sur émulateur si ?

Q12. Quand j’essaye d’ajouter un autre sprite il y a le message d’erreur “mon vieux ...” ( 2 sprites à l’écran et une largemap et on veut en rajouter un troisième). Quel est le problème ? Comme dit dans le texte qui s’affiche, tu a besoin de plus de VRAM que disponible, essaye d’utiliser des sprites ou une largemap avec moins de couleurs et/ou sous un autre format, ça peut réduire la qualité de tes images mais elles utiliseront moins de RAM.

Q13. Comment faire pour que quand 2 sprites se touchent ils disparaissent ? * Tu detecte la collision des deux en comparant leurs coordonnées respectives puis tu regardes la question 6

Q14. Comment faire pour que un sprite retombe toujours a son endroit iniciale aprés etre monté ? * tu sauvegardes la hauteur initiale dans une variable, que tu utilise dans la condition d’arret de chute.

Q15. Peut-on délimiter un sprite à partir d’une image quelconque ? J’entends par là que, si on a une image de 162 par 80, comme les sprites ont des largeurs et des longueurs inférieures existe-t-il une fonction pour dire quelque chose du genre : “tu prends les pixels contenus par le rectangle dont le coin en haut à gauche est (0,0) et le coin en bas à droite est (64,64) et tu l’affiches sur l’écran 0 à (63,63)” ? Merci d’avance :) Je suis pas sur d’avoir compris ta question, mais d’après moi, sur n’importe quel logiciel, comme Paint, tu découpes ton sprite en plusieurs morceaux de 64×64 et tu les affiches séparément sur ton écran...

Pour poser d’autres questions, cliquez sur “éditer”, en bas à droite de cette grande case.

Prochain → Jour 5 - Backgrounds

Mollusk 28/11/2005 00:35

 
day4.txt · Dernière modification: 19/01/2010 19:53 par 88.174.84.35
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki