Pull to refresh

Игра на WebAssembly, часть 2: уровни и опыт, админка

Reading time 4 min
Views 4K
В предыдущей статье получилось сделать прототип игры с вопросами. Но не получилось сделать это полноценно на WebAssembly. В этот раз предлагаю конвертировать этот прототип, сделав с него полноценное WebAssembly приложение, а так же добавить к нему атрибуты большинства игр — опыт и уровни игрока. А так же простую логику — при переходе на некоторые уровни будем открывать новые навыки.

Demo

Создаем WebAssembly проект


Создадим новый проект, который будет хостить WebAssembly приложение, внутри Web приложения (ASP.NET Core ). Если быть точнее, то Web приложение возвращает WebAssembly приложение, которое остается в браузере у пользователя и взаимодействует с сервером посредством http (или веб сокетов). Для этого, нам нужно создать BlazorApp проект и выбрать пункт ASP.NET Core hosted



Или же, из консоли:

dotnet new blazorwasm --hosted

Поcкольку у нас уже есть Blazor проект с предыдущей статьи, а синтаксис одинаковый у проектов с серверным хостингом и WebAssembly, то все страницы можно просто скопировать. Но с классами для логики так не получится — нужно создать новый контроллер, как часть backend-а. Это обычный asp.net контроллер, с которым наш клиент будет коммуницировать.

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

Меняем версию на .NET 5 preview 6


Срочной необходимости это делать нет. Но, поскольку предварительная версия .NET 5 уже доросла до шестой, поддерживает Blazor и в ней есть некоторые новые фичи (например, extension методы для запросов на сервер), то почему бы и не перейти на неё сейчас. Мигрировать довольно просто, если знать что делать. В нашем случае — это замена версий target framework в серверном проекте и переход на новую версию всех nuget пакетов.

Github commit: Update to .NET 5 preview 6


Добавляем опыт и уровень


Для связи между уровнем и опытом будем использовать простую формулу: минимум опыта для уровня = 2^(уровень). Для того, чтобы игрок мог понимать сколько опыта он накопил и какого он уровня, добавим в его модель эти два параметра. А так же, добавим поле в таблицу с вопросами для индикации сколько очков опыта даст один вопрос. Пока все вопросы будут добавлять 1 очко опыта.

Для отображения на пользовательском интерфейсе, используем простые компоненты Bootstrap.

<div class="row">
    <div class="col-md-auto">
        <span class="badge badge-warning">
            Уровень <span class="badge badge-light">@state.Level</span>
        </span>
    </div>
    <div class="col">
        <div class="progress mt-1">
            <div class="progress-bar" role="progressbar" style="width: @GetExperienceWidgetWidth()" aria-valuenow="@state.Experience" aria-valuemin="0" aria-valuemax="@experienceDiff">
                XP: @state.Experience
            </div>
        </div>
    </div>
</div>

Результат:



Github commit: Add level and experience to UI


Навыки уровней


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

Github commit: Show features depending on level


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

Github commit: Add leader board


В этом же изменении, при редактировании фидбека на неправильный ответ, наткнулся на интересный момент. Попробовал одновременно подписаться на события нажатия клавиши (если это Enter — отправить на сервер) и изменения значения контрола (если оно пустое — убрать сообщение о не верном ответе). Оказалось, что такой вариант не поддерживается. Что, в свою очередь спровоцировало как-то это обойти. В описном тикете есть варианты, но я попробовал еще один:

 var timer = new Timer(1);
timer.Elapsed += (object sender, ElapsedEventArgs e) => { wrongStyle = "visibility:hidden"; };
timer.Start();

Работает именно так, как мне нужно — при изменении ответа, сообщение пропадает. Хотя и таймер на 1 миллисекунду. Вообще, использования .NET таймера внутри браузера звучит странно. Но, похоже, что если пользователь не активен, то таймер автоматически замораживается.

Админка


Приятным бонусом использования Blazor внутри ASP.NET Core приложения является возможность использования инструментов зрелого фреймворка. В данном случае — мы можем сделать простую админку для просмотра\редактирования вопросов с помощью кодо-генерации.

Добавим несколько типичных строк в логику конфигурации авторизации (Startup.cs) и сгенерируем пару стандартных частей — Identity страницы для авторизации и контроллер с представлениями для просмотра вопросов. Получилась простыня кода, из которой руками писалось всего несколько строк.

Github commit: add admin part


Проверка ответов и безопасность


Так как большая часть логики находится на клиенте, например проверка правильности ответа, который отправил пользователь, то это и большая проблема с точки зрения безопасности. На данный момент продвинутый пользователь (который знает как посмотреть детали трафика в браузере) без проблем может проверить ответ во время загрузки вопроса с сервера. Наверное, оптимальным решением этой проблемы будет использование одностороннего шифрования для проверки правильности ответа. Но оставим это на позже, дав возможность юным хакерам накрутить себе игрового опыта.

Выводы


На сегодняшний день есть как позитивные так и негативные моменты разработки на Blazor. Самое приятное — это видеть как интерактивно меняется пользовательский интерфейс, при этом использовать только C# как язык программирования. Как ни странно, не смотря на простоту фреймворка, требуемый пользовательский интерфейс получается сделать довольно просто и при этом всё работает. Из негативных моментов — главная проблема, это ощущение сыроватости. Возможно при использовании стабильных версий всё выглядит лучше.

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

Результат:

Github
Demo
Tags:
Hubs:
+5
Comments 2
Comments Comments 2

Articles