click fraud detection
click fraud detection
Blog Case

Создание карточной игры Blackjack

BLOG
CASE
324
0
5/ 5stars
5/5
Время чтения: 25 минут

Задача заключается в создании многопользовательской карточной онлайн-игры в «очко», где игрокам поочередно предлагается брать карты. Выигрывает тот, кто набрал больше очков но не более чем 21. При выигрыше, сумма ставки прибавляется к счету игрока, который победил и отнимается у того, кто проиграл.

Наше приложение будет состоять из 2-х частей: серверной и клиентской. Создадим каркас приложения ангуляр для клиентской части. Для этого воспользуемся библиотекой командной строки angular-cli, которую желательно установить глобально в систему.

sudo npm install -g @angular/cli

Итак, создаем приложение следующим образом:

ng new client

При установке соглашаемся на использование роутинга, он нам пригодится. После чего получим каталог client с необходимой структурой папок. Нас больше всего будет интересовать каталог src/app, в котором и будет код нашего приложения. Игра будет содержать три роутинга и соответственно – три страницы и привязанных к ним компонента.

  1. Страница с формой авторизации.
  2. Страница со списком пользователей онлайн.
  3. Станица комнаты с игрой между двумя пользователями.

Поэтому создадим эти три компонента следующими командами:

ng g c login;
ng g c online;
ng g c room.

Вот так должен выглядеть результат, при котором создались 3 одноименных каталога с компонентами, которые также были включены в корневой модуль app.module.ts, о чем свидетельствует строка:

UPDATE src/app/app.module.ts

Если мы откроем этот файл, то заметим что в него добавился импорт каждого компонента и включен в секцию декларации.

import { LoginComponent } from './login/login.component';
import { OnlineComponent } from './online/online.component';
import { RoomComponent } from './room/room.component';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    OnlineComponent,
    RoomComponent
  ],

Привяжем эти компоненты к маршрутизатору, создав 3 маршрута (на самом деле их 4 но один используется для редиректа).

import { LoginComponent } from './login/login.component';
import { OnlineComponent } from './online/online.component';
import { RoomComponent } from './room/room.component';
 
const routes: Routes = [
  {
    path: '',
    redirectTo: 'login',
    pathMatch: 'full'
  },
  {
    path: 'login',
    component: LoginComponent
  },
  {
    path: 'online',
    component: OnlineComponent
  },
  {
    path: 'room/:uuid',
    component: RoomComponent
  }
];

В первом роутинге мы делаем редирект на форму авторизации (LoginComponent) на главной странице. Т.е. теперь, когда мы запустим сервер разработки командой:

ng serve

Потом, когда перейдем по адресу http://localhost:4200 нас автоматически перебросит на адрес http://localhost:4200/login и мы увидим такую картину:

В последнем роутинге мы определили переменную :uuid при указании шаблона пути, эта переменная будет изменятся и содержать уникальный идентификатор игровой комнаты.

Теперь осталось открыть шаблон корневого компонента app.component.html, убрать все лишнее от приветствия и вставить ссылки на каждый роут вот так:

Принято использовать специальную директиву [routerLink] для указания пути роутинга. Вместо параметра :uuid в роутинге игровой комнаты мы пока вставим тестовое значение room_id. В теге router-outlet будет выводится содержимое шаблонов компонентов, соответствующих пути роута.

Вот что должно получится:

Теперь предлагаю оформить интерфейс в лучших традициях bootstrap и подключить библиотеку ngx-bootstrap такой командой:

ng add ngx-bootstrap

Далее необходимо перезагрузить сервер разработки и применить в шаблоне разметку bootstrap.

Вот что у нас получилось:

Создадим форму для логина в шаблоне login/login.component.html.

Теперь необходимо привязать сабмит формы к методу компонента. Для этого откроем код компонента login/login.component.ts и добавим переменную с логином и метод.

export class LoginComponent implements OnInit {
 
  login: string;
  constructor() { }
 
  ngOnInit() {
  }
 
  doLogin(){
    console.log(this.login);
  }

}

Для проверки в методе doLogin мы выводим в консоль значение переменной login, объявленной в классе перед конструктором.

Эта переменная будет связана со значением поля input в шаблоне следующим образом:

Обратите внимание на обязательное присутствие атрибута name в теге input. Однако, для связывание переменной login директивой [(ngModel)] необходимо подключить модуль FormsModule в корневом модуле, иначе вы увидите следующую ошибку в консоле браузера:

Can't bind to 'ngModel' since it isn't a known property of 'input'.

Поэтому импортируем этот модуль и включим в секцию imports корневого модуля app.module.ts.

import {FormsModule} from '@angular/forms';

