[JAVA] J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft

J'ai téléchargé le processus de production avant, mais il a été mis sous tension au moment où j'ai fini de tout donner, donc je vais le renouveler.

Environnement de développement

Le langage est Java et l'éditeur utilise IntelliJ IDEA. La version de Minecraft est la 1.13.2. Le type de plugin est spigot.

Ce que vous pouvez faire avec ce plug-in

Ce plug-in est un plug-in qui vous permet de jouer au jeu japonais à l'ancienne "Daruma-san fell" que tout le monde a probablement fait dans Minecraft.

À propos de la description et de la fonction de ce plug-in

Description de ce plug-in

«Quand le vrai Daruma-san est tombé, il y avait un rôle de démon, mais ce plug-in n'a pas de démon. Au lieu de cela, il y a un ** objectif **. "Daruma-san est tombé" qui peut être fait avec ce plug-in est que pendant que Daruma-san tombe, il va à cet objectif. «Il y a un ** tour ** dans le" Daruma-san est tombé "de ce plug-in. Dans ce plug-in, un tour est à partir du moment où vous avez fini de dire "Daruma-san est tombé" et de juger si cela fonctionne ou non jusqu'à ce que vous commenciez à dire le prochain "da". Par exemple, si vous dites 3 tours, le jeu se termine après avoir exécuté le flux de dire "Daruma-san est tombé" et de juger s'il a bougé ou non. Ce nombre de tours peut être défini sur commande depuis l'intérieur du jeu, de sorte que la durée du jeu peut être librement décidée sur place. Un tour dure environ 13 secondes (10 secondes jusqu'à ce que vous ayez fini de dire "Daruma-san est tombé", 3 secondes pour le temps du jugement).

Caractéristiques de ce plug-in

Toutes les fonctionnalités suivantes ne seront activées que par les joueurs qui sont dans le jeu et sont reconnus comme participants.

Celui qui permet de comprendre facilement s'il s'agit d'un participant ou non

スクリーンショット 2019-07-18 14.35.14.png スクリーンショット 2019-07-18 14.35.23.png Au début du jeu ou lorsque vous atteignez l'objectif, [Watching] ou [Participant] sera affiché à côté du nom dans la liste des joueurs. Cela permet à l'administrateur de connaître les participants, les spectateurs, qui a marqué, etc. en un seul coup.

objectif

2019-06-24_22.04.06.png Si vous placez un bouton de pierre sur un bloc d'or, c'est votre objectif. S'il y a un bouton de pierre autre que le haut du bloc d'or, ce ne sera pas un objectif. Lorsque le joueur a terminé, le mode de jeu passe en mode spectateur, et il devient mode spectateur.

public void GoalEvent(PlayerInteractEvent event) {
        if (Daruma.check) {
            Player player = event.getPlayer();
            Block block = event.getClickedBlock();
            if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                if ((block != null ? block.getType() : null) == Material.STONE_BUTTON) {
                    Location location = block.getLocation().clone();
                    location.add(0,-0.1,0);
                    if (player.getGameMode() == GameMode.ADVENTURE && Daruma.list.contains(player.getName()) && location.getBlock().getType().equals(Material.GOLD_BLOCK)) {
                        getServer().broadcastMessage(ChatColor.BLUE + player.getName() + ChatColor.WHITE + "J'ai un objectif!");
                        player.setPlayerListName("["+ChatColor.BLUE+"Objectif terminé"+ChatColor.WHITE+"]"+"["+ChatColor.RED+"Regarder le match"+ChatColor.WHITE+"]"+ChatColor.RED+player.getName());
                        if (player.hasMetadata(Events.DATA_KEY)) {
                            player.removeMetadata(Events.DATA_KEY, plugin);
                        }
                        getServer().broadcastMessage(clearTime(Daruma.time));
                        (player.getWorld()).playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 1);
                        Daruma.Goallist.add(player.getName()+"<"+clearTime(Daruma.time)+ChatColor.WHITE+">");
                        player.setGameMode(GameMode.SPECTATOR);
                        Daruma.list.remove(player.getName());
                        if(Daruma.list.isEmpty()){
                            getServer().broadcastMessage("Le jeu se termine car tous les participants ont atteint l'objectif.");
                            for (Player target : Bukkit.getOnlinePlayers()) {
                                if (target.getGameMode() == GameMode.ADVENTURE || target.getGameMode() == GameMode.SPECTATOR) {
                                    target.sendTitle(ChatColor.RED + "Fini!", "", 10, 15, 10);
                                    target.teleport(target.getWorld().getSpawnLocation());
                                    target.setGameMode(GameMode.ADVENTURE);
                                    target.setPlayerListName(target.getName());
                                    target.setLevel(0);
                                }
                            }
                            Daruma.game=false;
                            Daruma.check=false;
                        }
                    }
                }
            }
        }
    }

Le code ressemble à ceci. Si un participant clique sur un bloc d'or avec un bouton en pierre, changez le mode de jeu pour afficher le temps d'effacement et en même temps enregistrez le temps d'effacement dans le tableau de classement et listez le joueur comme participant. Il est censé être supprimé et ajouté [Objectif] à la liste des joueurs. À ce stade, si tous les participants ont atteint l'objectif, le jeu se terminera automatiquement.

int min,sec;
        min = (time%3600)/60;
        sec = time%60;
        String clearTime;
        clearTime = ChatColor.GREEN+"Temps clair:"+min+"Minutes"+sec+"Secondes";
        return clearTime;

Le temps d'effacement est calculé avec un code comme celui-ci.

Enregistrer le point

2019-06-24_22.04.19.png Si vous placez un bloc d'émeraude, il devient un point de sauvegarde. Puisqu'il s'agit d'une fonction de sauvegarde automatique, elle est automatiquement enregistrée au moment où elle passe sur le bloc émeraude qui est le point de sauvegarde, et si elle se déplace tout en déterminant si elle a bougé, elle ne sera pas renvoyée au point de départ, mais sera renvoyée au dernier point de sauvegarde passé. Je vais. La fonction de sauvegarde automatique utilise des métadonnées et la sauvegarde a un temps de recharge de 5 secondes.


Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.EMERALD_BLOCK) && Daruma.list.contains(player.getName())&&player.getLevel()<1) {
                    player.setLevel(5);
                    player.setMetadata(DATA_KEY, new FixedMetadataValue(plugin,player.getLocation().clone()));
                    player.sendMessage(ChatColor.AQUA + "Je l'ai sauvé!");
                    player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1, 24);
                    Timer timer = new Timer();
                    TimerTask task = new TimerTask() {
                        int i = 5;
                        @Override
                        public void run() {
                            if(i<1){
                                player.setLevel(0);
                                player.setExp(0);
                                timer.cancel();
                            }
                            player.setLevel(i);
                            i--;
                        }
                    };
                    timer.schedule(task,0,1000);
                }
            }

Le code ressemble à ceci, c'est comme obtenir la destination du joueur, enregistrer l'emplacement actuel du joueur dans les métadonnées s'il y a un bloc d'émeraude là-bas, et le donner au joueur. S'il est laissé tel quel, il sera activé en continu, nous avons donc mis en place un temps de recharge pour éviter une activation continue.

Classement

2019-06-24_13.48.11.png Lorsqu'un joueur a terminé, le serveur affichera le temps clair du joueur. Même après la fin du jeu, il est possible d'afficher la liste de temps claire de la personne qui a marqué le but avec la commande depuis l'intérieur du jeu.

String string;
            if (!(Daruma.Goallist.isEmpty())) {
                for (int i = 1; i <= Daruma.Goallist.size(); i++) {
                    string = i + "Rang:" + Daruma.Goallist.get(i - 1);
                    getServer().broadcastMessage(string);
                }
            } else {
                getServer().broadcastMessage("Aucun joueur n'a marqué de but.");
            }

Le code ressemble à ceci. Si quelque chose est écrit sur le tableau de classement, le tableau de classement sera affiché. Si le tableau de classement est vide, le tableau de classement ne sera pas affiché.

truc

J'ai créé un gadget qui s'active lorsque vous marchez dessus en appliquant des points de sauvegarde.

Tapis de saut

void jumpPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.REDSTONE_BLOCK) && Daruma.list.contains(player.getName())) {
                    player.sendMessage(ChatColor.AQUA+"Je suis sur le tapis de saut!");
                    for(float o=0;o<360;o=(float)(o+0.5)){
                        (player.getWorld()).spawnParticle(Particle.CLOUD,(float) (location.getX()+Math.sin(Math.toRadians(o))*1), (float) (location.getY()), (float) (location.getZ()+Math.cos(Math.toRadians(o))*1), 1, 0, 0, 0, 0);
                    }
                    player.playSound(player.getLocation(), Sound.ITEM_FIRECHARGE_USE, 1, 1);
                    player.setVelocity(new Vector(0,1.75,0));
                }
            }
        }
    }

