Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » Tableaux de tableaux de pointeurs
Mb88 Hors ligne Rédacteur Points: 1213 Défis: 3 Message

Tableaux de tableaux de pointeurs

Posté le 30/05/2023 19:55

Dans mon jeu j'ai des tableaux de pointeurs que j'ai mis dans un autre tableau pour pouvoir changer de skin (garçon ou fille) et d'animation (sauter ou courir).
Les tableaux sont définis comme ça
/* Ne vous plaignez pas, je les ai mis dans l'ordre alphabétique ... */
extern unsigned char* boy_jump;
extern unsigned char* boy_run;
extern unsigned char* girl_jump;
extern unsigned char* girl_run;

unsigned char** player_sprites[] = {
    &boy_jump,
    &boy_run,
    &girl_jump,
    &girl_run
};

extern unsigned char* alpha_boy_jump;
extern unsigned char* alpha_boy_run;
extern unsigned char* alpha_girl_jump;
extern unsigned char* alpha_girl_run;

unsigned char** player_alpha[] = {
    &alpha_boy_jump,
    &alpha_boy_run,
    &alpha_girl_jump,
    &alpha_girl_run
};

et j'y récupère une image comme ça :
(*player_alpha[game->player.skin * 2 + game->player.action])
            [game->player.anim.anim_frame]

Le truc c'est qu'à mon avis je suis en train de faire de la grosse merde avec les pointeurs mais je ne sais pas comment faire mieux.

Ps : faudrait uniquement autoriser de resize en vertical les textarea de création d'un topic.


Lephenixnoir Hors ligne Administrateur Points: 24699 Défis: 170 Message

Citer : Posté le 30/05/2023 20:02 | #


Si tu veux utiliser le sprite tu as juste besoin de connaître boy_jump, pas &boy_jump - le second n'aurait du sens que si tu voulais en plus modifier la variable boy_jump. Mais ce n'est pas le cas, tu veux juste l'utiliser. Moralement tu as donc envie de faire un tableau comme ceci :

unsigned char* player_sprites[] = {
    boy_jump,
    boy_run,
    girl_jump,
    girl_run
};

Ça ça ne marche pas parce que la valeur de boy_jump (qui est un pointeur) n'est pas connue par le compilateur et donc il ne peut pas initialiser le tableau. Mais on est d'accord que dans l'idée c'est ça.

Maintenant ce que je soupçonne c'est que tes sprites il sont en fait définis comme ça :

unsigned char boy_jump[] = { ... };

Ce qui change tout parce que dans ce cas le type c'est pas unsigned char *, c'est unsigned char [<la taille>], et c'est pas du tout le même type. En l'occurrence, contrairement à la valeur d'un pointeur à l'instant, l'adresse du tableau est elle acceptable comme initialiseur, du coup tu peux écrire :

extern unsigned char boy_jump[];
extern unsigned char boy_run[];
extern unsigned char girl_jump[];
extern unsigned char girl_run[];

unsigned char* player_sprites[] = {
    boy_jump,
    boy_run,
    girl_jump,
    girl_run
};

Et ensuite t'en servir comme ça :

unsigned char *un_sprite = player_sprites[skin * 2 + action];
draw(un_sprite);

J'ai pas compris ce que faisait le frame en plus, sans doute que du coup il y a subtilité que j'ai ratée.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Hackcell Hors ligne Maître du Puzzle Points: 1533 Défis: 11 Message

Citer : Posté le 30/05/2023 20:45 | #


au hasard l'animation à plusieur frame ?
Lephenixnoir Hors ligne Administrateur Points: 24699 Défis: 170 Message

Citer : Posté le 30/05/2023 20:47 | #


Bien sûr. Ce que je voulais dire c'est qu'à partir de sa question je n'arrive pas à inférer la disposition mémoire qu'il a choisi pour ces animations.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Mb88 Hors ligne Rédacteur Points: 1213 Défis: 3 Message

Citer : Posté le 30/05/2023 21:07 | #


Maintenant tout pointe au même endroit, bon, donc il y a encore un truc a résoudre ...
Lephenixnoir a écrit :
J'ai pas compris ce que faisait le frame en plus, sans doute que du coup il y a subtilité que j'ai ratée.

