MFF

    Minecraft Forge France
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes
    • Forge Events
      • Automatique
      • Foncé
      • Clair
    • S'inscrire
    • Se connecter

    Ajouter plusieurs textures à un bloc (avec ou sans metadata)

    Planifier Épinglé Verrouillé Déplacé Les blocs
    1.7.x
    14 Messages 4 Publieurs 9.0k Vues 3 Watching
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • robin4002R Hors-ligne
      robin4002 Moddeurs confirmés Rédacteurs Administrateurs
      dernière édition par robin4002

      youtubeCe tutoriel est également disponible en vidéo.

      Sommaire

      • Introduction
      • Pré-requis
      • Code
        • Sur un bloc simple
        • Sur un bloc avec métadata
      • Bonus
      • Résultat
      • En vidéo
      • Crédits

      Introduction

      Dans ce tutoriel nous allons voir comment créer un bloc avec plusieurs textures, comme la tnt, l’herbe, etc. Les blocs directionnels ne seront pas traités dans ce tutoriel.

      La façon dont minecraft gère les faces des blocs est plutôt simple. En fonction de la face, le nombre “side” sera différent.

      • 0 pour le bas
      • 1 pour le haut
      • 2 pour le nord
      • 3 pour le sud
      • 4 pour l’est
      • 5 pour l’ouest
        Petit schéma récapitulatif :
        schéma face bloc

      Pré-requis

      • Créer un bloc basique
      • Créer un bloc avec des metadatas

      Code

      Sur un bloc simple :

      La première chose à faire est de supprimer la fonction .setTextureName au niveau de l’initialisation de votre bloc dans la classe principale. Elle ne servira plus.
      Maintenant changement de classe, tout le reste se fera dans la classe de votre bloc.

      Nous allons commencer par déclarer deux objets du type IIcon, dans mon cas je vais les nommer “bottom” et “top” (bas et haut) :

      private IIcon top, bottom
      

      (cette ligne se place avant le constructeur).
      Ensuite je vais ajouter en-dessous du constructeur la méthode pour enregistrer les icônes :

          public void registerBlockIcons(IIconRegister iiconRegister)
          {
              this.blockIcon = iiconRegister.registerIcon(ModTutoriel.MODID + ":red");
              this.top = iiconRegister.registerIcon(ModTutoriel.MODID + ":yellow");
              this.bottom = iiconRegister.registerIcon(ModTutoriel.MODID + ":orange");
          }
      

      La méthode registerBlockIcons sert donc à enregistrer les icônes. this.blockIcon est l’icône par défaut d’un bloc, il n’a pas besoin d’être déclaré puisqu’il l’est déjà dans la classe mère Block.java.
      ModTutoriel.MODID + “:red” correspond à “modtutoriel:red” puis que le String MODID de ma classe principale vaut “modtutoriel”. Ceci :

          public void registerBlockIcons(IIconRegister iiconRegister)
          {
              this.blockIcon = iiconRegister.registerIcon("modtutoriel:red");
              this.top = iiconRegister.registerIcon("modtutoriel:yellow");
              this.bottom = iiconRegister.registerIcon("modtutoriel:orange");
          }
      

      Revient au même.
      Le système des textures est le même qu’avec la fonction .setTextureName, il faut mettre modid:nom_de_la_texture et la texture devra être :
      <dossier de forge>/src/main/resources/assets/modid/textures/blocks/nom_de_la_texture.png

      Ensuite il faut ajouter la fonction getIcon :

          public IIcon getIcon(int side, int metadata)
          {
              return this.blockIcon;
          }
      

      Pour l’instant dans tout les cas, il utilisera la texture blockIcon. Nous allons donc ajouter des conditions pour changer ça. Comme dit l’introduction, 0 correspond au dessous, et 1 au dessus. Donc ma fonction doit ressembler à ça :

          public IIcon getIcon(int side, int metadata)
          {
              if(side == 0)
              {
                  return this.bottom;
              }
              else if(side == 1)
              {
                  return this.top;
              }
              return this.blockIcon;
          }
      

      Et voila !
      Les accolades n’étant pas obligatoire lorsqu’il y a qu’une seule instruction, ceci fonctionne aussi :

          public IIcon getIcon(int side, int metadata)
          {
              if(side == 0)
                  return this.bottom;
              else if(side == 1)
                  return this.top;
              return this.blockIcon;
          }
      

      Sur un bloc avec métadata :

      Tout se fera dans la classe du bloc. Allez donc dans cette classe et commencez par retirer tout ce qui concerne les textures (le tableau d’IIcon, le contenu dans la fonction registerBlockIcons et le contenu de la fonction getIcon). Nous allons voir deux méthodes. Dans la première méthode, nous allons appliquer une seule texture à un bloc, deux textures à deux autres blocs et trois textures aux derniers blocs (il y a quatre blocs en metadata dans cette exemple). Dans la deuxième méthode nous allons utiliser des tableaux à deux dimensions pour appliquer trois textures aux quatre blocs.

      Première méthode :

      Nous allons devoir déclarer chaque icône une par une. Donc plus vous allez avoir de textures différentes, plus la ligne va être longue :

          public IIcon block1, block1Top, block2, block3, block3Top, block3Bottom, block4, block4TopBottom;
      

      Dans cette exemple, le premier bloc aura donc deux textures, une en haut, et une autre pour tous les autres côtés, le second bloc n’aura qu’une seule texture, le troisième bloc aura une texture pour le bas, une autre pour le haut, et une dernière pour les quatre côtés, et pour finir le quatrième bloc aura une texture pour en haut et en bas, et une autre pour les quatre côtés.

      Maintenant il faut enregistrer toutes ces icônes. Voila à quoi ressemble la fonction registerBlockIcons après modification :

          public void registerBlockIcons(IIconRegister iconRegister)
          {
              this.block1 = iconRegister.registerIcon(ModTutoriel.MODID + ":block1");
              this.block1Top = iconRegister.registerIcon(ModTutoriel.MODID + ":red");
              this.block2 = iconRegister.registerIcon(ModTutoriel.MODID + ":yellow");
              this.block3 = iconRegister.registerIcon(ModTutoriel.MODID + ":orange");
              this.block3Top = iconRegister.registerIcon(ModTutoriel.MODID + ":green");
              this.block3Bottom = iconRegister.registerIcon(ModTutoriel.MODID + ":dark_green");
              this.block4 = iconRegister.registerIcon(ModTutoriel.MODID + ":dark_blue");
              this.block3TopBottom = iconRegister.registerIcon(ModTutoriel.MODID + ":blue");
          }
      

      Je ne vais pas réexpliquer la fonction à nouveau, vous devriez la connaître maintenant, si ce n’est pas le cas remontez juste au dessus dans le cas du bloc sans metadata, elle y est expliquée.

      Ensuite il faut compléter la fonction getIcon, il faut donc mettre des conditions en fonction du side et du metadata. Il est aussi possible de passer un switch, je vais montrer les deux et expliquer en commentaire :

          public IIcon getIcon(int side, int metadata)
          {
              switch(metadata)
              {
              case 0: // Metadata 0 donc bloc 1.
                  if(side == 1) // Si le côté est 1, donc en haut,
                  {
                      return this.block1Top; // on utilise la texture du haut.
                  }
                  return this.block1; // Dans tous les autres cas, on utilise la texture bloc1.
              case 1: // Metadata 1, donc bloc 2.
                  return this.block2; // On utilise la texture bloc2 dans tous les cas.
              case 2: // Metadata 2, donc bloc 3.
                  if(side == 0) // Si le côté est 0, donc en bas
                  {
                      return this.block3Bottom; // on utilise la texture du bas.
                  }
                  else if(side == 1) // Sinon, si le côté est 1, donc en haut
                  {
                      return this.block3Top; // on utilise la texture du haut.
                  }
                  return this.block3; // Sinon pour les 4 autres côtés on utilise la texture bloc3
              case 3: // Metadata 3, donc bloc 4.
                  if(side == 0 || side == 1) // Si le côté est 0 ou 1, donc en bas ou en haut,
                  {
                      return this.block4TopBottom; // on utilise la texture bloc4TopBottom pour le haut et le bas.
                  }
                  return this.block4; // Sinon on utilise la texture bloc4.
              default: // Pour tous les autres metadata,
                  return this.block1; // on met la texture bloc1, mais vous pouvez mettre une autre texture, de toute façon ce cas ne devrait jamais arriver en temps normal.
          }
      

      Deuxième méthode :

      Commencez par déclarer un tableau à deux dimensions :

      private IIcon[][] icons = new IIcon[subBlock.length][3];
      

      La première dimension est aussi longue que mon nombre de métadata. La deuxième est aussi longue que le nombre de textures différentes par bloc. Comme dit plus haut, je vais mettre 3 textures différentes (bas, haut, et côtés) dans cet exemple, si vous voulez mettre 2 textures différentes, il faut mettre 2, sinon vous en voulez 4, il faut mettre 4, etc …

      Ensuite nous allons enregistrer toutes les icônes du tableau :

          public void registerBlockIcons(IIconRegister iconRegister)
          {
              for(int i = 0; i < subBlock.length; i++)
              {
                  for(int j = 0; j < 3; j++)
                  {
                      this.icons[i][j] = iconRegister.registerIcon(ModTutoriel.MODID + ":" + subBlock[i] + "_" + j);
                  }
              }
          }
      

      Il faut utiliser deux boucles for. Les icônes vont prendre le nom suivant :
      modtutoriel:block1_0 (la texture sera : forge/src/main/resources/assets/modtutoriel/textures/blocks/block1_0.png)
      modtutoriel:block1_1 (la texture sera : forge/src/main/resources/assets/modtutoriel/textures/blocks/block1_1.png)
      modtutoriel:block1_2 (la texture sera : forge/src/main/resources/assets/modtutoriel/textures/blocks/block1_2.png)
      modtutoriel:block2_0 (la texture sera : forge/src/main/resources/assets/modtutoriel/textures/blocks/block2_0.png)
      etc …

      Pour finir, il faut compléter la fonction getIcon :

          public IIcon getIcon(int side, int metadata)
          {
              if(side > 2)
              {
                  side = 2;
              }
              return metadata >= 0 && metadata < subBlock.length ? this.icons[metadata][side] : this.icons[0][0];
          }
      

      Si le side est supérieur à 2, dans ce cas il vaut 2, donc dans le cas où le côté sera 3, 4 ou 5, il prendre la valeur 2, et donc la même texture que le côté 2.
      La condition ternaire à la fin sert à éviter un OutOfBoundException, comme dans le tutoriel sur les blocs avec metadata.

      Dans le cas où on aura voulu appliquer la même texture en haut et en bas, puis une autres textures sur le reste du bloc, la deuxième dimension du tableau n’aurait dû faire que 2, dans la fonction registerBlockIcons il aurait fallut mettre 2 à la place de 3 dans la deuxième boucle for, et la fonction getIcon aurait ressemblé à ça :

          public IIcon getIcon(int side, int metadata)
          {
              if(side == 0 || side == 1) // le side est égale à 0 ou 1
              {
                  return metadata >= 0 && metadata < subBlock.length ? this.icons[metadata][0] /** on utilise l'icône 0 **/ : this.icons[0][0];
              }
              return metadata >= 0 && metadata < subBlock.length ? this.icons[metadata][1] /** sinon on utilise l'icône 1 **/ : this.icons[0][0];
          }
      

      Bonus

      J’ai vu pas mal de demande pour faire un bloc invisible au joueur en survie mais visible par ceux en créative. Comme cela entre dans les blocs multi-texture, je vais montrer ici comment le faire. Vous avez besoin de deux icônes, une pour la texture visible, et une pour la texture invisible. Pour créer une texture invisible, il suffit d’ajouter une couche alpha à votre texture et de transformer le blanc en alpha (je montre comment le faire avec gimp à 50 minutes et 30 secondes de la vidéo).

      Déclarez donc l’icône pour la texture invisible :

          private IIcon crea;
      

      Puis enregistrez vos deux icônes :

          public void registerBlockIcons(IIconRegister iiconRegister)
          {
              this.blockIcon = iiconRegister.registerIcon(ModTutoriel.MODID + ":inv");
              this.crea = iiconRegister.registerIcon(ModTutoriel.MODID + ":yellow");
          }
      

      Et ensuite, voici la fonction getIcon :

          @SideOnly(Side.CLIENT) // Pour être sur que la fonction n'est pas lu en serveur car on fait appelle à FMLClientHandler
          public IIcon getIcon(int side, int metadata)
          {
              if(FMLClientHandler.instance().getClientPlayerEntity().capabilities.isCreativeMode) // Vérifie que le joueur est en créatif
              {
                  return this.crea;
              }
              return this.blockIcon;
          }
      

      On pourrait très bien passer par FMLClientHandler.instance().getWorldClient().provider.dimensionId pour faire changer la texture en fonction de la dimension où même en fonction du joueur avec FMLClientHandler.instance().getClientPlayerEntity().getCommandSenderName() !

      Comme une des textures est transparente, ajoutez aussi ces trois fonctions, sinon le bloc va avoir un effet vision des cavernes.

          @SideOnly(Side.CLIENT)
          public int getRenderBlockPass()
          {
              return 1;
          }
      
          public boolean renderAsNormalBlock()
          {
              return false;
          }
      
          public boolean isOpaqueCube()
          {
              return false;
          }
      

      Et voila ! Pour ceux qui en auraient besoin, voici un aperçu de la classe après modification.

      Résultat

      Voir le commit sur github
      Le commit sur github montre clairement où ont été placés les fichiers, ainsi que ce qui a été ajouté et retiré dans le fichier.

      En vidéo

      Youtube Video

      Crédits

      Rédaction :

      • robin4002

      Correction :

      • gagoi

      Creative Commons
      Ce tutoriel de Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

      retourRetour vers le sommaire des tutoriels

      1 réponse Dernière réponse Répondre Citer 0
      • D Hors-ligne
        dayvrespect
        dernière édition par

        j’ai un petit problème avec mes textures quand je lance le jeu, il va chercher le .png dans minecraft:textures/blocks/MISSING_ICON_BLOCK_165_crafter.png! j’ai fait les même code présent dans le tuto pour un block simple! j’ai essayer plusieurs manip mais sa ne veut pas changer

        1 réponse Dernière réponse Répondre Citer 0
        • robin4002R Hors-ligne
          robin4002 Moddeurs confirmés Rédacteurs Administrateurs
          dernière édition par

          Envoie tes codes.

          1 réponse Dernière réponse Répondre Citer 0
          • D Hors-ligne
            dayvrespect
            dernière édition par

            code class principal

            
            package fr.dayvrespect.common;
            
            import net.minecraft.block.Block;
            import net.minecraft.block.material.Material;
            import net.minecraft.creativetab.CreativeTabs;
            import cpw.mods.fml.common.Mod;
            import cpw.mods.fml.common.Mod.EventHandler;
            import cpw.mods.fml.common.Mod.Instance;
            import cpw.mods.fml.common.SidedProxy;
            import cpw.mods.fml.common.event.FMLInitializationEvent;
            import cpw.mods.fml.common.event.FMLPostInitializationEvent;
            import cpw.mods.fml.common.event.FMLPreInitializationEvent;
            import cpw.mods.fml.common.registry.GameRegistry;
            import fr.dayvrespect.proxy.CommonProxy;
            
            @Mod(modid = ModCrafter.MODID, name = "Mod Crafter", version = "1.0.0")
            public class ModCrafter
            {
            public static final String MODID = "modcrafter";
            
            @Instance(MODID)
            public static ModCrafter instance;
            
            @SidedProxy(clientSide = "fr.dayvrespect.proxy.ClientProxy", serverSide = "fr.dayvrespect.proxy.CommonProxy")
            public static CommonProxy proxy;
            
            public static Block blockCraft;
            
            @EventHandler
            public void preInit(FMLPreInitializationEvent event)
            {
            blockCraft = new BlockCraft().setBlockName("crafter").setCreativeTab(CreativeTabs.tabMaterials);
            GameRegistry.registerBlock(blockCraft, "block_craft");
            }
            
            @EventHandler
            public void init(FMLInitializationEvent event)
            {
            proxy.registerRender();
            }
            
            @EventHandler
            public void postInit(FMLPostInitializationEvent event)
            {
            
            }
            }
            
            

            code class block

            
            package fr.dayvrespect.common;
            
            import net.minecraft.block.Block;
            import net.minecraft.block.material.Material;
            import net.minecraft.client.renderer.texture.IIconRegister;
            import net.minecraft.entity.EntityLivingBase;
            import net.minecraft.item.ItemStack;
            import net.minecraft.util.IIcon;
            import net.minecraft.util.MathHelper;
            import net.minecraft.world.World;
            
            public class BlockCraft extends Block
            {
            
            public IIcon top, bottom, front;
            
            protected BlockCraft()
            {
            super(Material.wood);
            }
            
            private void registerIcon(IIconRegister iiconRegister)
            {
            this.blockIcon = iiconRegister.registerIcon(ModCrafter.MODID + ":log");
            this.front = iiconRegister.registerIcon(ModCrafter.MODID + ":log_front");
            this.top = iiconRegister.registerIcon(ModCrafter.MODID + ":log_top");
            this.bottom = iiconRegister.registerIcon(ModCrafter.MODID + ":log_bottom");
            
            }
            
            public IIcon getIcon(int side, int metadata)
            {
            return side == 1 ? this.top : (side == 0 ? this.bottom : (metadata == 2 && side == 2 ? this.front : (metadata == 3 && side == 5 ? this.front : (metadata == 0 && side == 3 ? this.front : (metadata == 1 && side == 4 ? this.front : this.blockIcon)))));
            }
            // ancien get Icon
            // public IIcon getIcon(int side, int metadata)
            // {
            // if(side == 0)
            // {
            // return this.bottom;
            // }
            // if(side == 1)
            // {
            // return this.top;
            // }
            // else if(side == 3)
            // {
            // return this.front;
            // }
            // return this.blockIcon;
            // }
            
            public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase living, ItemStack stack)
            {
            int direction = MathHelper.floor_double((double)(living.rotationYaw * 4.0F / 360.0F) + 2.5D) & 3;
            world.setBlockMetadataWithNotify(x, y, z, direction, 2);
            }
            
            }
            
            
            1 réponse Dernière réponse Répondre Citer 0
            • robin4002R Hors-ligne
              robin4002 Moddeurs confirmés Rédacteurs Administrateurs
              dernière édition par

              Dommage, le problème se joue à un s prêt :
              private void registerBlockIcon(IIconRegister iiconRegister)
              devrait être :
              public void registerBlockIcons(IIconRegister iiconRegister)
              (je sais pas pourquoi tu as mit private, normalement ça devrait être public).

              1 réponse Dernière réponse Répondre Citer 0
              • D Hors-ligne
                dayvrespect
                dernière édition par

                merci j’arrête pas de modifier pour savoir se qui déconné sur le code XD pour un S sniff et pour le private il ma semblé l’avoir vu quelque part XD!
                serait t’il possible quand tu aura un moment de dispo de m’accorder une discutions sur ts3 ou skype pour des info plus approfondis dans le cadre du mod que je souhaiterais créer et me dire si ce que je pense est possible ou non par rapport a ton expérience !

                en tous cas tu gere coté code je l’aurais jamais trouver je pense, merci.

                1 réponse Dernière réponse Répondre Citer 0
                • robin4002R Hors-ligne
                  robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                  dernière édition par

                  De rien ^^
                  Passe sur le ts de mff, j’y suis presque tout le temps.

                  1 réponse Dernière réponse Répondre Citer 0
                  • OptimusZeGamingO Hors-ligne
                    OptimusZeGaming
                    dernière édition par

                    Bonjour

                    je viens de faire le même code du block sur mon nouveaux furance mais il arrête pas de chercher la texture MISSING_ICON_BLOCK_166_furnace.png

                    j’ai chercher d’ou peux venir l’erreur mais je ne voit pas

                    Merci de votre aide

                    1 réponse Dernière réponse Répondre Citer 0
                    • robin4002R Hors-ligne
                      robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                      dernière édition par

                      Ça c’est signe d’un problème avec la fonction registerBlockIcons

                      OptimusZeGamingO 1 réponse Dernière réponse Répondre Citer 0
                      • OptimusZeGamingO Hors-ligne
                        OptimusZeGaming @robin4002
                        dernière édition par robin4002

                        @robin4002 voici la classe de mon furnace

                        import com.mod.Factory.Factory;
                        import com.mod.Factory.Reference;
                        
                        import net.minecraft.block.Block;
                        import net.minecraft.block.BlockContainer;
                        import net.minecraft.block.material.Material;
                        import net.minecraft.client.renderer.texture.IIconRegister;
                        import net.minecraft.util.IIcon;
                        
                        
                        
                        public class Machine_Furnace
                        {
                        	private IIcon haut, bas, blockIcon;
                        	
                        	public Machine_Furnace(Material rock) 
                        	{
                        		
                        	}
                        
                        	public void registerBlockIcons(IIconRegister iiconRegister)
                        	{
                        		this.blockIcon = iiconRegister.registerIcon(Reference.MOD_ID + ":machines/Machine_Furnace/furnace_front_off");
                                this.haut = iiconRegister.registerIcon(Reference.MOD_ID + ":machines/Machine_Furnace/furnace_top");
                                this.bas = iiconRegister.registerIcon(Reference.MOD_ID + ":machines/Machine_Furnace/furnace_top");
                        	}
                        	
                        	public IIcon getIcon(int side, int metadata)
                            {
                                if(side == 0)
                                {
                                    return this.bas;
                                }
                                else if(side == 1)
                                {
                                    return this.haut;
                                }
                                return this.blockIcon;
                            }
                        }
                        
                        1 réponse Dernière réponse Répondre Citer 0
                        • robin4002R Hors-ligne
                          robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                          dernière édition par

                          Ta classe n’extends pas Block, ce n’est pas normal

                          OptimusZeGamingO 1 réponse Dernière réponse Répondre Citer 0
                          • OptimusZeGamingO Hors-ligne
                            OptimusZeGaming @robin4002
                            dernière édition par

                            @robin4002 Super merci c’etait bien sa le probleme, j’ai oublier de le remettre comme j’ai refait la classe j’ai oublier de l’extends

                            Et autre question qui na rien a voir
                            est-ce que il a un tuto pour creer un four en 1.7.10 ?

                            1 réponse Dernière réponse Répondre Citer 0
                            • robin4002R Hors-ligne
                              robin4002 Moddeurs confirmés Rédacteurs Administrateurs
                              dernière édition par

                              Il ne me semble pas, le seul tutoriel four du forum c’est pour la 1.8.9 ou plus récent.

                              1 réponse Dernière réponse Répondre Citer 0
                              • JustAnDevJ Hors-ligne
                                JustAnDev
                                dernière édition par

                                et vraiment c’est juste 2-3 choses qui changent
                                1 la tile sur le tuto on n’enumere pas le

                                hasTileEntity 
                                

                                il n’existe pas en 1.8 et plus
                                2 tout les x y z ont été remplacé par les blocks pos en 1.8 +
                                le reste j’ai pas regardé

                                s

                                1 réponse Dernière réponse Répondre Citer 0
                                • robin4002R robin4002 a fait référence à ce sujet sur
                                • robin4002R robin4002 a fait référence à ce sujet sur
                                • robin4002R robin4002 a fait référence à ce sujet sur
                                • 1 / 1
                                • Premier message
                                  Dernier message
                                Design by Woryk
                                ContactMentions Légales

                                MINECRAFT FORGE FRANCE © 2024

                                Powered by NodeBB