Les blocs multi-textures


  • Administrateurs

    Pour l'instant vous savez juste comment créer un bloc avec une seule et même texture sur toutes les faces. Dans ce tutoriel nous allons donc voir comment utiliser des textures différentes sur chaque face.

    Multi-textures sur un bloc basique

    Commençons par le cas d'un bloc basique, car cela va être plus compliqué avec les metadata.
    Dans votre classe principale, enlevez le code qui gère la texture (setTextureName("modtutoriel:BlockTutorial")) ce qui donne :

        BlockTutorial = new BlockTutorial(BlockTutorialID).setHardness(1.0F)
        .setResistance(5.0F).setStepSound(Block.soundStoneFootstep).setUnlocalizedName("BlockTutorial");
    

    Maintenant retour dans la classe du bloc, où nous allons déclarer deux icônes :

        private Icon icontop, iconbottom;
    

    (pour ceux qui ne savent toujours pas, les déclarations se font après l'ouverture d'accolade de la classe)

    Après le constructeur ajoutez :

        public void registerIcons(IconRegister iconRegister)
        {
            blockIcon = iconRegister.registerIcon("modtutoriel:BlockTutorial");
            icontop = iconRegister.registerIcon("modtutoriel:BlockTutorial_Top");
            iconbottom = iconRegister.registerIcon("modtutoriel:BlockTutorial_Bottom");
        }
    
        @SideOnly(Side.CLIENT)
        public Icon getIcon(int side, int metadata)
        {
            return side == 0 ? iconbottom : side == 1 ? icontop : blockIcon;
        }
    

    Dans le void registerIcons j'enregistre les 3 icônes : celui par défaut d'un bloc, et les deux autres que j'ai créé. Pour les textures vous devrez maintenant avoir l'habitude, si vous ne savez toujours pas où les placer retournez voir le tutoriel sur les blocs basiques.
    Ensuite, dans le getIcon c'est une condition ternaire, si le side est 0, il utilise l'icône bottom (= bas en français, prenez aussi l'habitude de faire vos codes en anglais), si le side est 1 il utilise l'icône top (haut) et sinon il utilise l'icône blockIcon (celui par défaut des blocs)

    Résultat :
    Bloc avec multiple texture
    Voir sur github

    Voici un petit schéma des faces :
    Minecraft schéma des faces d'un bloc (ce même schéma est disponible en anglais sur le wiki de forge)

    Multiple-textures avec les metadata (6 faces différentes sur tout les blocs)

    Les multi-textures en metadata vont être un peu plus compliquées, surtout si vous voulez que certains blocs aient plusieurs textures et d'autres non. Le cas le plus simple est de mettre plusieurs textures à tous les blocs, c'est ce que nous allons voir en premier temps.

    Afin de ne pas avoir plus de 50 icônes dans notre classe, nous allons utiliser tableau à deux dimensions :

        private Icon[] IconArray;
    

    devient :

        private Icon[][] IconArray;
    

    Ajoutez aussi un nouveau String :

        private String[] sideType = new String[]{"bottom", "top", "north", "south", "west", "east"};
    

    Vous avez sûrement compris qu'il s'agit des 6 faces possibles, dans l'ordre. En effet, sideType[0] correspond à bottom, donc en dessous, comme sur le schéma, et j'ai fais de même pour les 5 autres côtés.

    Maintenant nous allons modifier l'iconregister :

        public void registerIcons(IconRegister iconregister)
        {
            IconArray = new Icon[type.length][6]; //6 car il y 6 side
            for(int i = 0; i < type.length; i++) //la boucle pour les metadata
            {
                for(int j = 0; j < 6; j++) //la boucle pour les côtés
                {
                    IconArray[i][j] = iconregister.registerIcon("modtutoriel:" + type[i] + "_" + sideType[j]);
                }
            }
        }
    

    Tout est expliqué en commentaire. Ainsi vos textures seront /assets/modid/textures/blocks/type_side.png. Donc :
    /assets/modid/textures/blocks/block1_bottom.png, /assets/modid/textures/blocks/block1_top.png, etc …
    Il ne reste plus qu'à modifier le getIcon :

        @SideOnly(Side.CLIENT)
        public Icon getIcon(int side, int metadata)
        {
            return metadata < type.length && metadata >= 0 ? IconArray[metadata][side] : IconArray[0][0];
        }
    

    Si le metadata est invalide il utilisera la texture du bloc de metadata 0 avec le côté bas.

    Voir sur github

    Multiple-textures avec les metadata (3 faces différentes sur tout les blocs (bas, haut, les 4 côtés))

    Le principe va être exactement le même qu'au dessus. Faites exactement la même chose. Ensuite, nous allons modifier quelques trucs :
    Comme nous voulons la même textures sur les 4 côtés, les 4 directions sont inutiles en peuvent être remplacé par "side" qui va globaliser les 4 côtés :

        private String[] sideType = new String[]{"bottom", "top", "north", "south", "west", "east"};
    

    devient :

        private String[] sideType = new String[]{"bottom", "top", "side"};
    

    Nous avons donc que 3 textures par bloc, dans l'iconregister remplacez les 6 par 3 :

        public void registerIcons(IconRegister iconregister)
        {
            IconArray = new Icon[type.length][3]; //3 texture par bloc cette fois (bas, haut, les 4 autres côtés)
            for(int i = 0; i < type.length; i++) //la boucle pour les metadata
            {
                for(int j = 0; j < 3; j++) //la boucle pour les côtés
                {
                    IconArray*[j] = iconregister.registerIcon("ModTutoriel:" + type* + "_" + sideType[j]);
                }
            }
        }
    

    Et pour finir, modification du getIcon :

        @SideOnly(Side.CLIENT)
        public Icon getIcon(int side, int metadata)
        {
            if(side > 2) side = 2;
            return metadata < type.length && metadata >= 0 ? IconArray[metadata][side] : IconArray[0][0];
        }
    

    Si le side est supérieur à 2, il est égal à 2; En gros, la face sud, la face est, et la face ouest utilisera aussi l'icône 2 qui est celui du nord, donc les 4 côtés auront la même texture.

    Voir sur github

    Multiple-textures avec les metadata (un peu de tout)

    Dans cette dernière partie nous allons voir comment mettre 6 textures différentes au premier bloc, 5 au deuxième, 4 au troisième, etc… jusqu’à une seule texture
    Cette partie vous servira donc d'exemple pour faire quelque chose de différent pour chacun de vos blocs (dans les deux autre parties nous avons vu comment appliquer les multiples-textures à tous les blocs et non un seul comme ici)

    En revanche, pour ça nous allons abandonner les boucles for, le code va donc être très long.

    Pour commencer, nous allons créer un icône par bloc, avec un tableau de la taille nécessaire pour stocker les différentes textures.

        private Icon[] Icon1 = new Icon[6];
        private Icon[] Icon2 = new Icon[5];
        private Icon[] Icon3 = new Icon[4];
        private Icon[] Icon4 = new Icon[3];
        private Icon[] Icon5 = new Icon[2];
        private Icon[] Icon6 = new Icon[2];
        private Icon Icon7, Icon8;
    

    Ça fait déjà plus long.

    Ensuite, le fonction registerIcons :

        public void registerIcons(IconRegister iconregister)
        {
            Icon1[0] = iconregister.registerIcon("modtutoriel:block1_bottom");
            Icon1[1] = iconregister.registerIcon("modtutoriel:block1_top");
            Icon1[2] = iconregister.registerIcon("modtutoriel:block1_north");
            Icon1[3] = iconregister.registerIcon("modtutoriel:block1_south");
            Icon1[4] = iconregister.registerIcon("modtutoriel:block1_west");
            Icon1[5] = iconregister.registerIcon("modtutoriel:block1_east");
    
            Icon2[0] = iconregister.registerIcon("modtutoriel:block2");
            Icon2[1] = iconregister.registerIcon("modtutoriel:block2_north");
            Icon2[2] = iconregister.registerIcon("modtutoriel:block2_south");
            Icon2[3] = iconregister.registerIcon("modtutoriel:block2_west");
            Icon2[4] = iconregister.registerIcon("modtutoriel:block2_east");
    
            Icon3[0] = iconregister.registerIcon("modtutoriel:block3_top");
            Icon3[1] = iconregister.registerIcon("modtutoriel:block3_bottom");
            Icon3[2] = iconregister.registerIcon("modtutoriel:block3_north");
            Icon3[3] = iconregister.registerIcon("modtutoriel:block3");
    
            Icon4[0] = iconregister.registerIcon("modtutoriel:block4_top");
            Icon4[1] = iconregister.registerIcon("modtutoriel:block4_bottom");
            Icon4[2] = iconregister.registerIcon("modtutoriel:block4");
    
            Icon5[0] = iconregister.registerIcon("modtutoriel:block5_bottom_top");
            Icon5[1] = iconregister.registerIcon("modtutoriel:block5");
    
            Icon6[0] = iconregister.registerIcon("modtutoriel:block6_top");
            Icon6[1] = iconregister.registerIcon("modtutoriel:block6");
    
            Icon7 = iconregister.registerIcon("modtutoriel:block7");
            Icon8 = iconregister.registerIcon("modtutoriel:block8");
        }
    

    C'est quand on voit ce genre de code qu'on comprend à quoi servait les boucles for dans les deux autres techniques 😛
    Pour le getIcon, nous allons utiliser un switch :

        @SideOnly(Side.CLIENT)
        public Icon getIcon(int side, int metadata)
        {
            switch(metadata)
            {
                case 0:
                    return Icon1[side];
                case 1:
                    return side > 1 ? Icon2[side - 1] : Icon2[0];
                case 2:
                    return side < 4 ? Icon3[side] : Icon3[3];
                case 3:
                    return side < 3 ? Icon4[side] : Icon4[2];
                case 4:
                    return side < 2 ? Icon5[0] : Icon5[1];
                case 5:
                    return side == 1 ? Icon6[0] : Icon6[1];
                case 6:
                    return Icon7;
                case 7:
                    return Icon8;
                default:
                    return blockIcon;
            }
        }
    

    Si vous tomber sur un OutOfBound, vérifiez que les side ne dépassent pas la taille de vos tableaux. Dans l'ordre on a

    • metadata 0 : le plus simple, comme il a 6 texture j'utilise simplement Icon1[side]
    • metadata 1 : si le side est supérieur à 1, j'utilise la texture Icon2[side - 1], donc pour le nord, (2) il va utilise l'icône Icon2[1] qui correspond bien à ma texture du nord. Même chose pour les 3 autres directions. Pour le haut et le bas, il utilise la texture Icon2[0]
    • metadata 2 : le côté est et ouest auront la même texture que le sud.
    • metadata 3 : le haut et le bas utiliserons leurs propres textures, les 4 côtés auront la même
    • metadata 4 : le haut et le bas utilisent la même texture (Icon6[0]), et les côtés Icon6[1]
    • metadata 5 : le haut utilise la texture Icon6[0], et le reste la texture Icon6[1]
    • metadata 6 : une seul texture pour tout le bloc
    • metadata 7 : une seul texture pour tout le bloc

    Voir sur github

    Voila, fin du tutoriel sur les multi-textures, si vous avez des questions ou des remarques postez-les à la suite, ce tutoriel est plutôt compliqué pour quelqu'un qui n'est pas à l'aise avec les conditions ternaire. D'ailleurs sachez que vous pouvez aussi utiliser des conditions "normales".



  • Salut,

    J'ai suivi le tutoriel à la lettre et comparé les fichiers sur github avec les miens et, malgré que ce soit la même chose (excepté les noms qui changent), les textures de mon bloc n'apparaissent pas (couleurs rose/noir), les messages d'erreur :

    2013-07-26 11:53:48 [SEVERE] [Minecraft-Client] Using missing texture, unable to load: modtutoriel:textures/blocks/FutEnBois_Bottom.png
    2013-07-26 11:53:48 [SEVERE] [Minecraft-Client] Using missing texture, unable to load: modtutoriel:textures/blocks/FutEnBois.png
    2013-07-26 11:53:48 [SEVERE] [Minecraft-Client] Using missing texture, unable to load: modtutoriel:textures/blocks/FutEnBois_Top.png

    Pourtant mes textures sont bien dans le bon dossier. Une idée? Je sens que c'est un truc tout bête T_T

    Merci d'avance.


  • Administrateurs

    Tu as oublié de changer le modid(modtutoriel) par le tien.



  • @'Minecraftienne':

    Salut,

    J'ai suivi le tutoriel à la lettre et comparé les fichiers sur github avec les miens et, malgré que ce soit la même chose (excepté les noms qui changent), les textures de mon bloc n'apparaissent pas (couleurs rose/noir), les messages d'erreur :

    2013-07-26 11:53:48 [SEVERE] [Minecraft-Client] Using missing texture, unable to load: modtutoriel:textures/blocks/FutEnBois_Bottom.png
    2013-07-26 11:53:48 [SEVERE] [Minecraft-Client] Using missing texture, unable to load: modtutoriel:textures/blocks/FutEnBois.png
    2013-07-26 11:53:48 [SEVERE] [Minecraft-Client] Using missing texture, unable to load: modtutoriel:textures/blocks/FutEnBois_Top.png

    Pourtant mes textures sont bien dans le bon dossier. Une idée? Je sens que c'est un truc tout bête T_T

    Merci d'avance.

    @'Superloup10':

    Tu as oublié de changer le modid(modtutoriel) par le tien.

    Oui ! De plus, cette erreur est récurrente, même lorsque les textures ne manquent pas il me sort ça… Sauf que quand je me connecte ingame ça me met les textures ^^



  • Ah oui c'est bon 😑 Merci.


  • Administrateurs

    @'EclipseOnFire':

    même lorsque les textures ne manquent pas il me sort ça… Sauf que quand je me connecte ingame ça me met les textures ^^

    Mets à jour forge, les premiers build était buggué au niveau des textures, le 799 et supérieurs fonctionnent correctement.


  • Administrateurs

    J'ai avancé le tutoriel pour les metadata, il me reste encore le cas ou les certains blocs ont plusieurs textures et d'autres non, ça va être long.


  • Administrateurs

    Tutoriel enfin terminé !



  • Super tuto 🙂


Log in to reply