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

Помогите Как рисовать/писать на картах?

Тема в разделе "Разработка плагинов для новичков", создана пользователем fromgate, 1 июн 2012.

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

    fromgate Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    Вобщем в двух словах, после этого любой кто захочет, мне кажется сможет рисовать и писать на картах:

    1. Рендерер. Собственно он и занимается рисованием.
    Код:
    package fromgate.dogtags;
     
    import org.bukkit.entity.Player;
    import org.bukkit.map.MapCanvas;
    import org.bukkit.map.MapRenderer;
    import org.bukkit.map.MapView;
    import org.bukkit.map.MinecraftFont;
     
    public class DTRenderer extends MapRenderer {
     
        Dogtags plg;
        String text;
     
        public DTRenderer (Dogtags plg, String text){
            super (true);
            this.plg = plg;
            this.text =  text;
        }
     
        @Override
        public void render(MapView map, MapCanvas canvas, Player p) {
            // "обнуляем" карту
            for (int j = 0; j < 128; j++)
                for (int i = 0; i < 128; i++)
                  canvas.setPixel(i, j, (byte) 0);
            // plg.dtimg - картинка (тип Image) загруженная из файла
            // если она существует - используем её как подложку
            if (plg.dtimg != null) canvas.drawImage(0, 0, plg.dtimg);
            // пишем текст строго по середине
            canvas.drawText(30, 63-(MinecraftFont.Font.getHeight()/2), MinecraftFont.Font, text);
            // пишем текст внизу карты
            canvas.drawText(2, 127-MinecraftFont.Font.getHeight(), MinecraftFont.Font, "§54;(с)2012, fromgate");
        }
    }
    



    В плагине, процедура создания новой карты (возвращает значение data предмета. Т.е. если вернуло 5, то просмотреть карту можно посредством /i map:5)
    Код:
        public int createMap(Player p, String text){
            MapView map = Bukkit.getServer().createMap(p.getWorld());
            DTRenderer mr = new DTRenderer (this, text);
            mr.initialize(map);
            // Удаляем стандартные рендереры
            map.getRenderers().clear();
            // Назначаем наш
            map.addRenderer(mr);
            return map.getId();
        }

    Теперь собственно можно создать карту при помощи команды:
    createMap (player, "map test");
    Где player - это игрок.
     
    ufes нравится это.
  2. Автор темы
    fromgate

    fromgate Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    Ну и соответственно если у вас несколько типов карт, нужно либо писать несколько рендереров либо же создавать универсальный, который в зависимости от параметров рисует то что нужно.

    Да, и картинку я готовил заранее: 128х128, соответствующая палитра. "Любую" картинку подсовывать пока не пробовал.
     
    ufes нравится это.
  3. Автор темы
    fromgate

    fromgate Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    Обнаружился ещё один нюанс. Карты... обнуляются после рестарта. Поэтому сделал процедурку, которая обновляет карту. Т.е. переназначает ей рендерер заново. Вызываю в onEnable задаю в качестве параметров сохраненные в файл значения id карты и текст, который на карте пишется.

    Код:
        public void updateMap(short id, String txt){
            MapView map = Bukkit.getServer().getMap(id);
            DTRenderer mr = new DTRenderer (this, txt);
            mr.initialize(map);
            for (MapRenderer r : map.getRenderers()) map.removeRenderer(r);
            map.addRenderer(mr);
        }
    
     
    ufes нравится это.
  4. makkarpov

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

    Баллы:
    88
    Это даже плюс, ибо количество карт ограничено, а так можно пересовывать только те карты, которые нужны, а остальные помечать как свободные
     
  5. Автор темы
    fromgate

    fromgate Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    makkarpov, я не правильно выразился. Обнуляется изображение. Почему-то изображение нарисованное моим рендерером не сохраняется в файл карты :(
    И чтобы не создавать новую карту - нужно апдейтить старую. Но если выясню как сохранять, апдейт карты будет не нужен...

    С картами же вообще бодяга странная. Свободных карт по сути не бывает. Есть "утерянные". Допусти сделал игрок карту (id 0) и уронил её. Она деспавнилась. Другой игрок сделал карту карту (id 1). В этом случае есть вероятность, что он получит пустую карту, на которой будет нарисовано id 0, а после правого клика картой она сменит свой номер на 1 будет нормально работать. Новая карта всегда будет иметь номер равный текущему количеству карт. Деспавнутые карты, к сожалению не замещаются. Хотя вроде было бы логично...
     
    ufes нравится это.
  6. Автор темы
    fromgate

    fromgate Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    Кстати, добавлю. Изображение обнуляется потому, что не происходит записи в NBT. Стандартный рендерер, насколько я помню, этим и занимается. Загружает изображение из NBT, меняет его (если есть изменения). И сохраняет обратно.

    С этим можно бороться несколькими способами (Я ещё не пробовал, потому рассуждают теоретически).
    1. Не удалять стандартные рендереры. Смещать координаты карты и надеяться, что Ваша картинка сохранится вместе с картой.
    2. Сохранять изображение самому. Так работать будет точно.
     
  7. ufes

    ufes Старожил Девелопер Пользователь

    Баллы:
    173
    DPOH-VAR вроде бы как копался в NBT.
     
  8. DPOH-VAR

    DPOH-VAR Старожил Пользователь

    Баллы:
    153
    Skype:
    dpohvar
    Да, копался.
    Я не трогал карты map_#.dat, но уверен, что там все просто.
    Вот описание содержания файла: http://www.minecraftwiki.net/wiki/Map_Item_Format
    Редактировать его вручную очень просто:
    есть класс NBTCompressedStreamTools, который загружает гзипнутый файл и представляет его в виде NBTTagCompound. Далее все по инструкции.
    Сложность заключается в том, что тут картинка сохраняется попиксельно, каждый цвет кодируется одним байтом => нельзя применить обычный рендер и скорее всего придется писать свой. (насколько понял - у карт есть всего несколько ключевых цветов по 4 градаций)
    Как взять NBT теги после рендеринга - я еще не разобрался. Скорее всего помогут методы a(NBTTagCompound) и b(NBTTagCompound) у класса WorldMapBase. Один из них нужен для загрузки данных, другой для выгрузки. (предполагаю, что b - для получения объекта, a - для рендеринга). Тогда возможно получится использовать обычный рендер, а затем полученный тег сохранять в файл.
     
    ufes нравится это.
  9. Автор темы
    fromgate

    fromgate Старожил Пользователь

    Баллы:
    173
    Имя в Minecraft:
    fromgate
    DPOH-VAR, там все просто, я копался в исходниках craftbukkit и убедился ;). Даже если не понимать, что там делается - можно тупо скопировать ;)
    Я просто не нашёл причин, для чего мне это действительно нужно - сохранять в картах. Лишняя работа.
     

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