PDA

Voir la version complète : [NDS][Aide] PAlib - Afficher/Masquer un sprite


Dr.Vince
18/08/2006, 01h05
Bon voilà mon problème, en regardant la doc de palib je n'ai vu aucune méthode pour afficher et masquer un sprite

donc soit je n'ai pas trouvé la méthode soit celle-ci n'existe pas, et alors dans ce cas j'aurais voulu savoir quelle méthode vous utilisez ???

Merci

t4ils
18/08/2006, 01h41
une technique de bourrin consiste à la mettre en dehors de l'écran pour la faire disparaitre

sinon, tu peux supprimer une sprite avec : PA_DeleteSprite(screen,obj_number)

Dr.Vince
18/08/2006, 01h46
pour la première méthode cela oblige à stocker les coordonnées au cas ou on veuile faire réapparaitre le sprite

et la deuxième méthode n'est pas ce que je recherche


et effectivement y a pas ces fonctions dans palib, ce qui est quand même un peu hallucinant, enfin bon....

t4ils
18/08/2006, 02h24
je vois ce que tu veux en fait

genre PA_PrintSprite(ecran,numero_sprite,etat) avec etat un booléen pour masqué ou apparent

si il n'y a pas ca, en effet c'est balot :/

Yodajr
18/08/2006, 10h25
Quand je dois masquer un sprite et que je ne veux pas le balancer hors de l'écran, je le rend transparent en affichant une frame vide (je laisse toujours la premiere vide pour ce genre de cas)

Nameless
18/08/2006, 11h42
Sinon tu peux aussi ré-associer le sprite avec une palette que tu n'as pas chargée je pense...

Dr.Vince
18/08/2006, 12h02
@Yodajr : c'est sur DS et pas sur PSP :p mais bon le principe est adaptable

@Nameless : effectivement, mais ça fait un peu bidouille


bon c'est pas grave je vais implémenter un gestionnaire de sprite au dessus de PAlib >(

Yodajr
18/08/2006, 12h58
C'est sur GBA que je te parlais DrVince ;) (meme si ca n'a aucune espece d'importance)

La premiere frame de mon sprite est vide, quand je veux le masquer sans bouger ses coordonnées, j'affiche cette frame, je vois pas ce qu'il y a de plus simple...

http://hothmoon.free.fr/spritesheet.png

Dr.Vince
18/08/2006, 13h05
ok, j'avais pas compris ça comme ça....

donc effectivement c'est assez simple, mais ça convient pas pour ce que je veux faire....

Yodajr
18/08/2006, 13h30
mais ça convient pas pour ce que je veux faire....
Pourquoi ?
(je veux pas vendre ma methode à tout prix, mais juste savoir ce qui coince, au cas ou :) )

Dr.Vince
18/08/2006, 13h54
bah en fait c'est pour PA Card Games.

On est obligé de proposer toutes les fonctions qui vont bien aux codeurs de mini-jeux car ils ne peuvent pas se servir de PAlib.

or ta solution repose sur les gfx et pas sur du code situé dans la lib

Voilà

KerneL
18/08/2006, 16h03
On pourrait peut être se reposer sur la gestion de la transparence des sprites en poussant la transparence d'un sprite à fond pour le masquer? C'est la première solution qui me vient à l'esprit mais ça se discute ^^. (si tu veux je m'en charge, vu que les sprites sont mes amis dans cette lib)

Dr.Vince
18/08/2006, 17h11
justement faudra qu'on se croise sur msn car je suis en train de modifier pas mal de chose.

Yodajr
18/08/2006, 17h48
Oki l'optique du lib ne conviens pas effectivement ^^

MIKEGBA
18/08/2006, 18h55
Bon, à priori , pour pas afficher un sprite qui est hors écran, la solution est assez simple, c'est de tout simplement pas le mettre dans la spritelist de l'oam...


...alors je sais pas comment est fait votre gestionaire de sprite, mais une méthode ( que j'utilise ) consiste à rafraichier cette liste à chaque frame, ainsi tu n'as dans l'oam que des sprites affichés à l'écran et rien d'autre.

:)

