Используйте это руководство, чтобы изучить возможности RxJS и получить свою первую работу

Я заканчивал колледж. Понятия не имел, что мне построить в первую очередь. Я знал, что мне нужно что-то, чтобы показать свои навыки. Моей целевой работой был интерфейсный разработчик, поэтому в проекте необходимо было задействовать эти навыки.

Каждый работодатель увидит вашу страсть в ваших первых проектах. Вот почему вам нужно выделяться. Вам нужно потратить некоторое время, чтобы произвести хорошее впечатление с помощью игры или бизнес-приложения.

Затраченное время равно качеству проекта.

Обязательно исследуйте каждый крайний случай. Ставьте под вопрос все. Создавайте обширные тесты. Найдите людей, которые попробуют ваше приложение.

Идея

У меня возникла идея создать шутер. Что-то простое, но в то же время сложное. Мне нужно было произвести впечатление на своего работодателя, но у меня было мало времени для вложений.

Мне понравилась идея перемещать игрока слева направо при съемке объектов. Пули тоже потребуют какой-то физики. Также были нужны игровые враги, чтобы я мог продемонстрировать свои навыки ООП.

У врагов будет разная сила, некоторые будут убиты раньше. Также игрок может умереть от столкновения. Пули нужно было рендерить и удалять после того, как они попали в цель.

Казалось простым, пока я не запачкал руки.

Стек технологий

Я тоже хотел иметь какой-нибудь бэкэнд, поэтому использовал для него json-server. Хотел показать, что умею работать с REST из интерфейса. Это используется для подачи очков и выбора конфигурации игры.

Мне нужен был способ отслеживать движение игроков, столкновения и другие значимые события. Именно здесь в игру вступает RxJS. Библиотека предлагает реактивное программирование на JS, и это то, что мне было нужно. Мне нужно реагировать на постоянно меняющиеся движения игроков, столкновения, летающие пули.

Чтобы склеить все это воедино, я использовал webpack. Для размещения изменений в моем браузере я использовал webpack-dev-server. Сегодня это может быть устаревшим, со всеми новыми разработками, но это только в образовательных целях.

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

Код

Я рассмотрю здесь несколько фрагментов кода. Ссылка на репо останется внизу. Можете судить о моем коде, я не злюсь :)

Враги

Враги необходимы для любого шутера. Скелет моих врагов был создан с помощью CSS, а JavaScript давал им движение. Я выбрал самые простые формы: конус, ромб, треугольник. Разделите их на классы с особыми очками здоровья и скоростью.

export class EnemyDiamond extends Enemy {
    constructor(node)
    {
        super(node);
        this.health_points = 300;
        this.dom_element.className = "enemy enemy_diamond_fill";
    }
    startMoving(speed)
    {
        super.startMoving(speed/2);
    }
}

Чтобы они двигались по экрану, я добавил интервал, с которым они будут двигаться. Этот интервал будет взят из конфигурации, чтобы усложнить игру. После того, как враг убит или ушел с экрана, я бы удалил его из DOM.

Rx.Observable.interval(speed).subscribe(function()
        {

            TOP_OFFSET+=MOVEMENT_SPEED;
            that.dom_element.style.top = `${TOP_OFFSET}px`;

            let off_bottom_edge = TOP_OFFSET >= windowHeight - 50;
            
            let alive_and_off_the_screen = off_bottom_edge && that.health_points > 0 ;

            if(alive_and_off_the_screen)
            {
                this.unsubscribe();
                removeDomElement(that.dom_element);
                return;
            }
        });

Пули

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

Чтобы определить местонахождение пули и врага, я использовал функцию getBoundingClientRect. Если эти двое находятся в одном месте, удалите пулю, добавьте разрушение к очкам и удалите HP врага.

Игрок

Игрок перемещался слева направо с помощью обработки событий мыши RxJS. Пули стреляли нажатием клавиши пробела и перемещались из нижней части экрана в верх. После выстрела я добавил отдачу, чтобы сделать ее более реалистичной.

Класс игрока отвечал за отслеживание столкновений, счет игрока и его благополучие. После того, как игрок был убит, игра окончена, мы удаляем игрока и показываем таблицу очков.

// mouse movement handling
const mouse_move_events = Rx.Observable.fromEvent(document,'mousemove');

        let mouse_moved = (event)=>{
    
            let cursor_not_close_to_right_edge
                = event.clientX < window.innerWidth - 250;

            if(cursor_not_close_to_right_edge)
                this.dom_element.style.left = event.clientX + 50;
            else   

                this.dom_element.style.left = window.innerWidth - 200;
        
        }
        
        mouse_move_events.subscribe(mouse_moved);

Окружающая обстановка

Во-первых, вам нужно создать свою игровую среду. Это можно сделать с первой страницы, на которую вы попадаете. Введите свое имя пользователя и выберите уровень сложности. После этого можно начинать игру.

Следующая страница - игровая зона, враги начнут лететь сверху экрана. Вы всегда можете проверить свой счет и HP в верхнем левом углу. Начните перемещать игрока с помощью мыши и используйте клавишу пробела, чтобы сбивать врагов.

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

Конечный результат

Мысли и ошибки :)

Наверное, я бы больше разделил опасения, но это был мой первый проект в жизни. У меня было несколько ошибок, и их было трудно отловить из-за запутанного кода.

Тестирование - это то, чего я не делал. Это то, что я упустил, и в то время не знал, как писать тесты. С этой точки зрения, с текущими знаниями, тестирование улучшило бы качество кода и выявило бы несколько ошибок.

Спасибо за чтение! Надеюсь, это вдохновило вас на создание чего-нибудь.