C'est parce que c'est un tableau de sprite coder qui contient plusieurs sprites, comme ça :
const unsigned char block[]={
    0x7f, 0xfe,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x80, 0x1,
    0x7f, 0xfe,
};

const unsigned char spikes[]={
    0x0, 0x0,
    0x18, 0x18,
    0x18, 0x18,
    0x18, 0x18,
    0x18, 0x18,
    0x2c, 0x2c,
    0x2c, 0x2c,
    0x2c, 0x2c,
    0x2c, 0x2c,
    0x46, 0x46,
    0x46, 0x46,
    0x46, 0x46,
    0x46, 0x46,
    0x3e, 0x3e,
    0x38, 0x38,
    0x7c, 0x7c,
};

const unsigned char allowchange[]={
    0xf, 0xf0,
    0x10, 0x8,
    0x20, 0x4,
    0x40, 0x2,
    0x80, 0x1,
    0x80, 0x1,
    0x81, 0x81,
    0x83, 0xc1,
    0x82, 0xc1,
    0x81, 0x81,
    0x80, 0x1,
    0x80, 0x1,
    0x40, 0x2,
    0x20, 0x4,
    0x10, 0x8,
    0xf, 0xf0,
};

const unsigned char* tiles[]={
    block,
    spikes,
    allowchange
};

Mb88 Hors ligne Rédacteur Points: 1213 Défis: 3 Message

Citer : Posté le 30/05/2023 21:56 | #


Du coup maintenant mes tableaux qui contiennent tout les pointeurs sont comme ça
/* Ne vous plaignez pas, je les ai mis dans l'ordre alphabétique ... */
extern unsigned char boy_jump[];
extern unsigned char boy_run[];
extern unsigned char girl_jump[];
extern unsigned char girl_run[];

unsigned char* player_sprites[] = {
    boy_jump,
    boy_run,
    girl_jump,
    girl_run
};

extern unsigned char* alpha_boy_jump[];
extern unsigned char* alpha_boy_run[];
extern unsigned char* alpha_girl_jump[];
extern unsigned char* alpha_girl_run[];

unsigned char* player_alpha[] = {
    alpha_boy_jump,
    alpha_boy_run,
    alpha_girl_jump,
    alpha_girl_run
};

Lephenixnoir Hors ligne Administrateur Points: 24699 Défis: 170 Message

Citer : Posté le 30/05/2023 22:45 | #


Dans ton message initial tu nous parles de boy_jump et player_sprites mais ton extrait de code utilise alpha_sprites. Ensuite tu nous présentes un alpha_sprites d'un type différent de player_sprites avec un alpha_boy_jump dont on pourrait penser qu'il est de même type que boy_jump sauf que non. Et tu nous justifies ça en nous montrant des sprites block, spikes et un tableau tiles dont tu ne nous montres pas comment ils sont utilisés.

On ne comprend rien à tes données, Mb, on est obligés de deviner. Prends le temps de nous montrer tout le code qui définit et utilise les sprites jusqu'à la création de player_sprites et son utilisation, tout le code qui fait pareil jusqu'à la création de alpha_sprites et son utilisation, et là on pourra te dire ce qui ne va pas.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Mb88 Hors ligne Rédacteur Points: 1213 Défis: 3 Message
Lephenixnoir Hors ligne Administrateur Points: 24699 Défis: 170 Message

Citer : Posté le 31/05/2023 00:09 | #


Du coup il y a un niveau de pointeurs en plus que ce que j'avais compris ; on a bien des choses comme

unsigned char* boy_jump[];

Note que tu dois toujours, toujours garder la cohérence entre la définition et toutes les déclarations externes. Si tu change le type entre les deux ça va péter et tu n'auras pas de warning donc c'est vraiment important de surveiller ça.

Comme précédemment, boy_jump et affiliés étant des tableaux, on peut toujours les utiliser directement comme initialiseurs (un pointeur vers le tableau est alors généré).

extern unsigned char* boy_jump[];
extern unsigned char* boy_run[];
extern unsigned char* girl_jump[];
extern unsigned char* girl_run[];

unsigned char** player_sprites[] = {
    boy_jump,
    boy_run,
    girl_jump,
    girl_run
};

Il est important de comprendre la progression des types ici. Au début, tu as une image dans le style de

