BITS at Night
20 августа
PreludeHorror — игра сверху вниз?Хорошо, я думал о Bits Night, многопользовательской игре ужасов, основанной на освещении.
- Во-первых, это многопользовательский шутер с видом сверху. Эту часть легко сделать с помощью узла.
- Что касается карты, я действительно не знаю дизайна, так что это не в моей лиге разрабатывать ее, поэтому Google Earth + некоторое редактирование могут сделать вас хорошая карта.
- Тогда нам нужно много темноты, но пользователь может включить свет фонарика и немного передвигаться.
- < li>Значит, есть другие игроки и монстры. Самым интересным режимом игры будет королевская битва. А пока давайте просто: 1 комната. Игроки могут убивать друг друга, а монстры — это боты.не нападайте на людей.
- Базовая система движения сверху вниз
- Меню для входа в игру
- Обновление координат на узле (попробуйте полномочия сервера)
- Заставьте других игроков появляться и исчезать.
- карта со стенами - можно сделать позже в любое время
- Освещение, фонарик и еще много чего
- ИИ монстров — случайным образом появляется и атакует вас.
- Jumpscares
- Система королевской битвы (ограничения на присоединение и количество живых)
Хорошо, выглядит нормально. Думаю, я могу начать. Я создам папку на рабочем столе и репозиторий
1. Базовая система движения сверху вниз. Случайная дешевая карта со стенами и игроком.- Нарисуйте несколько стен и создайте круглый объект игрока, например, с пистолетом или факелом.
Хорошо, важный момент в кодировании… .. не зацикливайтесь ни на чем, кроме текущей цели. Это все, что имеет значение.
- Я думаю, это нормально.
- Поэтому я интегрировал систему столкновений «Стены», но она не совсем хороша. Парень застревает в стенах. Поэтому я пытаюсь создать систему, которая возвращает игрока туда, откуда он пришел.
- У меня есть массив старых значений координат. Значит, всякий раз, когда игрок застревает в стене, я думаю, это вернет его обратно?
- Или подождите, если стена близко, оттолкните парня от стены. < /ul>var move = Keyboard_check(ord("W")) - Keyboard_check(ord("S")) скорость = 5*движение яf(point_distance(x,y, mouse_x, mouse_y) > 30){ направление = point_direction(x,y, mouse_x, mouse_y); } if(position_meeting(x + lengthdir_x(скорость, направление),y + lengthdir_y(скорость, направление),oWall)){ //столкновение со стеной - нет свободы в угле изображения, только в направлении скорость = 0 }еще{ //не сталкиваемся со стеной image_angle = направление; }
- Наконец-то это работает!. Это раздражало. И я думаю, что сейчас самым важным будет камера.
- Это всего лишь шаблон, поэтому я не думаю, что так важно много об этом писать
- Просто медленная интерполированная камера
- Поэтому я добавил шрифт, сделал несколько кнопок, текст, поле для вашего имени и все такое.
- Окей, это мило
- Итак, в основном репозитории я создаю папку с именем server для проекта узла
- Затем стандартный материал сервера веб-сокетов< /li>
- Шаблон асинхронной сети
- Итак, в oMenu после того, как парень нажмет «ИГРАТЬ», я собираюсь сообщитьсерверу «create_me»
- Итак, основная часть — это массив игроков, в котором хранятся все игроки. Итак, здесь будут все наши свойства игрока. x, y, имя, идентификатор и все такое.
- Еще несколько свойств, которые мы добавим позже, включен ли torchLight?
- Мы также сообщаем новичку и всем остальным на сервере уже существует кто-то новый
- Я хочу сделать это с помощью сервера, чтобы у нас был хороший авторитет, но поскольку у нас есть стены, которым я не могу доверять…< /li>
- По сути, клиент будет отправлять последние координаты.
- Я создал глобальную переменную, которая будет храниться независимо от того, включен фонарик или нет< /li>
- Я также добавил атрибут угла и факела здесь, в информации об узле игрока.
- Мне нужно рассказать каждому игроку о каждом игроке. Поэтому я создам для этого новую функцию, которая будет повторяться каждые 16 мс или около того.
- Эта функция собирает информацию об игроках, помещает ее в словарь и отправляет этот словарь в всем
- Теперь нам нужно обновить координаты и угол этих игроков в соответствии с соответствующими экземплярами oEnemy
- Когда webgl отключен, fps хороший, но после 3 oEnemies игра не обновляет свои позиции.
- Когда webgl установлено значение «Обязательно», тогда частота кадров низкая, но oENemies обновляются. Вот автоматическое определение.
- Когда для webgl установлено автоматическое определение, в Chrome низкая частота кадров, но игроки обновляются. Однако в Edge все работает отлично.
- Может быть, это то аппаратное ускорение, которое я отключил в Chrome? Давайте попробуем включить его и поиграть.
- Нет, хуже. Я установил половину половины и позволил увеличить частоту обновления состояния nodejs.
- Итак, я собираюсь использовать динамическое освещение. Теперь я думаю, что для этого мне нужно разбираться в поверхностях и многом другом.
- Хорошо, я прослушал руководство и во многом понял. Мы рисуем источники света (без тени) в виде многоугольника.
- На самом деле сначала свет, а затем многоугольник. для тени
- Хорошо, я почти понял урок Шона Сполдингса.
- Я последовал этому руководству, и на самом деле все было не так уж и плохо. Это конечный результат, и это только начало.
- Итак, в объекте oLighting вы можете заставить разные источники света работать для разных объектов, и это действительно здорово. < /ul>
- Нам нужно сообщить серверу, что мы выстрелили.
- Здесь мы отслеживаем каждый шаг пули в направлении, в котором она была выпущена, и проверяем, попала ли она в какого-либо игрока.
- Он возвращает идентификатор игрока, в которого мы попали, или -1, если мы никого не попали.
- Мы делаем это, используя перпендикулярное расстояние от линии, по которой была выпущена пуля. ul>Используем это, чтобы убить застреленного игрока
- Под убийством я имею в виду уничтожение веб-сокета.
- По сути, мы уничтожаем этого игрока для всех остальных.< /li>
- Как и любое другое свойство, такое как x, y, angular, теперь мы также будем использовать Health, обозначаемое H в nodejs.
- И когда игрок при попадании пули мое здоровье уменьшается на 30.
- Я также нарисовал полоски здоровья для всех, чтобы это было легче увидеть.
- Поэтому, когда вы получаете дозу адреналина, повышается уровень адреналина, и вы можете видеть немного больше, чем обычно.
- Итак, освещение – это управлениев oLighting, там я буду вносить изменения.
- Так что тьма всегда сбрасывается. Как только здоровье изменится, позвольте мне изменить темноту на 0,7 или что-то в этом роде.
- На этапе oPlayer
- Также шейдер мигает .
- Призраки могут видеть в темноте
- У призраков нет шкалы здоровья или концепции здоровья. Они исчезают, если на них падает свет примерно на 300 мс. Возможно, им действительно нужно какое-то здоровье, но шкала здоровья не отображается.
- Призраки могут проходить сквозь стены.
- Призраки могут напугать игроков. и убить их.
- Как тело игрока. «P», «G», «D»
- Игрок, призрак или мертвый (как будто вышел из игры)
- Как призраку не показывается полоса здоровья или стены….
- Изменения код трассировки пули. Стреляйте только в том случае, если человек П.
- По сути, если свет падает на призрак примерно на 1 секунду, призрак должен умереть.
- Для этого мы можем проверить, находится ли призрак (считающийся точкой) внутри треугольника, состоящего из игрока и нескольких огней.
- Итак, сначала давайте перенесем происхождение на игрока, который ловит призрака li>
- Итак, тета — это направление игрока.
- P1 и P2 — это конечные точки изотреугольника, который я пытаюсь построить. делать.
- Поэтому нам нужно проверить, находится ли призрак внутри <0,0> , P1 и P2.
- Давайте сделаем функция, которая делает это за нас
- Как найти P1 и P2? Предположим, что желтый радиус (диапазон факела) равен 80.
- Итак, P1 и P2 равны R e^(i theta +/- 40)
- Чтобы проверить, действительно ли точка находится в треугольнике, вы можете выполнить геометрию координат. L1, L2, L3 должны быть противоположными знаками для призрачной точки как точки треугольника, противоположной стороне
- поэтому я нашел этот алгоритм в stackoverflow < /ul>bool intpoint_inside_trigon(intPoint s, intPoint a, intPoint b, intPoint c) { int as_x = s.x-a.x; int as_y = с.у-а.у; bool s_ab = (b.x-a.x)*as_y-(b.y-a.y)*as_x > 0; if((c.x-a.x)*as_y-(c.y-a.y)*as_x > 0 == s_ab) возвращает false; if((c.x-b.x)*(s.y-b.y)-(c.y-b.y)*(s.x-b.x) > 0 != s_ab) return false; вернуть истину; }
- Я внес некоторые изменения в функцию для работы в js, а Великобритания использует массивы для точек
- Затем я создал эту функцию, которая проверяет все за нас< /li>
- Эта функция проверит все фонарики от P и проверит, находится ли G внутри. Если да, то, наверное, уменьшите здоровье примерно на 30?
- Нет, уменьшайте на 1 каждые 16 мс. Итак…..в секунду пропадает 60 единиц здоровья?
- Эта часть будет очень веселой.
- По сути, если (призрак подходит очень близко к игроку) и (призрак не находится под каким-либо факелом), напугать и убить игрока
- Хорошо, это гораздо проще написать, чем я ожидал, потому что нам нужно выполнить только два условия, указанные выше… Плохо сделай это завтра
- Здесь я просто делаю описанные выше действия в коде
- Нам нужно напугать этого игрока. Поэтому сообщите клиенту GMS какое-нибудь событие, например Jumpscare.
- А сейчас я просто сделаю предупреждение, будто вас напугали
- Теперь давайте добавим в игру немного реализма.
- Игрок, которого пугают скримеры, должен по-настоящему испугаться. Я имею в виду музыку скримеров и все такое
- Давайте сначала добавим немного музыкальной темы
- Я буду использовать oCamera для всех вещей, связанных со звуком< /li>
- Воспроизводится, когда вы P, а не G
- Музыка, которую я скачал с этого сайта
- Идея состоит в том, чтобы музыка играла всякий раз, когда поблизости появляется призрак. < /ul>
- Это своего рода предупреждение игроку, потому что у призраков много преимуществ.
- Хорошо, сначала давайте сделаем музыку Jumpscare
- О боже, это намного лучше.
- Мне нравится, как ребята в комментариях говорят: я, как призрак, понимаю это.
- Хорошо, музыка причудлива, но с призраком все в порядке… посмотрим< /li>
- Звуки я взял с сайта gatdamn.io, а также код оттуда. Я просто собираюсь это сказать. Звуковая система в этой игре — шедевр.
- По сути, звук затухает в геометрической прогрессии.
- Мы хотим невидимые стены и простую простую карту.
- Я убрала стены, закрывающие центральную лужайку, это показалось слишком тесным
- точки появления, случайно сгенерированные сервером
- /если вы призрак и вас убьют, вы просто умрете! , экран смерти, тебя убили...
- уличные фонари
- лучше скример
- стрелка, чтобы показать ближайшего игрока.
- изменения карты для расчистки дорог и исправления беспорядка.
- На данный момент в узле все игроки появляются в одной и той же точке, то есть
- Поэтому я создам массив точек появления, в которых может появиться парень.
- Система появления, которая выбирает наименее населенную точку для размещения пользователя.
- Чтобы проверить, работает ли это, сначала игрок будет спауниться где-нибудь, а затем в точке, наиболее удаленной от первого игрока.
- Исправили некоторые ошибки, и да, это работает! Один парень появился в INS, другой в малакарах, затем следующий в DH2, так счастлив
- После того, как P убивает P, один P становится G, и его можно легко убить. Итак, нам нужно отправить G туда, где меньше P.
- Это означает, что я внесу небольшую модификацию функции, чтобы призраки не включались в поиск
- li>
- Также интерполяция
ion необходимо пропустить. - Поэтому я хочу, чтобы уличные фонари были разбросаны по битовой карте. Это делает его немного менее темным.
- Появилась ошибка, но теперь все в порядке.
- Количество убийств
- Количество живых и призраков
- Интерфейс смерти говорит, что вы умерли, я думаю…
- На самом деле я не подсчитывал убийства. Мне нужно сделать один
- Каждый раз, когда P уничтожает G или P , ++
- Каждый раз, когда G пугает к черту P++
- Создание нового атрибута K для убийств
- Даже на стороне GMS я использую встроенный переменный счет за ваши убийства. Для врагов это просто переменная, называемая убийствами
- P убивая P
- P убивая G
- P убивая G li>
- В функции уменьшения здоровья призраков на данный момент происходило то, что после смерти G его ws закрывалось.
- Я добавил код, чтобы просто ++ подсчитывать количество убийств убийц
- G убивает P
- Когда призрак пугает P the G необходимо получить ++ kill
- К этому моменту у нас есть своего рода забавная игра
- Когда вы в P и вас нокаутировали, вам нужно получить сообщение «Вас убил _____»
- Когда вы G, и вы в восторге, вам нужен полный экран пользовательского интерфейса, показывающий статистику игры и все такое.
- Пусть в oController будет массив global.messages
- Каждое сообщение появляется, оно длится 2 секунды и исчезает
- от 1 до 0,5 альфа в 120 кадрах
- Теперь все, что нам нужно сделать, это отправить сообщение в этот массив всякий раз, когда у нас есть сообщение для отображения.
- мы помещаем еще один массив [ «MESSAGE», 6 ]
- При этом надпись «MESSAGE» будет отображаться красным цветом в течение 6 секунд
- Это очень аккуратная и простая система.
- Когда выбивается буква P, серверу необходимо передать какое-то сообщение GMS. Сделайте это
- Чтобы G мог напугать P или P мог выстрелить P.
- В функции призраков пугают игроков Я добавляю код для этого оповещения.
- Поэтому в основном линейные оповещения будут показывать сообщение.
- Если P будет сбит еще один P
- Когда пользователь действительно мертв и ушел, на данный момент ws закрывается.
- Нам нужна другая система, где всем будет транслироваться «destroy_player».
- Но игрока пока нельзя удалять из массива player
- Хмм, честно говоря, это сложно, потому что это потребует внесения серьезных изменений.
- Это простая система камер смерти.
- Я устанавливаю будильник, когда игрок умирает, чтобы вы могли видеть экран статистики появится позже.
- Вы можете создать таблицу лидеров, если знаете, у кого сколько убийств.
- У нас есть все убийства врагов в переменной убийств. < /ul>
- Поэтому нам нужно графически отобразить это в левом нижнем углу. Я могу взять его с gatdamn.io, но давайте сделаем это с нуля, как задачу по программированию.
- Таблица лидеров
- Мини-карта
- Экран смерти, вас убил… li>
- Тестирование
- Комнаты
- Нам нужно помечать пули по тому, кто в них стрелял, чтобы мы могли уничтожать пули при правильных столкновениях
Я изменил значения, и теперь движение выглядит очень красиво 🙂
Результатhttps://s3-us-west-2.amazonaws.com/secure.notion-static.com/df4e91ba-e974-4132-8907-01d1e35e71a8/screen_rec.mp42.Меню для входа в игру
- < li>Я сделаю новую комнату. Стандартный номер. Просто вводит ваше имя и отправляет вас в многопользовательский режим.
3. Обновление координат на узле. Настройка узла js-сервера
Далее давайте настроим коммуникацию на основе событий.
Попросите сервер создать игрока//МЕРТВЫЕ ИГРОКИ МОГУТ БЫТЬ ПРИЗРАКАМИ — ок, моя мама пошутила об ошибках движения стен, и это позволило мне получить очень крутую механику Strong>
Королевская битва + ужас: мертвые игроки становятся призраками и могут преследовать и убивать существующих игроков. Мертвые призраки — это всего лишь зрители.
Отправка обновлений на сервер
Результат — обновление сервера https://s3-us-west-2.amazonaws.com/secure.notion-static.com/35ddc11e-f23e-4ab6-a6cd-fb0fa9f4c4f9/coordinates_updating.mp4
Итак, я запускал это на хроме, fps был отстойным. Эдж был в порядке. Я думаю, это как-то связано с… Хорошо, я отключил WebGL, все работает нормально.
4. Заставлять других игроков появляться и исчезать. Отправка обновлений позиций с узла <р>
Отчет об ошибке:
Да, я был прав.т… Думаю, движение могло бы быть более плавным. Давайте усилим интерполяцию.
Ух ты, это чертовски гладко. Я починил это. Я изменил его с 50 мс на 16 мс.
Результатhttps://s3-us-west-2.amazonaws.com/secure.notion-static.com/597ee731-a41b-45b0-94a7-5eaa5b78a5ff/ координаты_updating.mp4Система освещения кажется крутой… Я сделаю это завтра. Не думай об этом, черт возьми, сейчас. Ваш прогресс на сегодня был довольно хорошим.
23 августа
5. Система освещенияСначала в oLigthing рисуется световой спрайт. Затем стены
///посмотри на Джобо с Шоном Сполдингом
24 августа
Хорошо, мне нужно увидеть Джобо с Шоном Сполдингом видео. Если мои системы не работают, я буду использовать это расширение.
Хорошо, мои системы не работают, и я собираюсь использовать это расширение👏👏👏
Даже это могло бы сработать p>https://gamemaker.io/en/blog/coffee-break-tutorial-simple-lighting-gmlJobo Lighting System
Хорошо, эта система трash в html5 и веб-сокетах в основном использует h5, поэтому я не могу, черт возьми
Официальное простое руководство GMS по системе освещения
Я также могу добавить уличные фонари и все такое
Result of Lighting и мультиплеерhttps://s3-us-west-2.amazonaws.com/secure.notion-static.com/385b432f-6c1a-401d -8223-fda2ea74bf49/multiplayer_with_lights.mp46. Концепция оружия
Так что, что касается динамики стрельбы, это будет частично управление сервером, так что это хорошо, не так ли? Я нарисую простой спрайт пули и добавлю скорости.
Создание пулиРезультат выглядит примерно так
Событие для отправки на сервер.Управление сервером (Часть 1 – сообщение другим игрокам, что в кого-то стреляли)
Как GMS выглядит так, будто игрок выстрелил гильзой «bullet_shot»: с(oEnemy){ if(clientId == real(realData[?"shooter"])) ){ //создаем пулю var Bullet = instance_create_layer(x +lengthdir_x(13,direction -85), y+lengthdir_y(13,direction-85),"Instances",oBullet); скорость пули = 10; Bullet.direction = image_angle; пуля.image_angle = пуля.направление; перезарядка = 20; //анимация отдачи x -= lengthdir_x(10, направление) y -= lengthdir_y(10, направление) } } перерыв; <р> 7. Авторитетные пули
Сейчас пули ничего не делают. Нам нужен код, который отслеживает путь пули и проверяет, попала ли она в кого-нибудь. Это также должно быть сделано централизованным органом, то есть сервером узла.
shootBullet FunctionfunctionshootBullet(shootersId) { вар кадр = 0 вар init_x = 0; вар init_y = 0; угол вар = 0; for (пусть я в игроках) { if (players[i].id == ShootersId) { init_x = игроки[i].x; init_y = игроки[i].y; угол = игроки[i].A; } } //отслеживаем траекторию пули в то время как (кадр <400) { var current_x = init_x + Math.sin(3,1415/180 * угол); var current_y = init_y - Math.sin(3,1415/180 * угол); //у нас есть текущие координаты пули. Теперь проверьте, не сталкивается ли он с кем-нибудь. for (пусть я в игроках) { var distance = Math.sqrt((current_x - player[i].x) ** 2 + (current_y - player[i].y) ** 2); если (расстояние < 16) { if (players[i].id != ShootersId) { //убедимся, что огонь по своим не прекращаетсяул. вернуть игроков[i].id; //идентификатор парня, в которого стреляли } } } } вернуть -1; ///-1 означает, что пуля еще ни в кого не попала }ох, черт, я забыл закрыть цикл while в функции ShootBullet
……также для x это не грех…там много глупых ошибок.
РезультатыДа, игрок, которого мы стреляем, умирает! Это очень здорово, но я думаю, что мы могли бы добавить переменную здоровья. Один выстрел, чтобы убить игрока, кажется слишком глупым
8. Health
25 августа
Добавление эффектов для здоровья9. Призраки: Различия между призраками и обычными игроками
Добавление атрибута body
Спрайт призраков
Это то, что я создал в aseprite. Да, я знаю, что самые популярные просмотры для этого — отстой…
Окончательный результат после интеграции Ghosts💜💜https://s3-us-west-2.amazonaws.com/secure.notion-static.com/78fa7c8f-9ab1-4b8c-8158-344cae7ea429/ghosts_integration.mp4
9. Киллиng Ghosts
Итак, для убийства призраков….
26 августа
< p>Сегодня у нас не так много времени, поэтому к 11 посмотрим, сколько вы сможете сделать.Математика…Функция GhostHealthReducer
Я временно все еще показывал полосу здоровья призрака.
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d4b6ec6c -cb1b-48e5-bf92-546da57ec1ae/ghosts_elimination_by_torchlight.mp410. Призраки атакуют игроков5 сентября
Да, верно «Я сделаю это завтра»
Призрак Функция проверки на паникуРезультатhttps://s3-us-west-2.amazonaws.com/secure.notion-static.com/f68d270f-312c-4d74-88de-34945933ccf5/jumpscares.mp4
11. Скэри и причудливая музыка
20 сентября
- < li>Я еще нарисовал призрака-джампера, там только 1 проблема. Это не страшно
Мне действительно пора сделать карту
12. Карта BITS и конфигурация стен21 сентября
Я не хочу хочу тратить на это слишком много времени. Его графика, братан.
Размещение на стенеЭта часть может оказаться очень сложной. Позвольте мне изменить размер холста, чтобы вырезать NAB?… Нет, все в порядке. Просто посмотрите, как выглядит размещение на стене
После утомительной работы. Вот блин и результат
22 сентября
Хорошо, теперь нам нужно заняться производством. Вам нужны
13. Система случайного появления, система появления уличных фонарей в Node.js
- < li>Нгл, это было весело. Теперь поместите это для спавна игрока.
Я также добавил эффект мерцания
14. Основные исправления пользовательского интерфейса.
Это будет следующий шаг.
23 сентября — 2 сеанса Pomodoro пытаются закончить это дело
Счетчик убийствДобавление к убийствам
Мы должны делать это в каждом конкретном случае
Вещи, которые отображаются в режиме чтения всякий раз, когда появляется предупреждение
24 сентября.
Сервер отправляет сообщения.Должен ли у нас быть режим наблюдателя или нет? Я думаю, нам следует
Итак, везде нам нужно добавить что-то вроде: если тело игрока == «D», тогда сделайте это, сделайте это
В функции уменьшения здоровья призраковКак GMS справляется с этим
26 сентября
15. Таблица лидеров и мини-карта30 сентября
Как прошли последние 4 дня? идти? Наверное, мне нужно небольшое расширение.
Что осталось?
Теперь дополнительные возможности
Пожалуйста, скопируйте это с gatdamn.io
Я сделал. Это было немного глючно, и я попытался это исправить. Ключевое слово опробовано.
Мини-картаТот же код, что и из gatdamn.io
16.. Хостинг и играбельностьБлин, чувак, всегда оставь это до конца. Хотя я не против.
Пожалуйста, примите меня на Firebase.
Ура, учебник уже готов.
3 сентября
< p>Столько времени ушло на решение ошибок эффектов и ошибок таблицы лидеров. Я даже не знаю, черт возьми, работает ли это. Мне нужно сделать зудящую страницу быстройПули
//если ты призрак и тебя убьют, ты просто умрешь! , экран смерти, вас убил…
//лучший скример
Как скачать BITS at Night через торрент
Всего несколько простых шагов:
- Устанавливаем программу μTorrent, через которую мы будем скачивать торренты
- Выбираем и скачиваем подходящий торрент-файл репака BITS at Night
- Двойным кликом открываем скаченный файл, программа μTorrent запустится автоматически и предложит выбрать место для сохранения дистрибутива.
- После того как репак скачается, запускайте его. Начнется установка и... это все, приятной игры!