Portnaouak
18/08/2006, 19h29
un truc tout simple est de redefinir sa priorité pour que le sprite se retrouve derriere les background. Comme ça il n'est pas apparent(cela sous entends que tu as un background)

SanoGP
15/09/2006, 23h33
Petit up improvisé ^^

Je commence à peine le dev sur DS avec la PALib et je me pose des questions qui rejoignent pas mal ce dont vous parlez ici :)

Venant de la GP et la Zodiac, j'ai toujours codé en utilisant un buffer qui était systématiquement affiché par l'OS. Donc, j'avais une simple copie de mon image dans la zone mémoire qui allait bien et tadaam, mon sprite apparaissait ^^ Et je mettais ce buffer à jour à chaque frame, sinon ca n'affichait plus rien :)

Ici j'ai du mal à bien piger comment ca marche, je met un "createsprite", rien dans la boucle et mon sprite reste affiché. Et je ne trouve pas du tout dans les sources la fonction qui s'occuppe véritablement de remplir ce satané buffer (enfin si j'ai vu des drawsprite et compagnie, mais... où sont-ils donc appelés ? pas dans le waitforvbl() qui est la seule fonction que j'appelle à chaque tour en tout cas ^^)

Comme tous mes programmes que je veux porter sont codé avec des structs et une variable qui dit si je dois afficher l'objet ou pas et qui est testé à chaque tour dans la boucle, j'ai un peu du mal avec la PALib ^^
Quelqu'un a une solution pour moi ? Ou des explications sur le fonctionnement de la PALib à ce niveau svp, ca m'aiderait beaucoup :)



(Psst, MikeGBA, ca à l'air d'être ca que je veux faire moi ^^ Alors elle est ou cette spritelist ? C'est quoi l'OAM xD)

Voilà j'arrête merci d'avance, je vous embeterai plus après ca normalement ^_^

MIKEGBA
16/09/2006, 00h34
(Psst, MikeGBA, ca à l'air d'être ca que je veux faire moi ^^ Alors elle est ou cette spritelist ? C'est quoi l'OAM xD)

Voilà j'arrête merci d'avance, je vous embeterai plus après ca normalement ^_^


la spritelist, c'est justement l'oam !

En gros, sur gba ou ds, c'est une zone de 1 ko qui commence à l'adresse 0x700000 sur gba ( ds je crois que c'est la meme adresse ).

C'est dans cette zone de 1 ko ou sont stoqués séquentiellement les infos d'affichages de tes 128 sprites dispo .

Pour chaque sprites, tu as 4 attributs de 16 bits chacun, ou tu as les infos de coordonées x et y d'affichage du sprite, le numéro de tile du sprite, la taille du sprite, etc....
Cette liste est normalement rafraichie à chaque vbl, et le moteur d'affichage décortique cette oam ( object attribut memory ) pour afficher tous tes joilis petits sprites dans la frama suivante.

voili voila !

Mollusk
16/09/2006, 00h42
Ben il y a une raison toute simlpe qui fait que la fonction n'est pas dispo dans PAlib : il faut effectivement mémoriser la position du sprite quand on le sort de l'écran... Donc il faudrait, pour PAlib, avoir un tableau qui mémorise la position de tous les sprites... En toute logique, le développeur est sensé l'avoir fait lui-meme, puisque c'est lui qui indique à PAlib où placer les sprites, donc dans cette optique le tableau ferait double emploi. Pour économiser de la mémoire, j'ai donc préféré ne pas le mettre et ne pas utiliser la fonction...

La technique de la frame vide est un peu lourde parce qu'elle requiert de recopier l'image en mémoire. Si tu veux sortir 60 sprites d'un coup, ca fait beaucoup je trouve pour l'effet voulu... Autant sortir de l'écran, plus rapide, ou alors mettre à un numero de Gfx vide, sans rien avoir à copier.
Quand à effacer par l'OAM, j'ai utilisé ca dans Musk avec une gestion dynamique des sprites, ca marche d'enfer :)

thoduv
16/09/2006, 00h47
Récréer tout l'Oam à chaque frame à partir d'un moteur de sprites> C'est d'ailleurs la technique qu'utilisent les jeux commerciaux. Je viens de m'y essayer sur un petit projet, et effectivement c'est terriblement flexible !

Mollusk
16/09/2006, 00h51
Apres ca dépend des jeux, mais pour un shoot'em up ca s'appliquait particulièrement bien. A chaque tour, pour chaque tir/ennemi en jeu, je faisais un PA_CreateSpriteFromGfx, donc je recréais le sprite en OAM sans remettre les images en Vram (tout était pré-chargé), un petit compteur NSprites++, et apres on finit par un for (i = NSprites; i < 128) PA_SetSpriteX(0, i, 256), et hop, tout le reste est dehors :)

