• Как избавиться от эффекта рыбьего глаза?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    5fe9fe587564d777784861.png

    Посмотрите на картинку. Вы для определения видимой высоты стенки в текущей точке используете расстояние от зрачка до пересечения луча с данной точкой стены, это и дает эффект рыбьего глаза.

    Чтобы это исправить вместо данного расстояния вам надо использовать расстояние от точки пересечения до перпендикуляра к направлению взгляда.
    Смотрите сноску в верхнем правом углу на рисунке.
    Где:
    A - камера
    B - точка пересечения луча с преградой
    Ось Y - направление взгляда
    Ось X - перпендикуляр к направлению взгляда
    α - угол между текущим лучем и осью x
    R - расстояние от камеры до точки пересечения луча с преградой
    l - расстояние от точки пересечения луча с преградой до перпендикуляра к направлению взгляда

    Вот пример https://jsfiddle.net/lastuniverse/0t1jo8cr/4/ , в нем есть некоторые искажения, возникающие из-за неправильного расчета length. Дело в том, что ваш алгоритм не находит точные координаты пересечения луча с гранью блока, а находит некую точку внутри блока, что так же добавляет искажения.

    Вот еще вариант https://jsfiddle.net/lastuniverse/6nrsL28g/8/ (переделал из ответа на вопрос Почему данный код работает неправильно? от товарища twobomb ). В нем эффект рыбьего глаза полностью нивелирован (смотрите функцию drawGame(...) ). Как бонус - данный пример работает в несколько десятков раз быстрее, и позволяет ставить блоки нестандартного размера)))

    5fea7f268ea1d386247037.png
    Ответ написан
  • Почему событие срабатывает несколько раз?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    у вас 2 косяка в коде.

    Первый вы поняли сами, каждый раз при коннекте вы запускаете новый слушатель события "end", и даже если событие возникнит 1 раз, а слушатели стоят как once то все равно сработает каждый из уже запущенных, но еще ни разу не сработавших слушателей.

    Второй косяк - это то что вы не завершаете запущенный setInterval, который каждую секунду продолжает уменьшать таймер, даже после того как таймер станет меньше нуля. В результате, когда таймер достигает нуля у вас начинает срабатывать условие if(this.timer <= 0) на каждый тик
    Ответ написан
    4 комментария
  • Как создать свой вариант конструктора Date?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Знатно накосячил из-за невнимательности.
    тоже верные варианты))

    Тут такое дело, встроеная Date не является классом как таковым, поэтому все неверные варианты убрал под спойлер

    Был не прав, варианты рабочие)))
    class ServerDate extends Date {
        construcror(...args) {
            super(...args);
            if (args.length === 0) {
                // если аргументов конструктора нет то получаем время от сервера
                fetch("url роутера на сервере отдающего время в миллисекундах")
                    .then((response) => {
                        return response.json();
                    })
                    .then((data) => {
                        this.setTime(data.time)
                    })
    
            }
        }
    }
    
    const date = new ServerDate();


    !!!!! возможно будет ругаться на super(...args);. Если да, то можно попробовать сделать так
    class ServerDate extends Date {
        construcror(...args) {
            // super(...args);
            if (args.length) {
                this.setTime(Date.now());
    
            }else{
                // если аргументов конструктора нет то получаем время от сервера
                fetch("url роутера на сервере отдающего время в миллисекундах")
                    .then((response) => {
                        return response.json();
                    })
                    .then((data) => {
                        this.setTime(data.time)
                    })            
            }
        }
    }
    
    const date = new ServerDate();
    
    console.log(date)




    Верный вариант мы с вами сейчас сделаем в комментариях.

    Но сразу предупреждаю, это откровенный костыль, не делайте так)))
    !!!!! Кроме того, такие функции как Date.now() и ей подобные по прежнему будут работать со временем клиента
    !!!!! А так же до тех пор пока идет запрос к серверу, дата полученная этим способом const date = new ServerDate(); будет содержать время клиента
    Ответ написан
  • Как правильно посчитать кол-во символов в переменной?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    var str = `tes
    
    ttt`;
    
    var str1 = str.replace(/\s/g,''); // удаляем все пробельные символы (побелы, табуляцию, переход на новую строку)
    
    console.log(str.length);
    console.log(str1.length);
    Ответ написан
    5 комментариев
  • Как найти сумму положительных элементов массива?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    let array = [-2, 4, -10, 8];
    let summ = array.reduce((a,v)=>v>0?a+v:a, 0);
    Ответ написан
    9 комментариев
  • Что делать если тайлы слишком маленькие?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    1. искать в гугле 2d game arts for free
    2. качать нужные тайлсеты
    3. вставить в их вашу прогу и использовать
    Ответ написан
    Комментировать
  • Как получать случайные уникальные числа из заданного интервала?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    function makeRandomizer([ min, max ]) {
      // сортировка может занять несколько больше времени чем обычно.
      const numbers = [...Array(max - min + 1)].map((n, i) => min + i).sort(()=>Math.random()<0.5?-1:1);
      return () => numbers.shift() ?? null;
    }
    Ответ написан
    Комментировать
  • Какой пакет npm использовать для бота?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    https://www.npmjs.com/package/puppeteer
    если же сайт достаточно простой, не SPA или подобное, не тянет кучу данных которые рендерит на клиенте то можно и с помощью https://www.npmjs.com/package/node-fetch
    Ответ написан
  • Ошибка типа: Cannot read property 'src' of null?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    вот эта строка
    const url = await page.$("div.post-container picture img");


    не находит элемента, удовлетворяющего div.post-container picture img
    и возвращает значение null. В результате url = null
    Ответ написан
    4 комментария
  • Как сделать проверку почты в таком формате xxx@xxx.xx?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    вот на хабре почитайте, если останутся вопросы - отвечу
    Прекратите проверять Email с помощью регулярных вы...
    Ответ написан
    Комментировать
  • Как решить задачу по Js с логическими и булевыми операторами?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    var numberVolunteers = 123456;
    var membersInGroup = 5;
    var out = (membersInGroup-numberVolunteers%membersInGroup)%membersInGroup;
    Ответ написан
    Комментировать
  • Как заменить числа на слова через map?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    var str = '5 80 75 30 85 90 10 30 0';
    var out= str.split(/ /).map(n=>(n=+n,n<10?`${n}`:n<30?'Третий':n<50?'Второй':n<100?'Первый':`${n}`)).join(' ');
    console.log(out); // 5 Первый Первый Второй Первый Первый Третий Второй 0
    Ответ написан
    Комментировать
  • Как сделать переменную из Socket.io доступной везде?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    если доступной нужно сделать переменную (не значение переменной) то так
    var sharedData;
    socket.on('Название события', data => {
      sharedData = data
    })


    Но подозреваю что вам нужно сделать доступной не саму переменную а полученное внутри обработчика значение data?

    Если вам нужен именно второй вариант, то ответ НИКАК))))

    НО:

    1. вы можете сделать видимость ее доступности:
    (async () => {
      async function getData(){
        const promise = new Promise(function(resolve, reject) {
          socket.on('Название события', data => {
            resolve(data);
          });
        });
        return promise;
      }
      var sharedData = await getData();
    
      // тут в sharedData будет доступно значение из data
    
    })();


    2. или же вы можете в нужных местах (в нескольких) ловить событие 'Название события', и при его получении обрабатывать data.

    3. есть и другие варианты, все они связанны с асинхронностью, и так или иначе позволяют правильно и своевременно обработать data поступившую посредством события 'Название события'
    Ответ написан
  • Какими средствами можно удобно и быстро рисовать изометрические тайлы со сдвигом назад?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    такие тайлы?
    grass.flowers.v0.01.pnggrass.usual.03.pngsand.03.pngsand.grass.v0.03.png

    примеры компоновки
    5fa40d4a91088638688812.jpeg
    5fa40d57b9d44457809720.jpeg


    Если да, то эти я делал в blender-e (при рендеринге включить изометрическую проекцию)
    вот blend файл тайла с травкой
    Ответ написан
    Комментировать
  • Как прервать запрос в mongoose?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    // мой chatId (я админ)
    const myId = 1396346856;
    // chatId собеседника
    let currentInterlocutorId;
    
    bot.on('message', msg => {
        //chatId который пишет боту
        const chatId = msg.chat.id
    
        // если сообщение от меня (хозяина бота)
        if (chatId === myId) {
            // не будем мучать БД при каждом моем сообщении поэтому сначала проверим, похоже ли то что я написал на ID пользователя
            if (/^\d+$/.test(msg.text)) {
    
                /*если сообщение которое я ввел равно chatId пользователя из базы данных, то следующие сообщения будут отправляться этому пользователю*/
                Person
                    .findOne({ chat: msg.text })
                    .then(person => {
                        currentInterlocutorId = msg.text;
                        bot.sendMessage(mayId, 'Соединение установлено')
                    })
                    .catch()
            }
    
            // если я (хозяина бота) ввел "stop" общение прекращаем
            if (msg.text === "stop") {
                bot.sendMessage(mayId, 'Соединение разорвано');
                bot.sendMessage(currentInterlocutorId, 'Я от тебя устал, не пиши мне больше!!!');
                currentInterlocutorId = undefined;
            }
    
        }
    
        // если собеседник был выбран
        if (currentInterlocutorId) {
            // если пишу я
            if (chatId === myId) {
                bot.sendMessage(currentInterlocutorId, msg.text)
            }
            // если выбранный собеседник пишет мне
            else if (chatId === currentInterlocutorId) {
                bot.sendMessage(mayId, msg.text)
            }
    
        }
    
    
    })
    Ответ написан
    1 комментарий
  • Можно ли создать GIF из GIF + PNG/JPG на Node.JS?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    для этих целей есть консольные программы и соответствующий npm модуль для них

    сами проги:
    www.graphicsmagick.org
    https://imagemagick.org/index.php

    npm модуль
    https://www.npmjs.com/package/gm
    Ответ написан
    Комментировать
  • Как отправить данные из бекенда на фронтенд?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    есть два основных способа:
    1. запросить данные с фронта по http с помощью XMLHttpRequest или Fetch. Для этого способа необходимо иметь на сервере ендпоинт, умеющий формировать и отправлять данные на соответствующий ему запрос.
    2. отправить данные по желанию сервера по заранее установленному клиентом websocket соединению. Для этого способа существует множество различных подходов, например:
    - самый простой (но не лучший). На клиенте стоит слушатель приходящих по ws собщений, который их парсит и определяет что же с ними делать дальше
    - более сложный в реализации. Шина событий, которую организовываете сами (или с использованием сторонних библиотек) (может быть организована и на ws и даже на http) В этом случае вы на сервере (или на клиенте) вызываете событие ws.emit("имя события", данные) а на противоположной стороне ловите это событие ws.on(ws.emit("имя события", (данные)=>{ тут обрабатываете полученные данные}).
    - более сложный в реализации. Та же шина событий, но с возможностью создания чегото типа каналов, на которые можно подписывать определенные группы клиентов)
    Ответ написан
    2 комментария
  • Как менять текст кнопок в TelegramBotApi?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    тут написано как
    https://core.telegram.org/bots/api#editmessagerepl...

    а как этим воспользоваться уже сильно зависит от используемого языка программирования и библиотеки для доступа к telegram api
    Ответ написан
  • Как вычислить время зажатия?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    вам не нужен таймер для этой цели. достаточно в момент нажатия запомнить текущее время а в момент отжатия от текущего времени вычесть запомненное.
    // переменная, в которую запоминаем время
    let pressedTime = Date.now();
    
    ...
    // при нажатии  
    pressedTime = Date.now();
    
    ...
    
    // при отжатии
    const passedTime = Date.now()-pressedTime;
    console.log("С момента нажатия прошло", passedTime, "миллисекунд");
    console.log("С момента нажатия прошло", passedTime/1000, "секунд");
    
    
    // при отрисовке внутри цикла window.requestAnimationFrame(loop);
    if( кнопка нажата ){
       const passedTime = Date.now()-pressedTime;
       style.margin = (parseInt(style.margin)+passedTime/100) + 'px';
    }


    если вам нужно более точное время чем миллисекунды то вместо Date.now() используйте performance.now()

    ну и вот еще посмотрите для реализации цикла игры https://developer.mozilla.org/ru/docs/DOM/window.r...

    вот наваял простенький вариант:
    Ответ написан
    5 комментариев
  • Как можно защитить верстку?

    lastuniverse
    @lastuniverse
    Всегда вокруг да около IT тем
    Вот еще вариант. запускаете сайт локально, и через тимвювер или аналоги предоставляете доступ к рабочему столу.
    Ответ написан
    7 комментариев