Задать вопрос
  • Направления создание клона Minecraft?

    twobomb
    @twobomb
    Делал когда-то такое на Unity. У меня помоему высота мира была 96 блоков, даже распространения воды делал точно такую как в ваниле, генерация ресурсов, травы деревьев, пещер и разные биомы. Билдил проект в веб приложение, запускал в браузере на старом самсунге еще на пятом андроиде, было около 30 фпс. На компе в браузере выдавало помоему больше тысячи фепесов. Ну насколько я помню это при том что браузер не умеет в многопоточность, если бы это было как приложение винды можно сильно быстрее. Ну естественно тут нужно постоянно выдумывать решения по оптимизации. Все 3д объекты, все текстуры, каждая точечка каждого полигона прописывалась ручками. На сколько я помню, у меня рендерилось всё чанками, 16х16 блоков. Тоесть чанк (16х16 блоков), это был один 3д объект, один меш которые создавался кодом. Естественно отображается только видимая часть, я думаю это понятно что мы не рендерим все блоки, а рендерим и создаем меш только видимой части блока, условно если это ровная площадка то сетка будет состоять только из верхних частей блока. Далее насколько я помню у меня был рендер и обратка по углу обзора, тоесть то куда игрок смотрит то и просчитывается , то и оборажается. По итогу мне также пришлось писать свои шейдеры (хотя я раньше никогда с этим не сталкивался), но это во первых нужно чтобы делать такой же свет как майнкрафте и такое же распространение света, у меня даже было 2 схемы жесткое (как было в старой версии майна) и мягкий как в новой. Во вторых переход на свои шейдеры еще поднял производительность.
    Ну крч, могу сказать это реально сложно. Даже таже генерация, там оч много математики, эти матрицы...С переходом между биомами я оч долго возился. Можно банально на день зависнуть только решая проблему, почему в твоём шейдере через полупрозрачную текстуру льда, другие текстуры или светящиеся объекты не корректно отображатся...
    Ну я там дошёл уже до того что начал делать генерацию деревень, и на этом моменте забил. Могу поискать код если интересно, ну там чёрт ногу сломит, я думаю даже я уже не разбирусь чё я там делал...
    Ответ написан
  • Как я могу сохранить список comboBox1, после закрытия программы?

    twobomb
    @twobomb
    private const string FILE = "C:\\savedata.txt";
            public Form1()
            {
                InitializeComponent();
                comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
                if (File.Exists(FILE)){
                    IFormatter f = new BinaryFormatter();
                    var fs = new FileStream(FILE, FileMode.Open, FileAccess.ReadWrite);
                    var data = (List<string>) f.Deserialize(fs);
                    comboBox1.Items.AddRange(data.ToArray());
                    fs.Close();
                }
            }
            protected override void OnClosing(CancelEventArgs e)
            {
                IFormatter f = new BinaryFormatter();
                var data = comboBox1.Items.Cast<string>().ToList();
                var fs = new FileStream(FILE, FileMode.Create, FileAccess.ReadWrite);
                f.Serialize(fs, data);
                fs.Close();
            }
    Ответ написан
    6 комментариев
  • Где лучше получать ввод - в Update или FixedUpdate?

    twobomb
    @twobomb
    Сделай ввод в FixedUpdate и посмотри на инпут лаг, и поймешь почему не стоит так делать. Хотя если не требуется динамичного управления, то вообще пофиг.
    p.s. ну это при условии дефолтной частоты вызовов, сколько она там 25 раз вызывается в сек?
    Ответ написан
    Комментировать
  • Почему ошибка SyntaxError: expected ':'?

    twobomb
    @twobomb
    Зачем вы в else задаёте условие? else это всё остальное, или уберите num > 3 или сделайте elif
    Ответ написан
    1 комментарий
  • Что нужно изучать, чтобы сделать свой аналог Авито?

    twobomb
    @twobomb
    У них есть свой блог на хабре, там они много чего описывают можете почитать. В том числе про технологии
    Ответ написан
    Комментировать
  • Как создать GUI в плагине Minecraft?

    twobomb
    @twobomb
    Время чат гпт...
    Возможно дальше написана дичь, но это не я писал.
    Для создания GUI в плагине Minecraft вам понадобится использовать API Bukkit/Spigot, который предоставляет необходимые инструменты для работы с интерфейсами пользователя.

    Пример создания GUI без возможности вытаскивания вещей и с поддержкой HEX цветов:
    public class ExampleGUI implements InventoryHolder {
    
        private Inventory inventory;
    
        public ExampleGUI() {
            // Создаем GUI с 27 ячейками и заголовком "Пример GUI"
            this.inventory = Bukkit.createInventory(this, 27, ChatColor.translateAlternateColorCodes('&', "Пример GUI"));
            // Добавляем предметы в инвентарь
            inventory.addItem(new ItemStack(Material.DIAMOND), new ItemStack(Material.GOLD_INGOT), new ItemStack(Material.IRON_INGOT));
        }
    
        @Override
        public Inventory getInventory() {
            return inventory;
        }
    
        public void openGUI(Player player) {
            // Открываем GUI для игрока
            player.openInventory(inventory);
        }
    
        @EventHandler
        public void onInventoryClick(InventoryClickEvent event) {
            // Отменяем возможность вытаскивания предметов из GUI
            if (event.getInventory().getHolder() instanceof ExampleGUI) {
                event.setCancelled(true);
            }
        }
    }

    Тута сломался чат пришло перегенрить и он выдал еще один альтернативный код...

    public class MyPlugin extends JavaPlugin implements Listener {
    
        private Inventory myGui;
    
        @Override
        public void onEnable() {
            // создание GUI
            myGui = Bukkit.createInventory(null, 9, "My GUI");
    
            // добавление предметов в GUI
            ItemStack item = new ItemStack(Material.DIAMOND);
            ItemMeta meta = item.getItemMeta();
            meta.setDisplayName(ChatColor.GREEN + "Diamond");
            item.setItemMeta(meta);
            myGui.addItem(item);
    
            // регистрация обработчика событий
            getServer().getPluginManager().registerEvents(this, this);
        }
    
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event) {
            if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
                // открытие GUI при нажатии правой кнопки мыши на блоке
                event.getPlayer().openInventory(myGui);
            }
        }
    }

    В этом примере создается GUI, содержащий один предмет - алмаз, и открывается при нажатии правой кнопки мыши на блоке. Обратите внимание, что в примере не предусмотрено перемещение предметов в инвентаре.


    Чтобы изменять/получать NBT у сущности, можно использовать классы NBTTagCompound и NBTTagList из библиотеки NBT. Например, чтобы установить NBT тэг "MyTag" у сущности "entity", можно использовать следующий код:
    NBTTagCompound nbt = new NBTTagCompound();
    nbt.setString("MyTag", "Hello world!");
    ((CraftEntity) entity).getHandle().load(nbt);

    А чтобы получить значение NBT тэга "MyTag" у сущности "entity":
    NBTTagCompound nbt = ((CraftEntity) entity).getHandle().save(new NBTTagCompound());
    String myTagValue = nbt.getString("MyTag");
    Ответ написан
  • Как остановить код в python, когда он выполнил условие?

    twobomb
    @twobomb
    def gen(c):
        for d1 in range(10):
            for d2 in range(10):
                for d3 in range(10):
                    min_d4 = max(0, d1 + d2 + d3 - 18)
                    max_d4 = min(9, d1 + d2 + d3)
                    for d4 in range(min_d4, max_d4 + 1):
                        min_d5 = max(0, d1 + d2 + d3 - d4 - 9)
                        max_d5 = min(9, d1 + d2 + d3 - d4)
                        for d5 in range(min_d5, max_d5 + 1):
                            d6 = d1 + d2 + d3 - d4 - d5
                            if 0 <= d6 <= 9:
                                print(f'{d1}{d2}{d3}{d4}{d5}{d6}')
                            c-=1
                            if c <= 0 :
                                return
    
    cnt = int(input('Введите количество счастливых билетов'))
    
    gen(cnt)
    Ответ написан
    Комментировать
  • Как сделать движение за курсором?

    twobomb
    @twobomb
    Чё сложного то, про rotate не слышали?

    p.s. вторую координату нужно брать центр картинки а у меня от края, поэтому чуть криво, ну сами прибавите + width/2 и +height/2...
    Ответ написан
    Комментировать
  • Как смягчить повороты объекта?

    twobomb
    @twobomb
    Ну естественно откуда там плавность если точки стоят друг возле друга и соеденены прямыми линиями.
    Вам нужно вашу линию преобразовывать в набор квадратичных или кубических кривых безье.
    И двигать нужно присваивая напрямую координаты получаемые из функции которая возвращает координату точки на кривой безье в определенном deltaT, и deltaT двигать одним шагом ну или если нужно делать ускорение,то плавно увеличивать шаг deltaT.
    P.S. Когда-то делал нечто подобное на канвасе, можешь выдрать себе функции получения точки на кривой и функцию интерполяции между двумя 4х точечными кривыми
    Ответ написан
    4 комментария
  • Почему анимация получается не плавной?

    twobomb
    @twobomb
    Ты имеешь ввиду залупленная анимация? Всего скорее потому-что по умолчанию юнити делает сглаженную кривую для точек анимации, открой кривые своей анимации выдели все точки нажми пкм и выбери линейную интерполяцию.
    Ответ написан
  • Почему методы без await исполняются последовательно?

    twobomb
    @twobomb
    Ну если при отправке http запроса вы используете какой-то его асинхронный метод, то да поток не блокируется, потому-что тот метод выполняется на другом потоке, а если вы в своей асинхронной функции будете использовать синхронные методы работы с http запросом, то и поток ваш будет блокироваться при их использовании.

    Вообще как мне кажется эти async,await добавлены больше для удобства и простого отлавливания исключений возникающих в методах выполняющихся на других потоках.
    Если раньше мне нужно было писать что-то типа такого:
    private void Button_Click(object sender, RoutedEventArgs e){
                var t =  new Task(() =>{
                        //дейтсвия выполняющиеся в другом потоке
                        Thread.Sleep(1000);
                });
                t.ContinueWith(new Action<Task>((task) =>{//вызываем по завершению работы таски
                    Dispatcher.Invoke(new Action(() =>{//вызываем в основном потоке, потому-что обращения к gui элементам может быть только через него
                        try{
                            if (t.IsFaulted)//если у нас возникло исключение в нашей первой таске вызываем его здесь что уловить его тут и обработать
                                throw t.Exception;
                            textblock.Text = "my text";
                        }
                        catch (Exception exception){
                            Console.WriteLine(exception);
                        }
                    }));
                }));
                t.Start();
            }


    То сейчас достаточно так:
    private async void Button_Click(object sender, RoutedEventArgs e){
                try{
                    await Task.Run(() =>{
                        //дейтсвия выполняющиеся в другом потоке
                        Thread.Sleep(1000);
                    });
                    textblock.Text = "my text";//и мы волшебно продолжаем выполнение в главном потоке
                }
                catch (Exception exception){//будет вызван даже если возникнет исключение в таске
                    Console.WriteLine(exception);
                }
            }


    Ну если вам нужно выполнить сразу несколько методов асинхронно и ждать их выполнение через await можно сделать так
    List<Task> tasks = new List<Task>();
    tasks.Add(Task.Run(() =>{
    	Thread.Sleep(1000);
    	Console.WriteLine("1");
    }));
    tasks.Add(Task.Run(() =>{
    	Thread.Sleep(1000);
    	Console.WriteLine("2");
    }));
    tasks.Add(Task.Run(() =>{
    	Thread.Sleep(1000);
    	Console.WriteLine("3");
    }));
    await Task.WhenAll(tasks.ToArray());
    Console.WriteLine("continue");
    Ответ написан
    Комментировать
  • Как проверить имеет ли сторее приложение фокус?

    twobomb
    @twobomb
    [DllImport("user32.dll")]
            private static extern IntPtr GetForegroundWindow();

    IntPtr HWND = GetForegroundWindow();
    string appname = Process.GetProcesses().First(p => p.MainWindowHandle == HWND).ProcessName;
    Ответ написан
    1 комментарий
  • Как сделать так чтобы змейка появлялась с нулевой координаты а не с один блок справа?

    twobomb
    @twobomb
    Поставьте код
    var head = {
          x: px,
          y: py,
        };
        snake.unshift(head);

    после
    if (px >= canvas.width) {
          px = 0;
        }
        if (px + box < 0) {
          px = canvas.width;
        }
        if (py >= canvas.height) {
          py = 0;
        }
        if (py + box < 0) {
          py = canvas.height;
        }

    Потому-что у вас всё по китайски, вы сначала делаете движение,потом добавляете, а потом уже делаете проверки. А нужно все наоборот.
    Использование setInterval для gameLoop - зло, никогда так не делайте. Используйте requestAnimationFrame или setTimeout на худой конец.
    И вообще структура ужасная не читабельно. Разделите отдельно фукнция просчет физики, отдельно рендеринг не смешивайте и вызывайте в gameloop по порядку всё.
    Ответ написан
    Комментировать
  • Как из строки сделать array?

    twobomb
    @twobomb
    foreach (var i in JArray.Parse(reader.ReadToEnd())){
                    Console.WriteLine(i["DateCreate"]);
    ....
                }
    Ответ написан
    Комментировать
  • Как дать юзеру возможность редактировать столбец А на листе Лист1?

    twobomb
    @twobomb
    Нажимаете рецензирование, разрешить изменение диапазонов выберите диапазоны.
    Далее выберите защитить лист и если необходимо установите пароль
    Ответ написан
    Комментировать
  • Как передать в текст кода переменную при динамической компиляции?

    twobomb
    @twobomb
    string code = File.ReadAllText(@"MyCompil.cs");
                code =code.Replace("hello", "Hi!");

    Ну или в args передавать непосредственно при запуске приложения параметрами...
    Ответ написан
    3 комментария
  • Как в зависимости от даты автоматически закрашивать ячейки в гугл с даты начало до конца?

    twobomb
    @twobomb
    Нажимаете на заливку, выбираете "условное формативание" в правилах форматирования "Дата после" ну и ниже цвет
    Ответ написан
    Комментировать
  • Как работает преобразование времени в Python?

    twobomb
    @twobomb
    Неизвестно.
    По сути здесь время переводят из наносекунд в милисекунду а потом из милисекунд в секунды.
    А остаток просто ограничит это 60 секундами. По идее такой таймер может показать неверное время и чем больше времени выполняется тем больше вероятность неверных значений
    P.S. Например если
    start = 50
    end = 10
    То результат будет -40, а должен быть 20 или 80 или 140 или сколько минут там у нас выполняется что-то....
    Ответ написан
    Комментировать
  • Как можно заставить этот скрипт работать 3 секунды?

    twobomb
    @twobomb
    function wrapperToggleConfetti(){
      toggleConfetti();  
      setTimeout(toggleConfetti,3000);
    }

    <button type="button" onclick="wrapperToggleConfetti()">Конфетти</button>
    Ответ написан
    Комментировать