edit : tout ca pour dire qu'on peut meme faire ce système flexible à partir du système 'rigide' (simple copie DMA) de PAlib sans toucher au code de la lib... Donc comme quoi c'est pas dur ^^

SanoGP
16/09/2006, 15h35
Merci bien pour vos réponses, je pense que je vais adopter ce système de réécriture de l'OAM à chaque frame :)

Ce que je cherche à avoir, en gros, c'est une fonction "bitblt" qui puisse me dessiner la frame que je veux (j'aime bien avoir mon propre système d'anim ^^) d'une image à la position où je veux,et que rien ne soit dessiné si je n'appelle pas cette fonction.
Encore une fois, si quelqu'un a des conseils à me donner ou des explications sur la meilleure facon de s'y prendre, je suis preneur à 100% ^_^

thoduv >> Je ne sais pas trop ce qu'est ton projet donc ca me gêne un peu de te demander ca, mais serais-tu d'accord pour me filer tout ou partie de ton code qui utilise directement l'OAM stp ?

Encore une fois merci à tous :)

Brunni
16/09/2006, 15h41
BitBlt ça c'est en software seulement (ou avec un GPU 3D) et la DS n'est pas très puissante donc tu vas t'embêter avec du soft...
En mode normal il faut gérer tes sprites comme d'hab (donc les 128 sont là et tu places simplement ceux que tu n'utilises pas en dehors de l'écran) ou alors comme tu l'as dit, tu remplis ton OAM dynamiquement (en gros ton BitBlt créerait un nouveau sprite dans la liste, aux positions spécifiées et en utilisant le n° d'image que tu lui as passée) ;)

thoduv
16/09/2006, 15h45
Merci bien pour vos réponses, je pense que je vais adopter ce système de réécriture de l'OAM à chaque frame :)

Ce que je cherche à avoir, en gros, c'est une fonction "bitblt" qui puisse me dessiner la frame que je veux (j'aime bien avoir mon propre système d'anim ^^) d'une image à la position où je veux,et que rien ne soit dessiné si je n'appelle pas cette fonction.
Encore une fois, si quelqu'un a des conseils à me donner ou des explications sur la meilleure facon de s'y prendre, je suis preneur à 100% ^_^

thoduv >> Je ne sais pas trop ce qu'est ton projet donc ca me gêne un peu de te demander ca, mais serais-tu d'accord pour me filer tout ou partie de ton code qui utilise directement l'OAM stp ?

Encore une fois merci à tous :)
Si l'anglais ne te fait pas peur, je te conseille de consulter des bonnes documentations, comme :
Tonc: http://user.chem.tue.nl/jakvijn/tonc/toc.htm
Gbatek: http://nocash.emubase.de/gbatek.htm

La gestion des sprites (objs) est séparée en deux: la partie graphique, qui utilise la VRAM, c'est là que tu place les graphismes de tes sprites, et la partie "gestion", l'OAM qui s'occupe de créer et d'afficher un sprite en fonction de la position, de la priorité (etc etc) et du numéro de graphisme dans la VRAM que tu lui as donné.

Si tu veux faire ton propre système, il faudra que tu utilise un mode bitmap, ou bien un bg bitmap.

SanoGP
16/09/2006, 15h52
Ouah, si j'avais su que vous étiez aussi rapide par ici, j'aurai rafraichit la page direct après avoir posté ;)