@NgModule({

  imports: [
   ...
    FormsModule
  ],

Осталось вызвать метод doLogin при сабмите нашей формы.

Результат работы:

Теперь нам предстоит задействовать веб-сокеты и по ним передать логин пользователя на сервер. Мы будем использовать библиотеку socket.io, и для нее есть обертка под Ангуляр, устанавливаем.

npm i ngx-socket-io --save

Далее ее необходимо импортировать в корневом модуле приложения, сконфигурировать и добавить в секцию imports.

import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
const config: SocketIoConfig = { url: 'http://localhost:3000', options: {} };

@NgModule({

  imports: [
    ...
    SocketIoModule.forRoot(config)
  ],

Как видно, мы планируем запустить сокет-сервер на порту 3000 локальной машины.

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

А пока создадим такой сервис в новом файле socket.service.ts.

import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';

@Injectable({
  providedIn: 'root'
})
export class SocketService {

  constructor(private socket: Socket) { }

  sockLogin(login: string) {
    console.log(`emmiting login ${login} to server`);
    this.socket.emit('LoginEvent', {data: login});
  }
}

Декоратором @Injectable мы делаем сервис способным к применению внутри компонентов. Функцией emit объекта socket мы передаем информацию на сервер.

Применим этот сервис в компоненте, пока просто импортировав его класс и добавив приватную переменную socket_service в конструктор класса компонента LoginComponent:

import { SocketService } from './../socket.service';
...
export class LoginComponent implements OnInit {

  constructor(private socket_service: SocketService) { }
  ...
}

После этого наш компонент попытается создать сокет-соединение с сервером, которого пока еще нет. Об этом будет свидетельствовать сообщение об ошибке в консоле.

Причем попытки соединится продолжаются не прекращаясь, это позволяет восстанавливать сокет-соединение при падении сервера.

Но несмотря на то, что рабочего сервера пока нет, все же реализуем отправку сообщения, вызвав метод sockLogin нашего сервиса из компонента LoginComponent, и передадим в нее переменную login.

doLogin(){
  this.socket_service.sockLogin(this.login);
}

Выводы

В этой статье рассмотрен процесс создания приложения Angular с использованием системы маршрутизации. Также описан процесс работы с компонентами, их шаблонами и сервисами на примере формы авторизации. Затронуто использование сокет-соединения на базе библиотеки ngx-socket-io.

В следующей статье будет рассмотрен процесс создания серверной части и взаимодействие его с клиентской.

У ВАС ОСТАЛИСЬ ВОПРОСЫ?

Оставьте ваши контактные данные. Наш менеджер свяжется и проконсультирует вас.

ПОЛУЧИТЬ КОНСУЛЬТАЦИЮ

Наш менеджер свяжется с Вами в ближайшее время

5/5
Проголосовало людей: 1
PWA приложения: что это, как применить в бизнесе, преимущества и «подводные камни»
В двух словах PWA (progressive web application) – формат создания веб-страниц, который сочетает функционал сайта…
Алексей Варламов
Алексей Варламов
Обзор методов веб-безопасности: 4 способа защитить свой сайт
Ежегодно сотни web-сайтов попадают под фильтры поисковых систем или удаляются из индекса из-за того, что…
Алексей Варламов
Алексей Варламов
Как создать продающий сайт компании
Мы не можем смотреть спокойно на подобное пренебрежение web-инструментами в бизнесе. Поэтому и решили написать…
Алексей Варламов
Алексей Варламов
Что такое мобильное приложение для сайта
Для удобства мобильной аудитории многие предприятия с веб-представительством создают мобильные приложения для собственного сайта. Это…
Алексей Варламов
Алексей Варламов
ПОЛУЧАТЬ ИНТЕРЕСНЫЕ СТАТЬИ
Уже подписались 251 человек
Автор
324
0
Дмитрий Жариков
Дмитрий
Жариков
most
Popular
Возможно
Эффективное продвижение интернет-магазина женской одежды. Подробное поочередное описание каждого выполненного шага
Виктория Тышкевич
Виктория Тышкевич
Продвигаете ли вы интернет магазин, сайт услуг, блог, Landing Page – без тексов не обойтись.…
Наталья Семенютенко
Наталья Семенютенко
Как сделать минималистичный сайт с плоским дизайном, карточками и изображениями высокого разрешения? В этом руководстве…
Галина Назарова
Галина Назарова
Давайте начнем
беседу!
КОММЕНТАРИИ0
ОСТАВИТЬ КОММЕНТАРИЙ К СТАТЬЕ
ПОДПИСЫВАЙТЕСЬ НА РАССЫЛКУ АЙТЫЖБЛОГ
ХОТИТЕ ПОЛУЧАТЬ 
ИНТЕРЕСНЫЕ СТАТЬИ?
Уже подписались 251 человек
313
ПОПИСЧИКОВ
ЧИТАТЬ
4295
ПОПИСЧИКОВ
СЛЕДИТЬ
9307
ПОПИСЧИКОВ
СЛЕДИТЬ