const unsigned char bj_s0[]={...};

C'est un tableau de unsigned char, et quand on utilise bj_s0 comme initialiseur durant la définition de boy_jump, le tableau s'affaiblit implicitement et devient un pointeur vers le début de la séquence, ie. un unsigned char *. Des pointeurs comme ça y'en a 9 (de bj_s0 à bj_s8) et donc on les stocke dans un tableau :

const unsigned char* boy_jump[]={
    bj_s0,
    /* ... */
    bj_s8
};

Il est important de voir que dans le type de boy_jump, l'étoile c'est ce qu'il reste du [] de bj_s0 à bj_s8, et le [] on vient de le rajouter en créant un nouveau niveau de tableau.

De la même façon, quand boy_jump est utilisé comme initialiseur dans player_sprites, il s'affaiblit automatiquement en un unsigned char **, et du coup quand on écrit :

unsigned char** player_sprites[] = {
    boy_jump,
    boy_run,
    girl_jump,
    girl_run
};

La deuxième * c'est ce qu'il reste du [] de bj_s0 à bj_s8, la première * c'est ce qu'il reste du [] de boy_jump qui s'est fait affaiblir implicitement, et le [] on vient de le rajouter en créant un nouveau niveau de tableau.

Encore une fois, il est super important de ne jamais mentir entre une définition de variable et ses déclarations externes, et donc en particulier dans assets.h il faut absolument utiliser le bon type au caractère près, à savoir :

extern unsigned char** player_sprites[];
extern unsigned char** player_alpha[];

Et ça s'utilise comme tu l'imagines, comme un double tableau de sprites, ie. exactement comme tu le fais.

player_sprites[skin * 2 + action][anim_frame]

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Mb88 Hors ligne Rédacteur Points: 1213 Défis: 3 Message

Citer : Posté le 31/05/2023 13:32 | # | Fichier joint


Merci beaucoup pour l'explication très complète de comment résoudre le problème, mais ça marche toujours pas : tout pointe vers le même endroit ...

Lephenixnoir Hors ligne Administrateur Points: 24699 Défis: 170 Message

Citer : Posté le 31/05/2023 14:17 | #


Je n'ai pas ma calto sous la main pour tester mais je note que dans ton dernier commit tu as écrit

extern unsigned char** player_sprites;
extern unsigned char** player_alpha;

Ce qui n'est pas le bon type.

Tu as d'ailleurs un warning à ce sujet, mais après avoir pull je ne l'ai pas vu, il a fallu que je fasse une recompilation complète pour que player.c soit recompilé (!!). Tu as donc un énorme red flag, à savoir un système de build qui parfois mélange des anciennes versions des fichiers sans recompiler ce que tu écris. Le protocole dans ce cas c'est tu lâches tout et tu ne fais plus confiance à ton code tant que tu n'es pas sûr que le g1a que tu obtiens est bien représentatif de ce qu'il y a dans ton code C.

La raison de ce problème est assez évidente, tu as la dépendance $(BUILD)/%.o: src/% mais tu n'as rien pour prendre en compte les headers. Le faire dans make est assez compliqué, tu es libre de te lancer dedans, de toujours tout recompiler, ou de changer de système de build (CMake le fait automatiquement par exemple), mais je si peux me permettre un conseil ne reste surtout pas avec un Makefile défaillant.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Mb88 Hors ligne Rédacteur Points: 1213 Défis: 3 Message

Citer : Posté le 31/05/2023 14:34 | #


J'aime bien meson, mais je pense que c'est pas pratique avec, car il faut un fichier cross-compile, et c'est assez chiant de devoir passer un argument à chaque fois. Merci beaucoup pour l'aide, maintenant le sprite s'affiche \o/

Par contre je déteste cmake donc je pense que je corrigerai le makefile.
Lephenixnoir Hors ligne Administrateur Points: 24699 Défis: 170 Message

Citer : Posté le 31/05/2023 14:37 | #


Cool !

Mb88 a écrit :
J'aime bien meson, mais je pense que c'est pas pratique avec, car il faut un fichier cross-compile, et c'est assez chiant de devoir passer un argument à chaque fois.

Oh tu sais rien ne t'empêche de faire un Makefile où "make" ça appelle meson/ninja avec le bon argument
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 78 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd