1. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

[СТАТЬЯ] Как сделать мини-игру?

Тема в разделе "Разработка плагинов для новичков", создана пользователем HunterGaming, 3 сен 2017.

  1. Автор темы
    HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    МИНИ-ИГРА

    Привет форумчане, думаю все хотят научится писать мини-игры(по крайней мере я хотел, и научился уже на 75%), и писал недавно о том, кто бы создал тему по созданию мини-игры, вот сам я и создаю).

    Что же нужно для создания мини-игры? Как минимум знание основ Java, а также Bukkit API.

    В этой теме я расскажу и покажу вам основной код мини-игры, логику и эвенты дописать думаю сами сумеете. У нас будет 5 классов:
    - Arena(в этом классе мы будем описывать свойства и методы),
    - ArenaManager(Менеджер всех арен),
    - ArenaState(Статус арены: LOBBY, GAME),
    - Utils(Класс с утилитой),
    - Main(Главный класс).

    Начнем мы с класса Arena:

    Код:
    package me.hunterplay.spleef.arena;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    import org.bukkit.Bukkit;
    import org.bukkit.GameMode;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.*********ventory.ItemStack;
    import org.bukkit.scoreboard.DisplaySlot;
    import org.bukkit.scoreboard.Objective;
    import org.bukkit.scoreboard.Score;
    import org.bukkit.scoreboard.Scoreboard;
    
    import me.hunterplay.spleef.Main;
    import me.hunterplay.spleef.config.MessageConfig;
    import me.hunterplay.spleef.utils.Utils;
    
    public class Arena extends ArenaManager {
    
        private Arena arena;
    
        private String arenaName; //Имя арены
        private List<String> arenaPlayers; //Лист игроков
        private int arenaTimeToStart; //Время до старта игры
        private int arenaTime; //Время игры
        private int arenaMinPlayers; //Минимальное кол-во игроков
        private int arenaMaxPlayers; //Максимальное кол-во игроков
        private ArenaState arenaState; //Статус арены
        private Location arenaSpawnPoint; //Локация, куда будет телепортироваться игрок на игру
        private Location arenaLobby; //Лобби арены
        private Location arenaPos1; //1 позиция арены
        private Location arenaPos2; //2 позиция арены
        private boolean lobbyCountdown; //Булевское значение - таймер лобби
        private boolean arenaCountdown; //Булевское значение - таймер арены
        private int lobbyScheduler; //Шедулер лобби
        private int arenaScheduler; //Шедулер арены
    
        public Arena(String arenaName) { //Конструктор для создания арены, для того что бы создать арену нужно написать Arena arena = new Arena("Arena1"), но так мы писать не будем, для этого есть отдельный класс ArenaManager, в нем будет метод
            this.arenaName = arenaName;
            arenaPlayers = new ArrayList<String>();
            arenaState = ArenaState.LOBBY;
            arena = this;
        }
    
        public void addPlayer(String pName) { //Добавление игрока на арену
            Player p = Bukkit.getPlayer(pName); //Создаем объект игрока с именем pName
    
            if (arenaLobby == null || arenaPos1 == null || arenaPos2 == null) { //Если локации равняются null, то пишем сообщение о том что арена не настроена и выходим из метода
                p.sendMessage("Арена не настроена!");
                return;
            }
    
            if (arenaIsFull()) { //Если арена заполнена, то пишем сообщение о том что она заполнена и выходим из метода
                p.sendMessage("Арена заполнена!");
                return;
            }
    
            if (arenaState != ArenaState.LOBBY) { //Если статус арены не лобби, то пишем сообщение о том что арена находится в игре и выходим из метода
                p.sendMessage("Арена находится в игре!");
                return;
            }
    
            p.getInventory().clear(); //Очищаем весь инвентарь игрока
            p.setHealth(p.getMaxHealth()); //Лечим игрока
            p.setFoodLevel(20); //Кормим игрока
            p.setFireTicks(0); //Тушим игрока от огня
            p.setGameMode(GameMode.SURVIVAL); //Ставим режим выживания
            p.teleport(arenaLobby); //Телепортируем в лобби арены
            arenaPlayers.add(pName); //Добавляем игрока в лист игроков
            sendMessageToArena(p.getName() + " присоединился к игре. Игроков " + arenaPlayers.size() + "/" + arenaMaxPlayers + "."); //Отправляем сообщение всем учащимся арены, о том что присоединился новый игрок
    
            Scoreboard scoreBoard = Bukkit.getScoreboardManager().getNewScoreboard(); //Создаем скорборд
            Objective objective = scoreBoard.registerNewObjective(arenaName, "dummy"); //Создаем обжектив с именем арены
            objective.setDisplayName("Lobby"); //Указываем тайтл нашего скорборда
            objective.setDisplaySlot(DisplaySlot.SIDEBAR); //Задаем displayslot, чтоб скорборд находился справа экрана
            for (int i = 0; i < 3; i++) { //Цикл для создания пустых ячеек в скорборде, сделано для красоты
                String[] str = { "", " ", "  " };
                Score score = objective.getScore(str[I]);
                score.setScore(i + 1);
            }
            Score messagePlayers = objective.getScore("Игроков " + arenaPlayers.size() + "/" + arenaMaxPlayers); //Показываем кол-во игроков и максимальное кол-во арены в скорборде
            messagePlayers.setScore(0);
            p.setScoreboard(scoreBoard); //Присваиваем скорборд игроку
    
            if (arenaPlayers.size() >= arenaMinPlayers) { //Если кол-во игроков в листе больше минимального значения, то запускаем таймер
                startCountdown(); //Запуск таймера
            }
        }
    
        public void startArena() { //Старт арены
            if (arenaCountdown) //Если arenaCountdown = true, то выходим из метода
                return;
    
            arenaCountdown = true; //Ставим значение true для arenaCountdown
    
            for (String pName : arenaPlayers) { //Перебираем всех игроков арены
                if (Bukkit.getPlayer(pName) == null) { //Если игрок вышел, то убираем его из листа
                    arenaPlayers.remove(pName);
                }
    
                if (arenaPlayers.size() < arenaMinPlayers) { //Если кол-во игроков меньше чем минимальное, выполняем следующие действия и выходим из метода
                    sendMessageToArena("Недостаточно игроков для старта игры!"); //Уведомляем игроков, о том что кол-во игроков меньше чем минимальное кол-во игроков
                    Scoreboard scoreBoard = Bukkit.getScoreboardManager().getNewScoreboard(); //Создаем новый скорборд
                    Objective objective = scoreBoard.registerNewObjective(arenaName, "dummy"); //Создаем новый обжектив с именем арены
                    objective.setDisplayName("Lobby"); //Указываем тайтл нашего скорборда
                    objective.setDisplaySlot(DisplaySlot.SIDEBAR); //Задаем displayslot, чтоб скорборд находился справа экрана
                    for (int i = 0; i < 3; i++) { //Цикл для создания пустых ячеек в скорборде, сделано для красоты
                        String[] str = { "", " ", "  " };
                        Score score = objective.getScore(str[I]);
                        score.setScore(i + 1);
                    }
                    Score messagePlayers = objective.getScore("Игроков " + arenaPlayers.size() + "/" + arenaMaxPlayers); //Показываем кол-во игроков и максимальное кол-во арены в скорборде
                    messagePlayers.setScore(0);
                    Bukkit.getPlayer(pName).setScoreboard(scoreBoard); //Присваиваем скорборд игроку
                    return;
                }
            }
    
            arenaState = ArenaState.GAME; //Задаем статус арены
            arenaCountdown = true; //Задаем arenaCountdown
            sendMessageToArena("Игра началась..."); //Уведомляем всех игроков арены, о том что игра началась
    
            for (String pName : arenaPlayers) {
                Player p = Bukkit.getPlayer(pName);
    
                //TODO: если надо выдаем предметы, думаю сделаете сами
    
                p.teleport(arenaSpawnPoint); //Телепортируем всех игроков арены на локацию арены
            }
    
            arenaScheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getInstance(), new Runnable() { //Создаем шедулер и присваиваем его значение нашей переменной arenaScheduler
                int arenaT = arenaTime; //Время игры
    
                [USER=79777]@Override[/USER]
                public void run() {
                    Scoreboard scoreBoard = Bukkit.getScoreboardManager().getNewScoreboard();
                    Objective objective = scoreBoard.registerNewObjective(arenaName, "dummy");
                    objective.setDisplayName("Game");
                    objective.setDisplaySlot(DisplaySlot.SIDEBAR);
                    Score messageToStart = objective.getScore("До конца осталось:");
                    messageToStart.setScore(1);
                    Score timeToStart = objective.getScore(Utils.getUtils().formatTime(arenaT));
                    timeToStart.setScore(0);
    
                    Iterator<String> players = arenaPlayers.iterator(); //Итератор - почти тоже самое, что у оператор for, но только если здесь вы используете for, и начнете чистить список играющих, то у вас вылетит ConcurrentModificationException, поэтому здесь используем Iterator
    
                    while(players.hasNext()) { // Пока у итератора не кончились ячейки
                        Player p = Bukkit.getPlayer(players.next());
    
                        p.setScoreboard(scoreBoard); //Присваиваем игрокам скорборд
                    }
    
                    if (arenaT <= 0) { //Если время меньше или равно 0, то заканчиваем игру
                        endArena(); //Конец игры
                    }
                    arenaT--;
                }
            }, 20L, 20L);
        }
    
        public void endArena() { //Конец
    
            //TODO: если надо, то ресетим площадку арены, либо загружаем схематик
         
            if (arenaPlayers != null) { //Если лист не пустой
                broadcastMessage(arenaPlayers.get(0) + " победил на арене " + arena.getArenaName());
                arenaState = ArenaState.LOBBY;
    
                Iterator<String> endPlayers = arenaPlayers.iterator();
                while(endPlayers.hasNext()) {
                    Player p = Bukkit.getPlayer(endPlayers.next());
                    endPlayers.remove();
    
                    if (p != null) {
                        p.teleport(ArenaManager.getArenaManager().getMainLobby()); // Телепортируем игрока главное лобби
                        p.setHealth(p.getMaxHealth());
                        p.setFireTicks(0);
                        p.getInventory().clear();
                    }
                    stopArenaCountdown(p); //Останавливаем шедулер арены, и ставим стандартный скорборд игроку
                }
            }
        }
    
        public void startCountdown() { //Старт таймера в лобби
            if (lobbyCountdown) //Если lobbyCountdown = true, выходим из метода
                return;
    
            lobbyCountdown = true; //Ставим значение true
    
            lobbyScheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getInstance(), new Runnable() { //Создаем шедулер и присваиваем его нашей переменной lobbyScheduler
                int arenaTTS = arenaTimeToStart; //Время до старта игры
    
                [USER=79777]@Override[/USER]
                public void run() {
                    Scoreboard scoreBoard = Bukkit.getScoreboardManager().getNewScoreboard();
                    Objective objective = scoreBoard.registerNewObjective(arenaName, "dummy");
                    objective.setDisplayName("Lobby");
                    objective.setDisplaySlot(DisplaySlot.SIDEBAR);
                    Score messageToStart = objective.getScore("До начала осталось:");
                    messageToStart.setScore(3);
                    Score timeToStart = objective.getScore(Utils.getUtils().formatTime(arenaTTS));
                    timeToStart.setScore(2);
                    Score none = objective.getScore("");
                    none.setScore(1);
                    Score players = objective.getScore("Игроков " + arenaPlayers.size() + "/" + arenaMaxPlayers);
                    players.setScore(0);
    
                    if (arenaPlayers.size() == 0) { //Если кол-во игроков в листе равно 0, то
                        Bukkit.getScheduler().cancelTask(lobbyScheduler); //Останавливаем шедулер лобби
                        lobbyCountdown = false; //Ставим значение false
                    }
    
                    for (String pName : arenaPlayers) {
                        Player p = Bukkit.getPlayer(pName);
    
                        p.setScoreboard(scoreBoard);
    
                        if (arenaTTS <= 0) { //Если arenaTTS меньше или равно 0, то
                            stopLobbyCountdown(p); //Останавливаем шедулер лобби и задаем стандартный скорборд
                            startArena(); //Начинаем игру
                        }
                    }
                    arenaTTS--;
                }
            }, 20L, 20L);
        }
    
        public void stopLobbyCountdown(Player p) { //Метод для удаления шедура лобби и установки стандартного скорборда
            Bukkit.getScheduler().cancelTask(lobbyScheduler);
            lobbyCountdown = false;
            p.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
        }
    
        public void stopArenaCountdown(Player p) { //Метод для удалиния шедулера арены и установки стандартного скорборда
            Bukkit.getScheduler().cancelTask(arenaScheduler);
            arenaCountdown = false;
            p.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
        }
    
        public void sendMessageToArena(String msg) { //Отправка сообщения всем игрокам арены
            if (arenaPlayers.size() == 0) {
                return;
            }
    
            for (String pName : arenaPlayers)
                if (Bukkit.getPlayer(pName) != null)
                    Bukkit.getPlayer(pName).sendMessage(msg);
        }
    }
    
     
    Последнее редактирование: 3 сен 2017
  2. Автор темы
    HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Продолжение первой статья, геттеры и сеттеры, тоже вставьте в этот класс

    Код:
        public boolean arenaIsFull() { //Проверка, заполнена ли арена
            return arenaPlayers.size() >= arenaMaxPlayers;
        }
    
        public Arena getArena() { //Геттер arena
            return arena;
        }
    
        public String getArenaName() { //Получение объекта арены
            return arenaName;
        }
    
        public void setArenaName(String arenaName) { //Установка имени арены
            this.arenaName = arenaName;
        }
    
        public List<String> getArenaPlayers() { //Получение листа игроков
            return arenaPlayers;
        }
    
        public int getArenaTimeToStart() { //Получение времени до начала игры
            return arenaTimeToStart;
        }
    
        public void setArenaTimeToStart(int arenaTimeToStart) { //Установка времени для начала игры
            this.arenaTimeToStart = arenaTimeToStart;
        }
    
        public int getArenaTime() { //Получение времени игры
            return arenaTime;
        }
    
        public void setArenaTime(int arenaTime) { //Установка времени игры
            this.arenaTime = arenaTime;
        }
    
        public int getArenaMinPlayers() { //Получение минимального кол-ва игроков
            return arenaMinPlayers;
        }
    
        public void setArenaMinPlayers(int arenaMinPlayers) { //Установка минимального кол-ва игроков
            this.arenaMinPlayers = arenaMinPlayers;
        }
    
        public int getArenaMaxPlayers() { //Получение максимального кол-ва игроков
            return arenaMaxPlayers;
        }
    
        public void setArenaMaxPlayers(int arenaMaxPlayers) { //Установка максимального кол-ва игроков
            this.arenaMaxPlayers = arenaMaxPlayers;
        }
    
        public ArenaState getArenaState() { //Получение статуса арены
            return arenaState;
        }
    
        public void setArenaState(ArenaState arenaState) { //Установка статуса арены
            this.arenaState = arenaState;
        }
    
        public Location getArenaSpawnPoint() { //Получение локации арены
            return arenaSpawnPoint;
        }
    
        public void setArenaSpawnPoint(Location arenaSpawnPoint) { //Установка локации арены
            this.arenaSpawnPoint = arenaSpawnPoint;
        }
    
        public Location getArenaLobby() { //Получение лобби арены
            return arenaLobby;
        }
    
        public void setArenaLobby(Location arenaLobby) { //Установка лобби арены
            this.arenaLobby = arenaLobby;
        }
    
        public Location getArenaPos1() { //Получение 1 позиции арены
            return arenaPos1;
        }
    
        public void setArenaPos1(Location arenaPos1) { //Установка 1 позиции арены
            this.arenaPos1 = arenaPos1;
        }
    
        public Location getArenaPos2() { //Получение 2 позиции арены
            return arenaPos2;
        }
    
        public void setArenaPos2(Location arenaPos2) { //Установка 2 позиции арены 
            this.arenaPos2 = arenaPos2;
        }
    
        public boolean isLobbyCountdown() { //Проверка, включен ли таймер в лобби
            return arenaCountdown;
        }
    
        public void setLobbyCountdown(boolean lobbyCountdown) { //Включение/отключение таймера в лобби
            this.lobbyCountdown = lobbyCountdown;
        }
    
        public boolean isArenaCountdown() { //Проверка, включен ли таймер на арене
            return arenaCountdown;
        }
    
        public void setArenaCountdown(boolean arenaCountdown) { //Включение/отключение таймера на арене
            this.arenaCountdown = arenaCountdown;
        }
    
        public int getLobbyScheduler() { //Получение значения lobbyScheduler
            return lobbyScheduler;
        }
    
        public void setLobbyScheduler(int lobbyScheduler) { //Установка значения lobbyScheduler
            this.lobbyScheduler = lobbyScheduler;
        }
    
        public int getArenaScheduler() { //Получение значения arenaScheduler
            return arenaScheduler;
        }
    
        public void setArenaScheduler(int arenaScheduler) { //Установка значения arenaScheduler
            this.arenaScheduler = arenaScheduler;
        }
    
    На сегодня все, если вам понравилось начало, отпишите в комментариях и я продолжу статью.
     
  3. TheZefirrkka

    TheZefirrkka Активный участник Пользователь

    Баллы:
    76
    Нееееет, опять....
     
  4. Bomblerm

    Bomblerm Новичок

    Баллы:
    6
    Жду дальнейших статьей!
     
  5. Rider3217

    Rider3217 Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Planet0111
    Код:
    public Arena(String arenaName) { //Конструктор для создания арены, для того что бы создать арену нужно написать Arena arena = new Arena("Arena1"), но так мы писать не будем, для этого есть отдельный класс ArenaManager, в нем будет метод
            this.arenaName = arenaName;
            arenaPlayers = new ArrayList<String>();
            arenaTimeToStart = 0;
            arenaTime = 0;
            arenaMinPlayers = 0;
            arenaMaxPlayers = 0;
            arenaState = ArenaState.LOBBY;
            arenaSpawnPoint = null;
            arenaLobby = null;
            arenaPos1 = null;
            arenaPos2 = null;
            lobbyCountdown = false;
            arenaCountdown = false;
            lobbyScheduler = 0;
            arenaScheduler = 0;
            arena = this;
        }
    Зачем так делать? Эти обьекты и так будут null, а примитивные переменные и так будут равны 0. Ну а boolean переменные и так будут false.
     
  6. Автор темы
    HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Спасибо, буду знать и исправлю.
     
  7. Автор темы
    HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Что тебе не нравится?
     
  8. hyndorik

    hyndorik Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    hyndo
    Половину скопипастил с давней темы, в некоторых местах текст даже идентичен
     
  9. Rider3217

    Rider3217 Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Planet0111
    Даже если так, то сама идея продолжения такой статьи уже радует.
     
  10. imDaniX

    imDaniX Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
  11. DonDays

    DonDays Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    DonDays
    runTaskTimer = BukkitTask - BukkitTask[]
    Location[]
    Зачем хранить игроков в виде их имен? Если игрок выйдет, он уже проигрывает/выйдет из очереди (waiting), как я понимаю, смысл тогда хранить их имена?
    Ужас, лучше сделать отдельный класс для работы с бордом, который сам будет искать повторяющиеся линии, записывая при вписывании линии их в лист
    [​IMG]
    АААААААААААААААААААА, стопаем один шедуллер столько раз, сколько игроков на арене :whistle:
    lombok
     
  12. Автор темы
    HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Спасибо, за твою критику.
     
  13. Автор темы
    HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Ну, а если остальным нравится, я буду продолжать.
     
  14. CatCoder

    CatCoder Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    CatCoder
  15. TheZefirrkka

    TheZefirrkka Активный участник Пользователь

    Баллы:
    76
    не надо
     
  16. DonDays

    DonDays Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    DonDays
    сними флажок и не продолжай писать
    [​IMG]
     
  17. Cool_boy

    Cool_boy Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    prettydude
    Добавил бы голосование... хотя нет, не надо, жмякай флажок выше.
     
  18. Rider3217

    Rider3217 Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Planet0111
    Продолжай, не обращай внимание на д*унов выше.
    А вам, дорогим д*унам, хочу сказать: Если информация в статье актуальная и развивающая + если она не заброшена, то дополнять статью нужно обязательно, какой бы плохой код не был. К тому же вы все-равно поможете ему исправить костыльность кода.
     
  19. Rider3217

    Rider3217 Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    Planet0111
    Не нравится - не читай.
    Я, думаю, ты заметил, что я выражаюсь так, как считаю нужным.
     
  20. thematdev

    thematdev Активный участник Пользователь

    Баллы:
    46
    Имя в Minecraft:
    thematdev
    Ну дык ты напиши статью со всеми исправлениями раз такой умный...
     

Поделиться этой страницей