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 » Effet miroir de Sprite
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Effet miroir de Sprite

Posté le 07/12/2015 20:28

Salut à tous,

Existes t-il une fonction qui permet de faire un effet miroir sur les sprites en C++ ?


Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 07/12/2015 22:18 | #


Je ne pense pas, il faut la faire à la main. Si t'es sur du 8x8 ou 16x16 c'est relativement simple. Et une symétrie horizonatle est plus simple qu'une symétrie verticale.
De souvenir, dans les sources de Gravity Duck Pierottl l'a fait
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 25/12/2015 19:43 | #


Après 4 jours sans internet chez mes grands parents, j'annonce que j ai réussi à créer une fonction qui retourne un poiteur qui pointe sur l image ayant subi un effet miroir d une image mis en argument avec ces dimentions. Je poste le code demain.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 25/12/2015 22:03 | #


Mais c'est pas ça qu'il faut faire.

Il faut appliquer le miroir à l'affichage ! Pour un symétrie par une droite horizontale, c'est juste trivial dans la formule (remplacer y + ligne courante par y + taille - ligne courante - 1), il n'y a que pour la verticale ou il faut - diantre ! - inverser l'ordre des bits à un certain point.
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 26/12/2015 10:26 | #


Eux excuse moi lorsque je disait miroir horizontale, je parle en réalité d une symétrie avec un axe verticale. Comme l on ce voit dans un miroir.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Dark storm En ligne Labélisateur Points: 11631 Défis: 176 Message

Citer : Posté le 26/12/2015 11:12 | #


À ce moment le miroir est vertical

Et Lephe a raison, à moins que ton jeu nécessite énormément de rapidité, faut appeler la fonction à l'affichage. Ce qui fait que ta fonction reverse_sprite(char* bmp) devrait utiliser un pointeur statique pour réutiliser la même mémoire à chaque fois. Attention aux fuite de mémoire, y'a rien de pire sur une calto.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 26/12/2015 13:30 | #


Voici le code:


[purple]unsigned char[/purple] * reversesprite( const [purple]unsigned char[/purple] * spritein,int br_x , [purple]int[/purple] br_y)
{

[b][blue]if[/blue][/b](spritein == NULL)return NULL;

    [purple]int[/purple] taille, lx , decalage;

    [purple]unsigned char[/purple] transit;
    [purple]unsigned char[/purple] out;

    [purple]unsigned char[/purple] * spriteout;

        decalage = size_x % 8;

    [b][blue]if[/blue][/b](decalage == [maroon]0[/maroon])lx = size_x/8;[green]//Calcul la taille en octets de l'image.[/green]
    [b][blue]else[/blue][/b] lx = (size_x/8) + 1;

    taille = lx * size_y;

    this[b]->[/b]spriteout = (unsigned char*) malloc(sizeof(unsigned char) * taille);[green]//Alloue l'espace mémoire, ne pas oublier de libérer à la fin du programme.[/green]

        [b][blue]for[/blue][/b](int i = [maroon]0[/maroon] ; i < size_y ; i++)
          [b][blue]for[/blue][/b](int a = [maroon]0[/maroon]; a < lx; a++)
            spriteout[i * lx + a] = spritein[ (i +1)*lx - (a+1)]; [green]//Copie l[gray]'image en inversant l'[/gray]ordre des octets de chaques lignes.[/green]

        [b][blue]for[/blue][/b](int i = [maroon]0[/maroon]; i < taille ; i++) [green]//Applique l'effet miroir aux octets.[/green]
         {
             transit = spriteout[i ];
             out = [maroon]0[/maroon]x0;
             [b][blue]if[/blue][/b]((transit & 0x80) != [maroon]0[/maroon]x0)  out = out | 0x01;
             [b][blue]if[/blue][/b]((transit & 0x40) != [maroon]0[/maroon]x0)  out = out | 0x02;
             [b][blue]if[/blue][/b]((transit & 0x20) != [maroon]0[/maroon]x0)  out = out | 0x04;
             [b][blue]if[/blue][/b]((transit & 0x10) != [maroon]0[/maroon]x0)  out = out | 0x08;
             [b][blue]if[/blue][/b]((transit & 0x08) != [maroon]0[/maroon]x0)   out = out | 0x10;
             [b][blue]if[/blue][/b]((transit & 0x04) != [maroon]0[/maroon]x0)   out = out | 0x20;
             [b][blue]if[/blue][/b]((transit & 0x02) != [maroon]0[/maroon]x0)   out = out | 0x40;
             [b][blue]if[/blue][/b]((transit & 0x01) != [maroon]0[/maroon]x0)   out = out | 0x80;

             spriteout[i ] = out;

         }

    [b][blue]if[/blue][/b](decalage != [maroon]0[/maroon]) [green]//Replace l'image correctement et enlève le surplus de pixel noir qui se trouve à la fin.[/green]
    {
         [b][blue]for[/blue][/b](int i = [maroon]0[/maroon] ; i < size_y ; i++)
            [b][blue]for[/blue][/b](int a = [maroon]0[/maroon]; a < lx; a++)
            {
                transit = ((unsigned char)spriteout[i * lx + a] >> ( decalage));

                spriteout[i * lx + a] = ((unsigned char)spriteout[i * lx + a] << ( 8 - decalage));

                [b][blue]if[/blue][/b](a != [maroon]0[/maroon])spriteout[i * lx + a - 1] = spriteout[i * lx + a - 1] | transit;
            }

    }

[b][blue]return[/blue][/b] spriteout; [green]//Retourne le pointeur.[/green]

}



