Créer un disque musical



  • Bonjour à tous, aujourd'hui, on va créer un disque musical !
    Pour ceci, vous aurez besoin de :

    • Un fichier sounds.json (placé habilement à la racine de vos ressources de mods (assets.tutoriel). Il s'agit du même emplacement que le mcmod.info (au cas où).
    • Une classe MusicDisc
    • Une texture de disque
    • Un fichier en .ogg

    Pour commencer, voyons le JSON
    #Le fichier JSON(Le fichier JSON)
    Pour faire un fichier JSON, c'est relativement assez simple. Vous pouvez trouver assez simplement des sites Comme celui-ci vous permettant d'avoir un générateur de JSON. Mais pour les plus puristes, faisons un JSON et regardons de quoi c'est composé !

    {
        "records.tutomusique": {
            "sounds":[
                {
                    "name":"records/tutomusique",
                    "stream":true
                }
            ],
            "category":"record"
        }
    }
    

    Nous avons donc trois tables (Array si vous préférez). Le premier niveau définit tout les sons de notre sounds.json (dans ce cas records.tutomusique est un des sons).
    Chaque son est constitué d'une array lui permettant d'avoir les informations permettant de savoir quoi jouer et où le placer dans le SoundSystem (master : partout, hostile : créatures hostiles, neutral : créatures neutres, record : Jukebox).
    Chaque information à l'intérieur du son (donc en dessous de sounds) permet de savoir : L'emplacement de la musique, et le fait de streamer le son (contre le fait de précharger)

    Dans notre cas, on va donc faire un fichier musique, de la catégorie "records" (donc Jukebox, noteblock), étant situé dans records/tutomusique, et se streamant (pour éviter le lag ingame, méthode plus sûre. Oubliez le préchargement si votre son fait plus de 3 secondes).

    Si vous voulez rajouter un autre son à la suite, il suffit de mettre une virgule après l'avant-dernière parenthèse et de copier de "records.tutomusique" à cette dernière. Le dernier son n'aura pas de virgule par contre. Question de principe 😄

    Les Textures et les fichiers musicaux

    Un petit paragraphe sur les fichiers : Ils doivent être placés à la racine du mod (donc dans "src/main/resources/assets/modtutoriel") les fichiers musicaux vont dans un dossier "sound" (et dans notre petit exemple, dans un sous-dossier records), et le sounds.json reste à cette racine (à côté du mcmod.info, je le rappelle).

    La classe MusicDisc

    Que contient cette classe ? Eh bien c'est assez simple, c'est grâce à elle que l'on va pouvoir personnaliser entièrement notre disque.

    On va commencer par initialiser cette class :

    public class MusicDiscTuto extends ItemRecord {
    
    }
    

    à ce stade, votre IDE (Eclipse, Idea, Netbeans, peu importe !) devrait commencer à vous mettre un message d'erreur. Pas de panique, c'est normal !
    Il suffit de rajouter le constructeur par défaut de la superclass, ce qui va vous donner ça :

    public class MusicDiscTuto extends ]ItemRecord {
    
        protected MusicDiscTuto(String recordName) {
            super(recordName);
        }
    }
    

    Voilà, on vient de créer notre constructeur ! Il suffira au moment de créer notre objet de lui passer simplement le nom du disque.

    Je vais vous coller le texte complet de la class pour le moment et vous l'expliquer après :

    public class ]MusicDisc extends ItemRecord
    {
        private static final Map records = new ]HashMap();
    
        public final String recordName;
    
        public MusicDisc(String recordName)
        {
            super(recordName);
    
            this.recordName = recordName;
            this.maxStackSize = 1;
            setCreativeTab(Tutoriel.tutoCreativeTabs);
    
            records.put(recordName, this);
        }
    
        // La suite vient ici
    }
    

    Alors qu'avons-nous ici ? Eh bien simplement, on a une HashMap (il s'agit d'un tableau à une seule dimension dont la clé pour accéder à ce que l'on stocke est ce que l'on veut. ici, ça sert simplement à faire un listing complet de tout les disques qu'on rajoute).

    Notre Hashmap sera une Hashmap de type HashMap <String, MusicDisc>pour être précis. Dans cette hashmap, on stockera à la création d'un objet son existence pour aller la chercher plus simplement (par exemple, un records.get(nomdurecord) nous permettra de récupérer l'objet MusicDisc correspondant.
    On va créer une string recordName qui contiendra le nom du disque.
    Et enfin, le constructeur, où lors de la création d'un objet de classe MusicDisc, on :

    • enregistrera le nom du disque
    • définira la taille d'un stack (vu que c'est un disque, on n'en met qu'un seul)
    • définira dans quelle creativeTab on décide de le ranger
    • l'insèrera dans notre table HashMap regroupant tout les disques qu'on créera

    Ensuite, on va rajouter les différentes méthodes nous permettant de gérer le disque en tant qu'objet !

    
    @Override
    public void registerIcons(IIconRegister iconRegister)
    {
        itemIcon = iconRegister.registerIcon(Tutoriel.MODID + %":" + recordName + "Record");
    }
    

    Kezako ? Il s'agit tout simplement de notre fichier texture qui sera (dans notre exemple) tutomusiqueRecord.png. Il sera stocké avec les items (logique, puisque cela en est un !) si on démonte rapidement la string qu'on fournit dans le registerIcon() cela nous donnera "tuto:tutomusiqueRecord". Et on verra un peu plus tard comment gérer la description (méthode qui pourra être utilisé dans n'importe quel objet, ainsi que n'importe quel bloc par ailleurs)

    
    @Override
    public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int par7, float par8, float par9, float par10)
    {
        if (world.getBlock(x, y, z) == Blocks.jukebox && world.getBlockMetadata(x, y, z) == 0)
        {
            if (world.isRemote)
                return true;
            else
            {
                ((BlockJukebox)Blocks.jukebox).func_149926_b(world, x, y, z, itemStack);
                world.playAuxSFXAtEntity((EntityPlayer)null, 1005, x, y, z, Item.getIdFromItem(this));
                –itemStack.stackSize;
                return true;
            }
        }
        else
            return false;
    }
    
    

    Ici, c'est tout simplement ce qu'il se passe lorsqu'on fait un clic droit avec notre disque.
    Pour vous expliquer, cette fonction sera utilisée à chaque clic droit. En gros, on regarde si le bloc sur lequel on clique est un bloc de type "jukebox", et si sa metadata est de "0". Si c'est vrai, alors on vérifie si on est côté serveur ou côté client.
    Dans le cas où on est dans le côté serveur, alors on lui renvoie "true" pour lui dire qu'il y a bien eu une action.
    Côté client, on récupère le bloc activé que l'on cast (autrement dit que l'on "transforme") en BlockJukebox. Le reste du code sert tout simplement à insérer un disque dans l'inventaire du jukebox, lire le fichier son, et réduire de 1 le stack du disque (donc le retirer de la main).
    le "else return false:" à la toute fin sert tout simplement à annuler l'effet d'un clic droit sur un autre bloc. Si par exemple vous voudriez faire un clic droit sur un certain type de bloc et faire une action (comme un objet de base ma foi), il vous suffirait de le mettre ici.

    Maintenant on va gérer la description du disque (là où on va mettre l'artiste et le titre). On peut facilement copier/coller cette fonction sur n'importe quel item/block bien entendu, pour rajouter une description qu'on gèrera derrière avec notre fichier lang.

        @Override
        public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
        {
            par3List.add(this.getRecordNameLocal());
        }
    
        @Override
        public String getRecordNameLocal()
        {
            return StatCollector.translateToLocal(this.getUnlocalizedName() + ".desc");
        }
    

    Ce code c'est tout simplement ce qui permet de mettre le "sous-titre" d'un item. On lui dit tout simplement d'ajouter au paramètre 3 (la description) le résultat de la requête de getRecordNameLocal() qui, quand à elle, va chercher dans notre fichier lang (translateToLocal) la valeur contenue dans le nom de notre objet(getUnlocalizedName) avec en plus à la fin ".desc"
    Donc il va aller chercher dans item.tutomusiqueRecord.desc de notre fichier lang les différentes choses à afficher (Je ferai un tuto plus tard sur cette fonction extrêmement utile).

    Enfin, les dernières fonctions à ajouter :

        @Override
        public EnumRarity getRarity(ItemStack itemStack)
        {
            return EnumRarity.rare;
        }
    
        public static MusicDisc getRecord(String par0Str)
        {
            return (MusicDisc)records.get(par0Str);
        }
    
        @Override
        public ResourceLocation getRecordResource(String name)
        {
            return new ResourceLocation(Tutoriel.MODID, name);
        }
    

    De quoi s'agit-il ce coup-ci ? Eh bien pour getRarity, on va donner une rareté à notre item (afin de rendre le disque bleu). Pour changer la couleur en violet par exemple, il suffira de mettre EnumRarity.epic, d'autres couleurs sont dispos, il vous suffit de regarder dans le fichier EnumRarity pour toutes les avoir.
    getRecord est un getter (sous-entendu une fonction nous permettant de faire une action sur une variable locale pas forcément ouverte) et nous permettant de récupérer le MusicDisc selon son nom directement (par exemple : MusicDisc recupMusic = MusicDisc.getRecord("tutomusique"); nous permettrait de récupérer dans recupMusic le disque tutomusique).
    getRecordResource est la fonction qui va aller chercher dans les ressources le nom du fichier à jouer (dans notre cas "tutomusique").

    On en a terminé avec notre classe MusicDisc (et donc le passage le plus embêtant), attaquons-nous à la suite, la création de l'objet en elle-même !

    La classe principale

    Dans notre classe principale, dans le init (où à l'endroit où l'on déclare les items selon la structure de notre mod), il suffira de mettre 3 lignes :

    on va déclarer notre objet (mettez le avec les autres déclarations) :

    public static ]Item record_tuto;
    
    

    Puis on initialise notre objet avec ceci :

        record_tuto = new MusicDisc("tutomusique").setUnlocalizedName("tutomusiqueRecord");]
    

    Et enfin on enregistre notre item

    GameRegistry.registerItem(record_tuto, "tutomusiqueRecord");
    

    Et voilà, notre item est dispo ingame !

    Les fichiers de localisation

    On va maintenant ajouter notre item dans le fichier de localisation. ajoutez ces deux lignes :

    item.tutomusiqueRecord.name=Disque
    item.tutomusiqueRecord.desc=robin4002 - Hyper Tuto Remix 2015 Fever Arcade Pro
    

    La première définit le nom de l'objet (celui en gros) et le deuxième définit ce qu'il y a dans la tooltip (en l'occurence l'artiste et le titre de la chanson).

    Credits

    ShadCanard



  • Cool, c'est justement ce que je cherchais 🙂


Log in to reply