Donc génial, merci une ènième fois pour ces réponses rapides, je pense que je vais m'en tenir donc à ce système ^^ Si j'ai bien compris, je peux utiliser les creategfx de la PALib pour tout loader en VRAM, puis me concoter un petit système de sprite qui remplira l'OAM pour afficher ca comme il l'entend ^_^

Une dernière chose que j'ai besoin de savoir avant d'entamer la lecture des docs très complètes que m'a conseillé thoduv, l'OAM me permet-t-il de choisir la partie de l'image désignée qui sera affichée ?

Muryoh
16/09/2006, 16h03
Sano : Ta finalement laissé tomber la Zodiac pour la DS ? :)

Brunni
16/09/2006, 16h21
Hé non, ça aussi c'est soit du soft soit de la 3D ;)
Par contre il te permet de choisir un n° de tile. En gros tes sprites sont composés de tiles, c'est-à-dire de petites images de 8x8 qui sont placées à la suite pour créer une grande image. Style un sprite de 16x16 qui aurait pour tile de base '3' serait dessiné ainsi:
3 4
5 6
Où chaque numéro est donc une image de 8x8, dans l'ordre dans la VRAM. Donc si tu as un spritesheet, tu peux la copier entièrement en VRAM par exemple, et les différentes images seraient placées verticalement:
0 1
2 3
4 5
6 7
Et ensuite tu peux par exemple dessiner le sprite de 16x16 du dessus en choisissant '0' comme tile de base, ou le sprite du dessous en choisissant '4'. Tu peux également écrire un système qui copie dynamiquement les tiles en VRAM, en gros pour le sprite du dessus on aurait écrit uniquement les tiles 3 à 6 en VRAM (au prochain endroit libre) et le sprite aurait utilisé celles-ci ^^
[Edit] Ha, ex codeur zodiac, maintenant je comprends pourquoi ;)

SanoGP
16/09/2006, 16h47
Muryoh >> Meuh non, je m'ouvre simplement à d'autres horizons ;)

Brunni >> Ah bin c'est parfait, je comprend mieux maintenant les limitations de taille :) Je suppose que j'ai simplement à utiliser un updategfx de PALib pour remplacer les données du sprite concerné par les tiles de la frame suivante en VRAM ^_^

Au fait, je viens de remarquer dans la doc de thoduv : si le 8ème bit de l'attr0 est à 1, le sprite est affiché, à 0 il est caché. Peut-être quelqu'un de plus compétent que moi pourrait écrire une petite macro pour cacher et afficher le sprite ?

(et c'est vrai que la Zod et la GP sont de vrais petits PC, ca fait bizarre d'utiliser le hard pour coder xD)

Mollusk
16/09/2006, 16h52
Le 8ème bit correspond en fait à la rotation. 1 pour rotation, 0 pour pas de rotation. Un sprite mis en doublesize sans rotation ne s'affiche pas, c'était une méthode sur gba il me semble pou cacher les sprites

SanoGP
16/09/2006, 16h58
Ah mince, la doc était pourtant claire là-dessus :( Peut-être était-ce différent pour la GBA ? Ils mettent :

bits 8-9:
* 00. Normal rendering.
* 01. Sprite is an affine sprite, using affine matrix specified by attr1{9-D}
* 10. Disables rendering (hides the sprite)

Je trouve con qu'ils n'aient pas prévu un bit pour éviter de dessiner le sprite sans le sortir de l'OAM :(

EDIT: Oups désolé je suis dans le mauvais sens, on part de la droite, donc il s'agit du bit numéro 9, donc le dixième et non le huitième. Est-ce qu'il pourrait aussi avoir cette fonction sur DS ?

Mollusk
16/09/2006, 17h18
Ben c'est marqué ca :
When Rotation/Scaling used (Attribute 0, bit 8 set):
9 Double-Size Flag (0=Normal, 1=Double)
When Rotation/Scaling not used (Attribute 0, bit 8 cleared):
9 OBJ Disable (0=Normal, 1=Not displayed)
Donc disabled, oui, si pas de rotation

thoduv
16/09/2006, 17h21
l'OAM me permet-t-il de choisir la partie de l'image désignée qui sera affichée ?
Non, c'est d'ailleurs inutile car la taille des sprites n'est jamais très conséquente (16*16, 32*32, rarement plus).

SanoGP
16/09/2006, 17h25
Ué mais je m'étais gourré, je n'avais pas réalisé que le bit de gauche était le bit 9 en fait. J'ai un peu regardé, la macro pour mettre le bit 9 à 0 donnerait ca :

(EDIT: j'ai remis la macro post suivant, j'avais fait une erreur)

Ma DS est malheureusement restée à Grenoble, je suis chez mes parents pour quelques temps, si quelqu'un veut bien tester cette macro, ca prend peu de temps et on ne sait jamais ;)

SanoGP
16/09/2006, 17h39
Heu désolé en fait la doc dit qu'il faut mettre ce bit à 1 pour faire disparaitre le sprite, donc la macro donnerait plutôt ca (j'ai rajouté celle pour le faire réapparaître) :