J'ai fait un tapis de saut qui saute lorsque vous marchez sur le bloc de redstone. Ce n'est pas amusant de sauter tel quel, alors j'utilise également des jeux de sons et des particules pour ajouter de la direction.

Le sol sur lequel tu ne devrais pas marcher

void dontstep(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.NETHER_WART_BLOCK) && Daruma.list.contains(player.getName())) {
                    (player.getWorld()).spawnParticle(Particle.FLAME, location.getX(), location.getY(), location.getZ(), 30, 0.35, 0.35, 0.35);
                    if (player.hasMetadata(DATA_KEY)) {
                        MetadataValue value = null;
                        List<MetadataValue> values = player.getMetadata(DATA_KEY);
                        for (MetadataValue v : values) {
                            if (Objects.requireNonNull(v.getOwningPlugin()).getName().equals(plugin.getName())) {
                                value = v;
                                break;
                            }
                        }
                        if (value == null) {
                            return;
                        }
                        Location location1 = (Location) value.value();
                        assert location1 != null;
                        player.teleport(location1);
                    } else {
                        player.teleport(Daruma.startpoint);
                    }
                    player.playSound(player.getLocation(), Sound.ENTITY_GHAST_HURT, 1, 1);
                }
            }
        }
    }

Lorsque vous montez sur le bloc Nether Wart, vous serez redirigé vers le point de sauvegarde ou le point de départ. Cela a également une production qui dit: "Les étincelles sont dispersées à partir du point où le joueur atterrit." ~~ Quand je l'ai essayé, ça ressemblait à un rocher ● ~

Speed pad

void dashPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.DIAMOND_BLOCK) && Daruma.list.contains(player.getName())&&!(player.hasPotionEffect(PotionEffectType.SPEED))) {
                    player.sendMessage(ChatColor.AQUA+"Je suis sur le tableau de bord!");
                    player.playSound(player.getLocation(),Sound.BLOCK_BEACON_AMBIENT,1,1);
                    player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,30,3),true);
                }
            }
        }
    }

J'ai créé un tableau de bord qui accélère pendant un certain temps lorsque vous marchez sur le bloc de diamant. L'addPotionEffect donne un effet de potion qui augmente la vitesse de déplacement. ~~ Ne dites pas que je ne pouvais pas penser à une production ~~

Pad lent

void slowPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.LAPIS_BLOCK) && Daruma.list.contains(player.getName())&&!(player.hasPotionEffect(PotionEffectType.SLOW))) {
                    player.playSound(player.getLocation(),Sound.ENTITY_SLIME_JUMP,1,1);
                    player.sendMessage(ChatColor.RED+"Je suis monté sur le tapis lent!");
                    player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW,80,3),true);
                }
            }
        }
    }

J'ai fait un pad lent qui ralentit pendant un certain temps lorsque vous marchez sur le bloc Lapis Lazuri. Le mécanisme est presque le même que le pad de vitesse.

Coussin aveugle

void blindPad(PlayerMoveEvent event){
        if((Daruma.game)){
            Player player = event.getPlayer();
            if (player.isOnGround()){
                Location location = event.getTo().clone();
                location.add(0, -0.1, 0);
                if (location.getBlock().getType().equals(Material.COAL_BLOCK) && Daruma.list.contains(player.getName())&&!(player.hasPotionEffect(PotionEffectType.BLINDNESS))) {
                    player.playSound(player.getLocation(),Sound.ENTITY_SLIME_JUMP,1,1);
                    player.sendMessage(ChatColor.RED+"Je suis sur le tapis aveugle!");
                    player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS,80,255),true);
                }
            }
        }
    }

J'ai fait un tampon aveugle qui disparaît pendant un certain temps lorsque vous marchez sur le bloc de charbon. Le mécanisme est presque le même que le pad de vitesse.

finalement

