NodeJs Express и socket.io.
Фронтенд розробка JavaScript. -> Гра шахові танки.
Домашнє завдання.
Створити розраховану на багато користувачів гру.
Гра є полем з квадратних шахових клітин.
Розмір поля може встановлюватись у налаштуваннях.
Приклад налаштувань гри
{
fps: 25,
width: 20,
height: 20,
size: 50,
}
fps - кількість кадрів у с.
width, height - кількість клітин по вертикалі та горизонталі
size – розмір клітини в пікселях.
1 реліз
Серверна частина.
- Створити двомірний масив із клітинами.
Формат масиву.
scene = [
[
[ x: number,
y: number,
color: string,
borderColor: string,
border: number,
power: number[0-100]
actor: object
],
[x: number, y: number, ...],
[]
...
],
[],
...
]
При підключенні користувача на сцені розставити для нього фігури у шаховому порядку білі зверху праворуч, чорні внизу ліворуч (у кутах) для першого та другого користувача.
Якщо користувачів більше 3 нічого не робимо.
Формат об’єкта фігури.
actor = {
color: string[black|white],
name: [pone|rook|quin|king|bishop|knight],
power: number[0-100],
strenght: number[0-100],
position: {x,y},
image: string
}
- Реалізувати подію переміщення.
Вхідні дані.
{
action: 'move',
from: {
x: number,
y: number,
},
to: {
x: number,
y: number,
}
}
Події переміщати фігуру.
-
З частотою fps передавати на клієнт по вебсокет цей об’єкт сцени.
{ data: scene, action: ‘render’ }
Клієнтська сторона.
-
З’єднається із сервером.
-
Реалізувати функцію малювання клітин на полотні canvas.
-
Реалізувати малювання об’єктів фігур.
-
Реалізувати переміщення фігури з надсиланням повідомлення на сервер.
2 реліз
Серверна частина.
-
На сцену додати нового актора – танк замість ферзя.
-
Додати в сцену масив із кульками.
{ data: scene, action: ‘render’, tanks: [{color: string, image: string position: {x,y}},…], bullets: [{color: string, image: string position: {x,y}},…] }
-
Реалізувати подію повороту танка на 45 градусів.
-
Реалізувати подію пересування танка у 8 напрямах.
-
Реалізувати подію пострілу.
-
Переміщення кульки з видаленням поля при досягненні краю.
Клієнтська частина
-
Відображення танка
-
Відображення куль.
3 реліз
Серверна частина.
-
Відпрацювати колізію кульки з фігурою.
-
Відпрацювати колізію танка із фігурою.
Фронтенд розробка JavaScript. -> Використання express та web-socket-ів для обміну клієнт-сервер.
NodeJS початок. Використання express та web-socket-ів для обміну клієнт-сервер.
Ставимо реакт.
npm install react react-dom --save
Ставимо express.
npm install express --save
Ставимо typescript.
npm install typescript --save
Встановимо типи для nodejs
npm install @types/node --save
Створюємо конфігурацію в tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "ES5",
"outDir": "dist",
"rootDir": "src"
},
"exclude": [
"node_modules"
]
}
Запуск білдера.
node ./node_modules/typescript/bin/tsc --watch
Встановимо nodemon
npm install --save nodemon
Налаштуємо його конфігурацію у nodemon.json
{
"verbose": false,
"ignore": ["node_modules"],
"watch": ["src/*"],
"ext": "*"
}
Необхідно відстежувати вихідний код у src, а не відкомпільований у dist!
Створимо простий сервер.
var express = require('express');
const app = require('express')();
const server = require('http').createServer(app);
app.use(express.static('.'));
server.listen(5000, () => {
console.log('Listening 5000');
});
Запуск
node_modules/nodemon/bin/nodemon.js dist/server/index.js
Простий шаблон сторінки.
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title>
<script src="node_modules/systemjs/dist/system.js"></script>
</head>
<body>
<h1>Hello from Node!</h1>
</body>
</html>
Встановимо універсальний завантажувач модулів.
npm install systemjs@0.19.22 --save
Фронтенд додаток.
Створюємо файл client/index.ts
console.log('Start!!!')
Додамо скрипт завантаження.
<script>
SystemJS.config({
defaultJSExtensions: true
});
SystemJS.import('dist/client/index.js');
</script>
Зробимо оновлення сторінки після запуску сервера.
Ставимо лібу socket.io.
npm install socket.io @types/socket.io --save
Підключимо її на клієнта та спробуємо створити підключення.
Створюємо новий файл у client/includes/SocketConnection.ts
import { Client } from 'socket.io';
import * as io from 'socket.io';
export class SocketConnection {
socket: any;
constructor(url: string) {
this.socket = io(url, {transports:['websocket']});
}
}
Приклад відпрацювання з’єднання та надсилання повідомлення на сервер.
this.socket = io(url, {transports:['websocket']})
.on('connect', (connection) => {
this.socket.emit('hello',{message: 'hello message'});
})
Підключаємо та використовуємо в client/index.ts
import { SocketConnection } from './includes/SocketConnection';
var socket = new SocketConnection('ws://localhost:5000')
console.log('Start!!!')
Додаємо шляхи до завантажувача.
<script>
SystemJS.config({
defaultJSExtensions: true,
map: {
'socket.io': 'node_modules/socket.io-client/dist'
},
packages: {
'socket.io': {
main: './socket.io.js'
}
}
});
SystemJS.import('dist/client/index.js');
</script>
[посилання на документацію по клієнту] (https://socket.io/docs/client-api/)
Додаємо сокет сервер на сервері.
const server = require('http').createServer(app);
// adding socket listener
const io = require('socket.io')(server, {});
Створюємо клас сокет з’єднання на сервері server/includes/SocketServer.ts
export class SocketServer {
constructor(io: any) {
io.on('connection', socket => {
console.log('Connected');
console.log(socket.id);
});
}
}
Створюємо об’єкт класу SocketServer у вхідному файлі сервера server/index.ts.
// adding socket listener
const io = require('socket.io')(server, {});
var socketServer = new SocketServer(io);
Додавання шаблонизатора swig
npm install swig --save
Доопрацюємо вхідний файл сервера.
app.set('views', __dirname + '/../../src/server/tpl');
app.engine('html', require('swig').renderFile);
app.use("/", function(request, response){
response.render("index.html");
});
Перенесемо шаблон index.html у src/server/tpl.
Перевантаження сторінки у браузері.
Встановимо бібліотеку.
npm install livereload --save
Додамо наступне в server/index.ts.
// livereload
const livereload = require("livereload");
const liveReloadServer = livereload.createServer();
liveReloadServer.watch(__dirname, '/../../src');
liveReloadServer.server.once("connection", () => {
setTimeout(() => {
liveReloadServer.refresh("/");
}, 1000);
});
const connectLivereload = require("connect-livereload");
app.use(connectLivereload());
app.use(connectLivereload()) - автоматично додасть тег скрипта на всі сторінки.
** Необхідно стежити за позицією коду та розміщувати перед підключенням шаблонизатора **
Іноді сервер livereload не завершується і залишає відкритим порт 35729.
Тому перед стартом сервера можна примусово прибивати процес порту 35729.
kill -9 $(lsof -t -i:35729)
Об’єднаний сервер NodeJs та транспілятор Typescript.
(Посилання на бібліотеку)https://www.npmjs.com/package/concurrently
npm install concurrently --save
Запустимо 2 команди, пропишемо команду start у package.json
“scripts”: { … “start”: “concurrently "./bin/run.cmd" "./bin/build.cmd"” },