#define PA_SetSpriteHide(screen, sprite) PA_obj[screen][sprite].atr0=(PA_obj[screen][sprite].atr0+512)
#define PA_SetSpriteDrawn(screen, sprite) PA_obj[screen][sprite].atr0=(PA_obj[screen][sprite].atr0&65023)

(je ne suis pas sur de moi, mes compétences en binaires sont quasi-inexistantes ^^)

SanoGP
16/09/2006, 18h29
Bon bin je viens de tester sur DeSmuME en incluant les macros dans l'exemple "PlatformGame" et ca me semble marcher parfaitement, je peux faire apparaître ou disparaître le sprite à volonté ^_^

Je suppose qu'elles demandent à être améliorées (genre le +512 qui doit pouvoir être fait plus rapidement, ou une vérification de si le sprite n'est pas déjà caché ou affiché), mais si vous voulez vous en servir aucun problème :)

Brunni
16/09/2006, 18h37
Pour améliorer la lecture, tu peux faire comme ça (pas testé):
#define PA_SetSpriteHide(screen, sprite) (PA_obj[screen][sprite].atr0 |= 1 << 9)
#define PA_SetSpriteDrawn(screen, sprite) (PA_obj[screen][sprite].atr0 &= ~(1 << 9))

Mollusk
16/09/2006, 18h42
Euh, tu as testé sur des sprites en rotation ?

Brunni
16/09/2006, 18h44
Ben dans ce cas ça ne marche pas c'est sûr :(
La seule technique valable dans ces cas (du moins sur GBA, vu que je dév pas sur DS) c'est de les mettre en 8x8 et de déplacer en dehors de l'écran ^^

SanoGP
16/09/2006, 18h54
Brunni >> Merci, ta syntaxe marche nickel :)

Mollusk >> Ah non du tout désolé, mais ces macros me suffisent amplement je n'utilise que très peu de sprite en rotation ^_^

Muryoh
16/09/2006, 18h55
les mettre en dehors, restera la meilleur solution dans tout les cas, rotation ou pas.

Muryoh
16/09/2006, 18h58
hs: sano, tu ne traine plus sur irc ?

SanoGP
16/09/2006, 19h00
Je trouve pratique de ne pas avoir à mettre les sprites dehors perso ^^
(Nope, je n'y vais plus depuis un bout de temps :) Heu, c'est qui ? xD)

SanoGP
17/09/2006, 17h37
Je suis en train de penser, il suffit de mettre le bit de rotation à 0 lui-aussi au moment de cacher le sprite, puis de le remettre à 1 quand on le réaffiche non ?
(Comme je suppose que ca ne vide pas les "propriétés" de la rotation dans l'autre atribute ?)

Brunni
17/09/2006, 17h53
Ca suffit effectivement, mais c'est con parce qu'il faut te rappeler ensuite pour lesquels tu dois la réactiver.

SanoGP
17/09/2006, 18h39
Oki, merci :) (pour moi c'est bon vu que mon moteur de sprite saura, lui, si le sprite est en rotation ou non ^_^)