It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Dark storm En ligne Labélisateur Points: 11631 Défis: 176 Message

Citer : Posté le 26/12/2015 18:43 | #


Ah oui, t'es en C++
Je me demandais comment ça pouvait compiler en déclarant des variables après des conditions. x)

Enfin, c'est pas mal de mettre des espaces de temps en temps, mais faut garder une certaine logique

Pour finir, t'as pas compris le coup de l'allocation dynamique là… Si tu appelle MLib dessus, du type : ML_bmp_or(reversesprite(bitmap, 16, 16), 16, 16, 42, 42);, t'es sur d'avoir une fuite. Un truc pas forcément propre mais fonctionnel puisque tu utilise le pointeur directement est de le libérer à la fin de la fonction. Comme ça tu transmet bien l'adresse en mémoire mais tu indique au CPU qu'il peut la réutiliser par la suite. Enfin, attend l'avis de Lephe pour trouver une solution plus propre quand même.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 26/12/2015 18:52 | #


Dark storm a écrit :
Enfin, c'est pas mal de mettre des espaces de temps en temps, mais faut garder une certaine logique

Je plussoie. Comment veux-tu coder un moteur de jeu complet avec une indentation foireuse ?

Dark storm a écrit :
Pour finir, t'as pas compris le coup de l'allocation dynamique là… Si tu appelle MLib dessus, du type : ML_bmp_or(reversesprite(bitmap, 16, 16), 16, 16, 42, 42);, t'es sur d'avoir une fuite.

Je crois que le but de cette fonction est de stocker le bitmap renversé dans une variable justement pour éviter de le re-calculer à chaque fois, ce qui est plutôt lent...

Dark Storm a écrit :
Un truc pas forcément propre mais fonctionnel puisque tu utilise le pointeur directement est de le libérer à la fin de la fonction. Comme ça tu transmet bien l'adresse en mémoire mais tu indique au CPU qu'il peut la réutiliser par la suite.

