Créer un item zoom


  • Administrateurs

    Sommaire

    Introduction

    Bonjour ! Dans ce tutoriel nous allons apprendre à créer un item qui aura pour effet de créer un zoom avant lors d'un clic droit.
    Ce tutoriel ne montre en aucun cas comment modifier le FOV de Minecraft. Nous allons changer le zoom directement (comme avec Optifine, lorsqu'on appuie sur la touche "ALT GR")

    Pré-requis

    Code

    Classe principale :

    Une fois la base de votre mod ainsi que votre item avec sa propre classe créés à l'aide des pré-requis ci-dessus, ajoutez cette variable statique dans votre classe principale :

    public static boolean zoom;
    

    Dès à présent, vous n'avez plus rien à faire dans votre classe principale.

    Classe de l'Item :

    Pour activer notre boolean, nous allons tout d'abord appeler une fonction connue de tout moddeurs Minecraftien :

        public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn)
        {
            return itemStackIn;
        }
    

    Nous avons, pour le moment, uniquement appelé la fonction qui est appelée lors d'un clic droit.
    Maintenant nous allons ajouter le bout de code qui va permettre de switcher le boolean.

    Au dessus de :

    return itemStackIn;
    

    Ajoutez cette condition très importante :

    if(worldIn.isRemote)
    {
    }
    

    :interrogation: Pourquoi est-elle si importante ? :interrogation:
    ❗ La réponse ici :

    Inutile de vous expliquer le fonctionnement client/serveur de Minecraft, ce n'est pas l'objectif de ce tuto ! 😉

    Bien, une fois la condition ajoutée, nous allons, ENFIN, appeler notre boolean !

    Dans votre condition, ajoutez cette ligne :

    VotreClassePrincipale.zoom = !VotreClassePrincipale.zoom;
    

    Bien entendu, VotreClassePrincipale est à remplacer par le nom de votre classe principale. 🙂

    Notre petit engrenage est désormais opérationnel, votre classe devrait ressembler à ça :

    public class ItemZoomer extends Item
    {
        public ItemZoomer()
        {
            super();
        }
    
        public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn)
        {
            if(worldIn.isRemote)
            {
                VotreClassePrincipale.zoom = !VotreClassePrincipale.zoom;
            }
            return itemStackIn;
        }
    }
    

    :crayon: Le boolean se changera en true lors du clic droit de la souris, puis se mettra en false quand vous cliquerez à nouveau !

    Bien, nous avons fait le plus facile jusque-là. À présent il est temps de passer aux choses sérieuses. 😛

    Créez une classe TickClientHandlerEvent dans votre package client !

    Petit tour rapide dans votre classe principale pour enregistrer le TickClientHandlerEvent !
    Dans la méthode preInit de votre mod (tout en bas de cette dernière):

    if(event.getSide().isClient())
    {
        FMLCommonHandler.instance().bus().register(new TickClientHandlerEvent());
        MinecraftForge.EVENT_BUS.register(new TickClientHandlerEvent());
    }
    
    

    Oui, je vous conseille d'utiliser la fonction de Forge ET de FML pour l'enregistrement de l'event.
    On sait jamais... :dodgy:

    Classe Tick Client Handler Event :

    Pour commencer, nous allons avoir besoin de l'event RenderGameOverlayEvent !
    Nous allons donc créer une méthode comme ceci :

    @SubscribeEvent
    public void onRenderExperienceBar(RenderGameOverlayEvent event)
    {
    }
    

    Nommez la méthode comme vous voulez, du moment qu'il y a l'annotation @SubscribeEvent et le paramètre RenderGameOverlayEvent !

    Ensuite, nous allons ajouter une condition où l'on va appeler notre fameux boolean de notre classe principale que voici :

    if(VotreClassePrincipale.zoom)
    {
    } else {
    }
    

    Comme vous vous en doutez, il faut bien un "else" pour rétablir le zoom par défaut ! :3
    Dans cette même condition, nous allons ajouter une AUTRE condition, qui permettra de vérifier si le joueur est en First Person Mode.

    Donc dans votre condition, ajoutez ceci :

    if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)
    {
    }
    

    Pas de panique ! Si vous vous sentez perdu, voici ce à quoi devrait ressembler votre classe TickClientHandler :

    public class TickClientHandlerEvent 
    {
        @SubscribeEvent
        public void onRenderExperienceBar(RenderGameOverlayEvent event)
        {
            if(VotreClassePrincipale.zoom)
            {
                if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)
                {
    
                }
            } else {
    
            }
        }
    }
    

    Maintenant, il est temps de remplir ces conditions par la fonction de zoom ! 🙂

    Créez une nouvelle fonction en dessous de la méthode qui a le @SubscribeEvent, comme ceci :

    public static void zoom(double zoomValue)
    {
    }
    

    Comme vous auriez pu vous en douter, il manque un petit quelque chose à cette fonction pour qu'elle puisse fonctionner comme il se doit. 😉

    ObfuscationReflectionHelper.setPrivateValue(EntityRenderer.class, Minecraft.getMinecraft().entityRenderer, zoomValue, "cameraZoom", "field_78503_V");
    

    À mettre dans votre fonction zoom(double zoomValue) !

    Eeeeet oui ! La fameuse variable cameraZoom de la classe EntityRenderer est private... Donc, qu'on ne peut pas l'avoir directement en faisant

    Minecraft.getMinecraft().entityRenderer.cameraZoom = zoomValue;
    

    Obligé d'utiliser la réflection Java. 🙂

    Nous allons donc maintenant appeler cette fonction dans la sous-condition, et dans le else, comme il s'en suit :

        if(VotreClassePrincipale.zoom)
        {
            if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)
            {
                zoom(6.0D); //c'est déjà pas mal, mais libre à vous de jongler sur la valeur
            }
        } else {
            zoom(1.0D); //par défaut, le zoom de la caméra est à 1.0D
        }
    

    Votre classe doit ressembler à ça au final :

    public class TickClientHandlerEvent 
    {
        @SubscribeEvent
        public void onRenderExperienceBar(RenderGameOverlayEvent event)
        {
            if(VotreClassePrincipale.zoom)
            {
                if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)
                {
                    zoom(6.0D); //c'est déjà pas mal, mais libre à vous de jongler sur la valeur
                }
            } else {
                zoom(1.0D); //par défaut, le zoom de la caméra est à 1.0D
            }
        }
    
        public static void zoom(double zoomValue)
        {
            ObfuscationReflectionHelper.setPrivateValue(EntityRenderer.class, Minecraft.getMinecraft().entityRenderer, zoomValue, "cameraZoom", "field_78503_V");
        }
    }
    

    Voilà, c'est tout pour ce tutoriel !

    Résultat

    En Gif, rien que pour vous ! 🙂

    Crédits

    Rédaction :

    Correction :

    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



  • Y a une erreur je crois dans la classe finale TickClientHandlerEvent , tu met

    minecraft.entityRenderer
    

    au lieu de

    Minecraft.getMinecraft()
    

  • Administrateurs

    Corrigé ! 🙂



  • Marche parfaitement en 1.7.10 également 🙂

    Yeah , ce tuto est génial j'ai même édité le code pour avoir un Overlay voici le code pour les intéressé 🙂

    JE SUIS EN 1.7.10 ( Je ne sais pas si ca marche en 1.8 )

    public static final ResourceLocation zoomOverlay = new ResourceLocation("dinocraft", "textures/blur/zoom.png");
    
    public static void renderTextureOverlay(ResourceLocation s, float f)
       {
        Minecraft minecraft = FMLClientHandler.instance().getClient();
           ScaledResolution scaledresolution = new ScaledResolution(minecraft, minecraft.displayWidth, minecraft.displayHeight);
           int i = scaledresolution.getScaledWidth();
           int j = scaledresolution.getScaledHeight();
           GL11.glEnable(GL11.GL_BLEND);
           GL11.glDisable(GL11.GL_DEPTH_TEST);
           GL11.glDepthMask(false);
           GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
           GL11.glColor4f(1.0F, 1.0F, 1.0F, f);
           GL11.glDisable(GL11.GL_ALPHA_TEST);
           minecraft.getTextureManager().bindTexture(s);
           Tessellator tessellator = Tessellator.instance;
           tessellator.startDrawingQuads();
           tessellator.addVertexWithUV(0.0D, j, -90D, 0.0D, 1.0D);
           tessellator.addVertexWithUV(i, j, -90D, 1.0D, 1.0D);
           tessellator.addVertexWithUV(i, 0.0D, -90D, 1.0D, 0.0D);
           tessellator.addVertexWithUV(0.0D, 0.0D, -90D, 0.0D, 0.0D);
           tessellator.draw();
           GL11.glDepthMask(true);
           GL11.glEnable(GL11.GL_DEPTH_TEST);
           GL11.glEnable(GL11.GL_ALPHA_TEST);
           GL11.glColor4f(1.0F, 1.0F, 1.0F, f);
       }
    
    @SubscribeEvent
    public void onRenderExperienceBar(RenderGameOverlayEvent event)
    {
     if(ItemRegister.zoom)
     {
     if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)
      {
     zoom(6.0D); //c'est déjà pas mal, mais libre à vous de jongler sur la valeur
     if(ItemRegister.zoom && Minecraft.getMinecraft().gameSettings.thirdPersonView == 0 && Minecraft.getMinecraft().currentScreen == null)
     {
      renderTextureOverlay(zoomOverlay, 1.0F);
     }
      }
     }
     else
     {
     zoom(1.0D); //par défaut, le zoom de la caméra est à 1.0D
     }
    }
    
    public static void zoom(double zoomValue)
    {
    ObfuscationReflectionHelper.setPrivateValue(EntityRenderer.class, Minecraft.getMinecraft().entityRenderer, zoomValue, "cameraZoom", "field_78503_V");
    }
    }
    

  • Administrateurs

    Nope ! En 1.8 il y a le Tessellator qui devient WorldRenderer (enfin, il faut appeler WorldRenderer VIA tessellator)

    like that :

    
    Tessellator tessellator = Tessellator.getInstance();
    WorldRenderer worldrenderer = tessellator.getWorldRenderer();
    
    worldrenderer.startDrawingQuads();
    
    

    etc…



  • Salut, le code fonctionne très bien seul problème c'est que quand on quitte l'item en question dans l'inventaire, si on a pas refait de clic droit ça reste en zoom…. Comment on peut faire ?



  • C'est à dire ?



  • Il veut dire que lorsque tu fait un click droit avec l'item il zoom mais lorsque tu change le slot de l'inventaire ca reste en zoom , il voudrais savoir comment faire pour que lorsqu'on change de slot ( donc on est plus sur l'item zoom ) ca dézoom 🙂


  • Administrateurs

    @'QuantumSheep':

    Salut, le code fonctionne très bien seul problème c'est que quand on quitte l'item en question dans l'inventaire, si on a pas refait de clic droit ça reste en zoom…. Comment on peut faire ?

    Pour enlever le zoom lors du switch d'item, il suffit d'ajouter une condition :

    
    ItemStack itemstack = Minecraft.getMinecraft().thePlayer.getCurrentEquippedItem();
     if(itemstack != null && itemstack.getItem() == VotreClassePrincipale.votreItem && Minecraft.getMinecraft().gameSettings.thirdPersonView == 0)
     {
     zoom(6.0D); //c'est déjà pas mal, mais libre à vous de jongler sur la valeur
     }
     }else{
     zoom(1.0D); //par défaut, le zoom de la caméra est à 1.0D
     }
    
    

  • Correcteurs

    Hum, j'ai dû mal comprendre pour la condition mais switch d'item n'enlève pas le zoom.

    Edit: Oui, mal compris, une erreur de condition


  • Correcteurs

    J'avais commencé par ce tuto pour mes snipers.

    Au final le mieux pour moi a été de passer par les tag nbt de mes armes.
    Sinon le zoom est mal pris en compte je trouve: Afficher un GUI si le zoom est activé devient un réel problème si le joueur drop l'arme (oui c'est une éventualité)

    Donc faîtes bien attention aux utilisations de vos items avant d'opter pour l'une ou l'autre solution



  • Bonsoir, à tous.

    J'ai suivi le tuto et j'ai plusieurs problèmes  😢

    J'ai enregistré l'item dans ma classe principal comme tout les autres items, donc j'ai mis la texture et quand je met la texture j'obtient un crash :c
    Et lorsque la texture n'est pas correct ou n'est pas mise pas de crash de plus, j'ai voulut faire que lorsqu'on switch d'item sa remet la vue normal mais sa ne marche pas non plus je suis en 1.7.10 :c



  • Yo, faudrait ton code et tes logs stp de maniere a mieux cerné le probleme



  • Classe Principal : https://pastebin.com/1kdV9Cv7
    Classe de l'item : https://pastebin.com/1QEZbGDV
    TickClientHandlerEvent : https://pastebin.com/D92X8epY
    L'erreur a l'ajout de la texture dans la classe principal : https://pastebin.com/yrvejYAh