Il a fallu environ six mois pour arriver à ce point. C'est une erreur fatale visqueuse, et elle est finalement terminée en étant crachée, donc je suis fier de ce plug-in. J'utilise la méthode sleep dans certaines parties du traitement du jeu, mais si je l'utilise sans réfléchir, le jeu lui-même s'arrêtera (car tout le traitement est effectué dans un thread), donc la classe Timer pour que le jeu ne s'arrête pas Il était difficile de concevoir quelque chose comme l'utilisation. Il y a peut-être un meilleur moyen, mais je l'ai utilisé pour le moment. Cependant, je suis encore immature et je pense qu'il y a encore des points qui peuvent être améliorés, alors j'aimerais y apporter des améliorations. S'il y a une voix telle que "Je veux que tu la distribues", je la distribuerai après avoir ajouté des explications telles que des commandes dédiées. ~~ Je serais heureux si vous pouviez le diffuser via des likes, des actions, Twitter, etc. ~~ Merci d'avoir lu jusqu'ici. La source sera ici.

Recommended Posts

J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft
J'ai fait un package qui peut comparer des analyseurs morphologiques avec Python
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
J'ai créé un plug-in "EZPrinter" qui génère facilement des PDF cartographiques avec QGIS.
J'ai fait un module PyNanaco qui peut charger des crédits nanaco avec python
Récapitulatif du format des formats qui peuvent être sérialisés avec gensim
J'ai étudié le prétraitement qui peut être fait avec PyCaret
J'ai créé un plug-in qui peut faire "Daruma-san tombé" avec Minecraft
Une histoire qui a trébuché lorsque j'ai créé un bot de chat avec Transformer
J'ai fait une loterie avec Python.
J'ai fait une minuterie pomodoro dure qui fonctionne avec CUI
J'ai créé un démon avec Python
J'ai fait un programme qui calcule automatiquement le zodiaque avec tkinter
[python] J'ai créé une classe qui peut écrire rapidement une arborescence de fichiers
J'ai fait un compteur de caractères avec Python
J'ai fait une carte hexadécimale avec Python
J'ai fait un jeu de vie avec Numpy
J'ai fait un générateur Hanko avec GAN
J'ai fait un jeu rogue-like avec Python
J'ai fait un simple blackjack avec Python
J'ai créé un fichier de configuration avec Python
J'ai fait une application WEB avec Django
J'ai fait un simulateur de neurones avec Python
[Python] J'ai créé un utilitaire qui peut accéder au type dict comme un chemin
J'ai fait une simple minuterie qui peut être démarrée depuis le terminal
J'ai créé un outil qui facilite un peu la décompression avec CLI (Python3)
J'ai fait un robot de remplacement de tampon avec une ligne
J'ai fait une prévision météo de type bot avec Python.
J'ai créé une application graphique avec Python + PyQt5
Mémo qui a fait un graphique pour animer avec intrigue
J'ai essayé de créer un bloqueur de filles pourries sur Twitter avec Python ①
[Python] J'ai créé un téléchargeur Youtube avec Tkinter.
J'ai fait un simple portefeuille de Bitcoin avec pycoin
J'ai créé un Bot LINE avec Serverless Framework!
J'ai fait un graphique de nombres aléatoires avec Numpy
J'ai fait un jeu de cueillette avec Python
Made Mattermost Bot avec Python (+ Flask)
J'ai créé une image Docker qui peut appeler FBX SDK Python à partir de Node.js
Une histoire à laquelle j'étais accro après la communication SFTP avec python
〇✕ J'ai fait un jeu
J'ai fait un Twitter BOT avec GAE (python) (avec une référence)
J'ai créé un bot de livre de compte de ménage avec LINE Bot
J'ai créé un serveur syslog prêt à l'emploi avec Play with Docker
J'ai fait un jeu d'éclairage de sapin de Noël avec Python
J'ai créé une fenêtre pour la sortie du journal avec Tkinter
J'ai créé une application de notification de nouvelles en ligne avec Python
J'ai créé une VM qui exécute OpenCV pour Python
J'ai essayé de faire LINE BOT avec Python et Heroku
Un mémo que j'ai touché au magasin de données avec python
J'ai fait un jeu mono tombé avec Sense HAT
J'ai créé une application Twitter qui décrypte les caractères de pré-connexion avec heroku (échec)
Création d'une application Web qui mappe les informations sur les événements informatiques avec Vue et Flask
[Python] J'ai créé une fonction qui déchiffre et décrypte AES simplement en le lançant avec pycrypto.
J'ai fait un jeu de frappe simple avec tkinter de Python
J'ai créé un package pour filtrer les séries chronologiques avec python
J'ai fait un blackjack avec du python!
J'ai créé une application de livre simple avec python + Flask ~ Introduction ~
unixtime ← → J'ai essayé de créer une classe qui effectue facilement la conversion datetime