NON. Les interruptions, ça existe, tu sais ? Ne fais jamais ça. C'est bien enregistré ?
Une solution propre, c'est d'écrire un wrapper basique du type draw_reversed_sprite() qui se charge de récupérer le pointeur, appeler ML avec les bons arguments et le libérer ensuite. En plus ça allègerait la syntaxe.
Ou alors conserver le pointeur tout le long de l'exécution de la fonction et ne le libérer qu'à la fin.

Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11631 Défis: 176 Message

Citer : Posté le 26/12/2015 18:59 | #


Les interruptions modifient l'espace de RAM alloué aux programmes ? Je croyais qu'elle n'interagissaient qu'avec un espace bien précis. Quoi que, à bien y réfléchir, ça ne reste qu'un timer.

Concernant la lenteur, pour un truc de type Gravity Duck, osef un peu, ça va assez vite. Sinon, pour garder la structure actuelle du code, le mieux reste de faire un buffer de taille fixe au début du programme. Mais c'est pas très souple donc oui, la fonction de Lephe reste la meilleure solution.
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 26/12/2015 19:01 | #


Dark storm a écrit :
Les interruptions modifient l'espace de RAM alloué aux programmes ? Je croyais qu'elle n'interagissaient qu'avec un espace bien précis. Quoi que, à bien y réfléchir, ça ne reste qu'un timer.

Tu ne sais pas ce qu'une interruption fait. Ne fais aucune présupposition ou tu fonces dans le mur, un jour ou l'autre.
Dans le cas particulier de gint, jamais aucune mémoire n'est allouée dynamiquement, mais tu sais que sous x86 les appels systèmes utilisent des interruptions ? Alors oui, ceux-là ne tombent pas n'importe quand mais il faut quand même se méfier.

Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Fife86 Hors ligne Membre Points: 830 Défis: 0 Message

Citer : Posté le 27/12/2015 10:04 | #


J ai en réalité créé une class sprite qui contient un pointeur sur l image normal ainsi qu un poiteur initialisé a Null dans le constructeur pour stocker l image renversée. Elle contient aussi une fonction pour créer l inverse de l image. Dans le destructeur de la class je libère le pointeur si il n est pas Null.
It's Show Time !!!
Mes Jeux :
- Street Fighter : Pour les accrocs du free-fight.
- Kirby's DreamLand : Gobe , Gobe , Gobe !!!
- L'invasion Seanchans : Détruit la flotte ennemis a bord du "Danseur des vagues".


< Le recoin du C-Engine >
Kirafi Hors ligne Membre Points: 2180 Défis: 10 Message

Citer : Posté le 12/03/2016 10:50 | #


Bon je reprend le topic .

Voilà j'ai ça pour des sprites 8, 16, 24, 32 de large (oh serait-ce mes bateaux de SeaRush ? ).
Je ne l'ai pas testé parce que justement ce n'est pas fini , mais en théorie ça fonctionne.
        //Ici se débrouiller pour créer un tableau de char pour contenir le reverse_sprite

        for (line = 0; line < 16; line++)    //Les sprites font tous 16 pixel de haut
        {
            for (value = 0; value < size; value++)    //Si 8 pixel de large, size = 1, si 16 de large, size = 2, etc...
            {
                for (i = 0; i < 8; ++i)    //Parcoure les 8 bits de la valeur
                {
                    reverse_sprite[line*size+value] += ((1 << i) & sprite[size-value-1]) << 8-i;    //Inverse les bits de cette manière : abcdefgh -> hgfedcba, tout en inversant les valeurs si le sprite est plus long que 8 pixels comme ça (line de 24 pixel, soit 3 valeurs): A, B, C -> C, B, A
                }
            }
        }

        //Renvoyer le pointeur reverse_sprite ou qqch comme ça pour pouvoir l'afficher avec MonochromeLib
        //Ou carrément trouver un moyen de l'afficher avec ML sans le renvoyer à la manière de "ML_bmp_or_rotate, zoom" j'ai vu que c'était comme ça mais je sais pas trop comment fonctionne le dessin dans la vram...

iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)

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 107 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